diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 5e3e4b989f..0000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,8 +0,0 @@ -blank_issues_enabled: true -contact_links: - - name: Feature Requests and Ideas - url: https://github.com/open-goal/jak-project/discussions/new/choose - about: Please use the discussion board to bring up feature requests and ideas. If there is interest in them, they can then be converted to an issue(s). - - name: Discord Help Channel - url: https://discord.gg/dPRCfsju3N - about: The best place for general help and asking questions. diff --git a/.github/ISSUE_TEMPLATE/jak1-bug-report.yml b/.github/ISSUE_TEMPLATE/jak1-bug-report.yml deleted file mode 100644 index c9f71ae66d..0000000000 --- a/.github/ISSUE_TEMPLATE/jak1-bug-report.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: "\U0001F41B Jak 1 Bug Report" -description: Create a bug report for Jak 1. -labels: ["bug", "jak1"] -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%3Ajak1+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 - - JP - validations: - required: true - - - type: dropdown - attributes: - label: Have you set the game to something other than `60fps`? - options: - - "No" - - "Yes" - validations: - required: true - diff --git a/.github/ISSUE_TEMPLATE/jak2-bug-report.yml b/.github/ISSUE_TEMPLATE/jak2-bug-report.yml deleted file mode 100644 index 69005637ed..0000000000 --- a/.github/ISSUE_TEMPLATE/jak2-bug-report.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: "\U0001F41B Jak 2 Bug Report" -description: Create a bug report for Jak 2. -labels: ["bug", "jak2"] -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%3Ajak2+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 - - JP - validations: - required: true - - - type: dropdown - attributes: - label: Have you set the game to something other than `60fps`? - options: - - "No" - - "Yes" - validations: - required: true - diff --git a/.github/schemas/README.md b/.github/schemas/README.md new file mode 100644 index 0000000000..d392ea9434 --- /dev/null +++ b/.github/schemas/README.md @@ -0,0 +1,7 @@ +Generated via typescript definitions: + +```bash +npx ts-json-schema-generator --path './*.ts' --type 'ModMetadata' > mod-schema.v1.json +``` + +And then some value validations added on mostly for valid semver checking \ No newline at end of file diff --git a/.github/schemas/mods/v2/mod-schema.v2.json b/.github/schemas/mods/v2/mod-schema.v2.json new file mode 100644 index 0000000000..dfa1f90827 --- /dev/null +++ b/.github/schemas/mods/v2/mod-schema.v2.json @@ -0,0 +1,43 @@ +{ + "$ref": "#/definitions/ModMetadata", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "ModMetadata": { + "additionalProperties": false, + "properties": { + "publishedDate": { + "type": "string" + }, + "schemaVersion": { + "description": "Semantic Version", + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", + "type": "string" + }, + "supportedGames": { + "items": { + "enum": [ + "jak1", + "jak2", + "jak3", + "jakx" + ], + "type": "string" + }, + "type": "array" + }, + "version": { + "description": "Semantic Version", + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", + "type": "string" + } + }, + "required": [ + "schemaVersion", + "version", + "publishedDate", + "supportedGames" + ], + "type": "object" + } + } +} diff --git a/.github/schemas/mods/v2/types.ts b/.github/schemas/mods/v2/types.ts new file mode 100644 index 0000000000..aef931ea6f --- /dev/null +++ b/.github/schemas/mods/v2/types.ts @@ -0,0 +1,21 @@ +// interface ChangelogEntry { +// summary: string, +// timestamp: string, +// authors?: string[], +// description?: string, +// } + +/** + * Semantic Version + * @pattern ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ + */ +type Semver = string; + +type SupportedGame = "jak1" | "jak2" | "jak3" | "jakx"; + +export interface ModMetadata { + schemaVersion: Semver; + version: Semver; + publishedDate: string; + supportedGames: SupportedGame[]; +} diff --git a/.github/scripts/create-mod-release/bundle-linux.py b/.github/scripts/create-mod-release/bundle-linux.py new file mode 100644 index 0000000000..ae458e838a --- /dev/null +++ b/.github/scripts/create-mod-release/bundle-linux.py @@ -0,0 +1,27 @@ +from common import ( + create_output_dir, + download_release, + finalize_bundle, + get_args, + override_binaries_and_assets, + patch_mod_timestamp_and_version_info, +) + +args = get_args("linux") + +print(args) + +# Create our output directory +create_output_dir(args, "linux") + +# Download the Release +download_release(args, "linux", is_zip=False) + +# Override any files +override_binaries_and_assets(args, "linux") + +# Replace placeholder text with mod version and timestamp +patch_mod_timestamp_and_version_info(args, "linux") + +# Rezip it up and prepare it for upload +finalize_bundle(args, "linux", is_zip=False) diff --git a/.github/scripts/create-mod-release/bundle-macos.py b/.github/scripts/create-mod-release/bundle-macos.py new file mode 100644 index 0000000000..07dc32730e --- /dev/null +++ b/.github/scripts/create-mod-release/bundle-macos.py @@ -0,0 +1,27 @@ +from common import ( + create_output_dir, + download_release, + finalize_bundle, + get_args, + override_binaries_and_assets, + patch_mod_timestamp_and_version_info, +) + +args = get_args("macos-intel") + +print(args) + +# Create our output directory +create_output_dir(args, "macos-intel") + +# Download the Release +download_release(args, "macos-intel", is_zip=False) + +# Override any files +override_binaries_and_assets(args, "macos-intel") + +# Replace placeholder text with mod version and timestamp +patch_mod_timestamp_and_version_info(args, "macos-intel") + +# Rezip it up and prepare it for upload +finalize_bundle(args, "macos-intel", is_zip=False) diff --git a/.github/scripts/create-mod-release/bundle-windows.py b/.github/scripts/create-mod-release/bundle-windows.py new file mode 100644 index 0000000000..38df6da79d --- /dev/null +++ b/.github/scripts/create-mod-release/bundle-windows.py @@ -0,0 +1,27 @@ +from common import ( + create_output_dir, + download_release, + finalize_bundle, + get_args, + override_binaries_and_assets, + patch_mod_timestamp_and_version_info, +) + +args = get_args("windows") + +print(args) + +# Create our output directory +create_output_dir(args, "windows") + +# Download or Build the Release +download_release(args, "windows", is_zip=True) + +# Override any files +override_binaries_and_assets(args, "windows") + +# Replace placeholder text with mod version and timestamp +patch_mod_timestamp_and_version_info(args, "windows") + +# Rezip it up and prepare it for upload +finalize_bundle(args, "windows", is_zip=True) diff --git a/.github/scripts/create-mod-release/common.py b/.github/scripts/create-mod-release/common.py new file mode 100644 index 0000000000..e8eefa3ede --- /dev/null +++ b/.github/scripts/create-mod-release/common.py @@ -0,0 +1,191 @@ +import datetime +import json +import os +import glob +import shutil +import tarfile +import urllib.request +import zipfile + + +def default_asset_prefix(platform): + if platform == "windows": + return "opengoal-windows" + elif platform == "linux": + return "opengoal-linux" + elif platform == "macos-intel": + return "opengoal-macos-intel" + elif platform == "macos-arm": + return "opengoal-macos-arm" + else: + return "opengoal-unknown" + + +def get_args(platform): + return { + "outputDir": os.getenv("outputDir"), + "versionName": os.getenv("versionName"), + "toolingRepo": os.getenv("toolingRepo"), + "toolingReleaseAssetPrefix": os.getenv( + "toolingReleaseAssetPrefix", default_asset_prefix(platform) + ), + "toolingVersion": os.getenv("toolingVersion") + } + + +def create_output_dir(args, dir_name): + if os.path.exists(os.path.join(args["outputDir"], dir_name)): + print( + "Expected output directory already exists, clearing it - {}".format( + os.path.join(args["outputDir"], dir_name) + ) + ) + os.rmdir(os.path.join(args["outputDir"], dir_name)) + + os.makedirs(os.path.join(args["outputDir"], dir_name), exist_ok=True) + +def download_release(args, out_folder, is_zip=True): + toolingRepo = args["toolingRepo"] + tooling_version = args["toolingVersion"] + if tooling_version == "latest": + # Get the latest release + with urllib.request.urlopen( + f"https://api.github.com/repos/{toolingRepo}/releases/latest" + ) as response: + data = json.loads(response.read().decode()) + tooling_version = data["tag_name"] + + if is_zip: + releaseAssetUrl = f"https://github.com/{toolingRepo}/releases/download/{tooling_version}/{args['toolingReleaseAssetPrefix']}-{tooling_version}.zip" + urllib.request.urlretrieve( + releaseAssetUrl, os.path.join(args["outputDir"], out_folder, "release.zip") + ) + # Extract it + with zipfile.ZipFile( + os.path.join(args["outputDir"], out_folder, "release.zip"), "r" + ) as zip_ref: + zip_ref.extractall(os.path.join(args["outputDir"], out_folder)) + os.remove(os.path.join(args["outputDir"], out_folder, "release.zip")) + else: + releaseAssetUrl = f"https://github.com/{toolingRepo}/releases/download/{tooling_version}/{args['toolingReleaseAssetPrefix']}-{tooling_version}.tar.gz" + urllib.request.urlretrieve( + releaseAssetUrl, + os.path.join(args["outputDir"], out_folder, "release.tar.gz"), + ) + # Extract it + with tarfile.open( + os.path.join(args["outputDir"], out_folder, "release.tar.gz") + ) as tar_ball: + tar_ball.extractall(os.path.join(args["outputDir"], out_folder)) + os.remove(os.path.join(args["outputDir"], out_folder, "release.tar.gz")) + + +def override_binaries_and_assets(args, out_folder): + # Copy-in Mod Assets + customAssetsDir = "./custom_assets" + if os.path.exists(customAssetsDir): + shutil.copytree( + customAssetsDir, + os.path.join(args["outputDir"], out_folder, "data", "custom_assets"), + dirs_exist_ok=True, + ) + + goalSourceDir = "./goal_src" + if not os.path.exists(goalSourceDir): + print( + "Goal source directory not found at {}, not much of a mod without that!".format( + goalSourceDir + ) + ) + exit(1) + shutil.copytree( + goalSourceDir, + os.path.join(args["outputDir"], out_folder, "data", "goal_src"), + dirs_exist_ok=True, + ) + + gameAssetsDir = "./game/assets" + if not os.path.exists(gameAssetsDir): + print("Game assets directory not found at {}!".format(gameAssetsDir)) + exit(1) + shutil.copytree( + gameAssetsDir, + os.path.join(args["outputDir"], out_folder, "data", "game", "assets"), + dirs_exist_ok=True, + ) + + decompilerConfigDir = "./decompiler/config" + if os.path.exists(decompilerConfigDir): + shutil.copytree( + decompilerConfigDir, + os.path.join(args["outputDir"], out_folder, "data", "decompiler", "config"), + dirs_exist_ok=True, + ) + else: + print( + "Decompiler config directory not found at {}, skipping.".format( + decompilerConfigDir + ) + ) + + +def patch_mod_timestamp_and_version_info(args, out_folder): + try: + mod_settings_files = glob.glob(f"{args['outputDir']}/{out_folder}/data/goal_src/**/mod-settings.gc", recursive=True) + for settings_file_path in mod_settings_files: + file = open(settings_file_path, "r") + file_data = file.read() + file.close() + # Check if the placeholder string is present in the file + if "%MODVERSIONPLACEHOLDER%" in file_data: + # Replace the placeholder string with the version and date string + version_str = ( + args["versionName"] + + " " + + datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M:%S") + ) + file_data = file_data.replace("%MODVERSIONPLACEHOLDER%", version_str) + # Write the updated content back to the mod-settings + file = open(settings_file_path, "w") + file.write(file_data) + file.close() + print( + f"String %MODVERSIONPLACEHOLDER% replaced with '{version_str}' in the file." + ) + else: + print(f"Couldn't find %MODVERSIONPLACEHOLDER% in the file.") + except Exception as e: + print( + f"Something went wrong trying to replace placeholder text with mod version info:" + ) + print(e) + +def finalize_bundle(args, out_folder, is_zip=True): + if is_zip: + shutil.make_archive( + f"{out_folder}-{args['versionName']}", + "zip", + os.path.join(args["outputDir"], out_folder), + ) + os.makedirs(os.path.join(args["outputDir"], "dist"), exist_ok=True) + shutil.move( + f"{out_folder}-{args['versionName']}.zip", + os.path.join( + args["outputDir"], "dist", f"{out_folder}-{args['versionName']}.zip" + ), + ) + else: + shutil.make_archive( + f"{out_folder}-{args['versionName']}", + "gztar", + os.path.join(args["outputDir"], out_folder), + ) + os.makedirs(os.path.join(args["outputDir"], "dist"), exist_ok=True) + shutil.move( + f"{out_folder}-{args['versionName']}.tar.gz", + os.path.join( + args["outputDir"], "dist", f"{out_folder}-{args['versionName']}.tar.gz" + ), + ) + # Cleanup + shutil.rmtree(os.path.join(args["outputDir"], out_folder)) diff --git a/.github/scripts/create-mod-release/emit-metadata.py b/.github/scripts/create-mod-release/emit-metadata.py new file mode 100644 index 0000000000..2acbd967f7 --- /dev/null +++ b/.github/scripts/create-mod-release/emit-metadata.py @@ -0,0 +1,36 @@ +# Simple script to emit a metadata.json file with the relevant mod information +# Values are passed in as environment variables +from datetime import datetime +import json +import os + +def split_comma_sep_val(str): + if "," not in str: + return [str] + return str.split(",") + +# Validate supported games list +games = split_comma_sep_val(os.getenv("SUPPORTED_GAMES")) +if len(games) == 0: + print("SUPPORTED_GAMES list is empty") + exit(1) +for game in games: + if game != "jak1" and game != "jak2" and game != "jak3" and game != "jakx": + print("SUPPORTED_GAMES contains invalid game: ", game) + exit(1) + +# Input has been validated, create metadata.json +metadata = { + "schemaVersion": os.getenv("SCHEMA_VERSION"), + "version": os.getenv("VERSION").removeprefix("v"), + "supportedGames": games, + "publishedDate": datetime.now().isoformat(), +} + +with open("{}/metadata.json".format(os.getenv("OUT_DIR")), "w", encoding="utf-8") as f: + print( + "Writing the following metadata: {}".format( + json.dumps(metadata, indent=2, ensure_ascii=False) + ) + ) + f.write(json.dumps(metadata, indent=2, ensure_ascii=False)) diff --git a/.github/scripts/releases/error-code-metadata.json b/.github/scripts/releases/error-code-metadata.json index 95a0cf1f8c..54a9435ea5 100644 --- a/.github/scripts/releases/error-code-metadata.json +++ b/.github/scripts/releases/error-code-metadata.json @@ -1,4 +1,10 @@ { + "3990": { + "msg": "Provided invalid or missing arguments" + }, + "3991": { + "msg": "Input path(s) do not exist" + }, "4000": { "msg": "Validation Failed: Cannot locate ELF" }, diff --git a/.github/scripts/releases/extract_mod_build_unix.sh b/.github/scripts/releases/extract_mod_build_unix.sh new file mode 100644 index 0000000000..3977348779 --- /dev/null +++ b/.github/scripts/releases/extract_mod_build_unix.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +set -e + +DEST=${1} +BIN_SOURCE=${2} +SOURCE=${3} + +mkdir -p $DEST + +PREP_BIN="${PREP_BIN:-true}" + +if [ "$PREP_BIN" = "true" ]; then + cp $BIN_SOURCE/game/gk $DEST + cp $BIN_SOURCE/goalc/goalc $DEST + cp $BIN_SOURCE/decompiler/extractor $DEST + + chmod +x $DEST/gk + chmod +x $DEST/goalc + chmod +x $DEST/extractor +fi + +mkdir -p $DEST/data +mkdir -p $DEST/data/launcher/ +mkdir -p $DEST/data/decompiler/ +mkdir -p $DEST/data/game +mkdir -p $DEST/data/log +mkdir -p $DEST/data/game/graphics/opengl_renderer/ + +cp -r $SOURCE/.github/scripts/releases/error-code-metadata.json $DEST/data/launcher/error-code-metadata.json +cp -r $SOURCE/decompiler/config $DEST/data/decompiler/ +cp -r $SOURCE/goal_src $DEST/data +cp -r $SOURCE/game/assets $DEST/data/game/ +cp -r $SOURCE/game/graphics/opengl_renderer/shaders $DEST/data/game/graphics/opengl_renderer +cp -r $SOURCE/custom_assets $DEST/data + +python ./.github/scripts/releases/replace-mod-version-timestamp.py $DEST/data/goal_src \ No newline at end of file diff --git a/.github/scripts/releases/extract_mod_build_windows.sh b/.github/scripts/releases/extract_mod_build_windows.sh new file mode 100644 index 0000000000..e686927001 --- /dev/null +++ b/.github/scripts/releases/extract_mod_build_windows.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -e + +DEST=${1} +BIN_SOURCE=${2} +SOURCE=${3} + +mkdir -p $DEST + +cp $BIN_SOURCE/gk.exe $DEST +cp $BIN_SOURCE/goalc.exe $DEST +cp $BIN_SOURCE/extractor.exe $DEST + +mkdir -p $DEST/data +mkdir -p $DEST/data/launcher/ +mkdir -p $DEST/data/decompiler/ +mkdir -p $DEST/data/game +mkdir -p $DEST/data/log +mkdir -p $DEST/data/game/graphics/opengl_renderer/ + +cp -r $SOURCE/.github/scripts/releases/error-code-metadata.json $DEST/data/launcher/error-code-metadata.json +cp -r $SOURCE/decompiler/config $DEST/data/decompiler/ +cp -r $SOURCE/goal_src $DEST/data +cp -r $SOURCE/game/assets $DEST/data/game/ +cp -r $SOURCE/game/graphics/opengl_renderer/shaders $DEST/data/game/graphics/opengl_renderer +cp -r $SOURCE/custom_assets $DEST/data + +python ./.github/scripts/releases/replace-mod-version-timestamp.py $DEST/data/goal_src \ No newline at end of file diff --git a/.github/scripts/releases/replace-mod-version-timestamp.py b/.github/scripts/releases/replace-mod-version-timestamp.py new file mode 100644 index 0000000000..236f835e8b --- /dev/null +++ b/.github/scripts/releases/replace-mod-version-timestamp.py @@ -0,0 +1,41 @@ +import datetime +import json +import os +import glob +import shutil +import tarfile +import urllib.request +import zipfile +import sys + +def patch_mod_timestamp(goal_src_path): + try: + mod_settings_files = glob.glob(f"{goal_src_path}/**/mod-settings.gc", recursive=True) + for settings_file_path in mod_settings_files: + file = open(settings_file_path, "r") + file_data = file.read() + file.close() + # Check if the placeholder string is present in the file + if "%MODVERSIONPLACEHOLDER%" in file_data: + # Replace the placeholder string with the version and date string + version_str = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M:%S") + file_data = file_data.replace("%MODVERSIONPLACEHOLDER%", version_str) + # Write the updated content back to the mod-settings + file = open(settings_file_path, "w") + file.write(file_data) + file.close() + print( + f"String %MODVERSIONPLACEHOLDER% replaced with '{version_str}' in the file." + ) + else: + print(f"Couldn't find %MODVERSIONPLACEHOLDER% in the file.") + except Exception as e: + print( + f"Something went wrong trying to replace placeholder text with mod version info:" + ) + print(e) + +if len(sys.argv) > 1: + patch_mod_timestamp(sys.argv[1]) +else: + print(f"No goal_src path provided to replace-mod-version-timestamp") \ No newline at end of file diff --git a/.github/workflows/build-matrix.yaml b/.github/workflows/build-matrix.yaml deleted file mode 100644 index 59601c577f..0000000000 --- a/.github/workflows/build-matrix.yaml +++ /dev/null @@ -1,62 +0,0 @@ -name: Build - -on: - push: - branches: - - master - pull_request: - branches: - - master - merge_group: {} - -jobs: - # Windows - build_windows_clang: - name: "🖥️ Windows" - uses: ./.github/workflows/windows-build-clang.yaml - with: - cmakePreset: "Release-windows-clang" - cachePrefix: "" - secrets: inherit - - build_windows_msvc: - name: "🖥️ Windows" - uses: ./.github/workflows/windows-build-msvc.yaml - with: - cmakePreset: "Release-windows-msvc" - cachePrefix: "" - secrets: inherit - - # Linux - build_linux_clang: - name: "🐧 Linux" - uses: ./.github/workflows/linux-build-clang.yaml - with: - cmakePreset: "Release-linux-clang-asan" - cachePrefix: "" - secrets: inherit - - build_linux_gcc: - name: "🐧 Linux" - uses: ./.github/workflows/linux-build-gcc.yaml - with: - cmakePreset: "Release-linux-gcc" - cachePrefix: "" - secrets: inherit - - # MacOS - build_macos_intel: - name: "🍎 MacOS" - uses: ./.github/workflows/macos-build.yaml - with: - cmakePreset: "Release-macos-clang" - cachePrefix: "" - - # Q4 2023 there will hopefully be native arm64 runners - # https://github.com/github/roadmap/issues/528 - # build_macos_arm: - # name: "🍎 MacOS" - # uses: ./.github/workflows/macos-build-arm.yaml - # with: - # cmakePreset: "Release-macos-clang" - # cachePrefix: "" diff --git a/.github/workflows/compiler-output-check.yaml b/.github/workflows/compiler-output-check.yaml deleted file mode 100644 index ea5ffac2b5..0000000000 --- a/.github/workflows/compiler-output-check.yaml +++ /dev/null @@ -1,98 +0,0 @@ -name: Compilation Check - -on: - pull_request: - branches: - - master - -jobs: - build: - name: Compare - runs-on: ubuntu-20.04 - timeout-minutes: 60 - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - with: - ref: master - - - name: Install Package Dependencies - run: | - sudo apt update - sudo apt install build-essential cmake \ - clang gcc g++ lcov make nasm libxrandr-dev \ - libxinerama-dev libxcursor-dev libpulse-dev \ - libxi-dev zip ninja-build libgl1-mesa-dev libssl-dev - - - name: Setup sccache - uses: hendrikmuhs/ccache-action@v1.2.13 - with: - variant: sccache - key: linux-ubuntu-20.04--Release-linux-clang-asan-${{ github.sha }} - restore-keys: linux-ubuntu-20.04--Release-linux-clang-asan - max-size: 1000M - - - name: CMake Generation (master) - env: - CC: clang - CXX: clang++ - run: | - cmake -B build --preset=Release-linux-clang-asan \ - -DCMAKE_C_COMPILER_LAUNCHER=sccache \ - -DCMAKE_CXX_COMPILER_LAUNCHER=sccache - - - name: Build goalc (master) - run: | - cmake --build build --parallel $((`nproc`)) --target goalc - mv ./build ./build.master - - - name: Checkout PR - uses: actions/checkout@v4 - with: - clean: "false" - - - name: CMake Generation (PR) - env: - CC: clang - CXX: clang++ - run: | - cmake -B build --preset=Release-linux-clang-asan \ - -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 - - diff --git a/.github/workflows/cut-release.yaml b/.github/workflows/cut-release.yaml index 8f53bf48b8..ff2331b572 100644 --- a/.github/workflows/cut-release.yaml +++ b/.github/workflows/cut-release.yaml @@ -1,4 +1,4 @@ -name: 🏭 Cut Mod Release +name: Cut Mod Release ⭐ on: workflow_dispatch: @@ -12,26 +12,69 @@ on: - patch - minor - major + binary_source: + description: 'Binary Source' + required: true + default: 'modbase' + type: choice + options: + - vanilla + - modbase + - build_binaries + jak1: + description: 'Supports Jak 1?' + required: true + default: 'true' + type: boolean + jak2: + description: 'Supports Jak 2?' + required: true + default: 'false' + type: boolean + jak3: + description: 'Supports Jak 3?' + required: true + default: 'false' + type: boolean + jakx: + description: 'Supports Jak X?' + required: true + default: 'false' + type: boolean permissions: contents: write jobs: - cut_release: - name: "Cut Release" - uses: open-goal/mod-bundling-tools/.github/workflows/mod-bundler.yml@v1 + prep_vars: + name: "Prep Variables" + runs-on: ubuntu-latest + outputs: + supported_games: ${{ steps.prep-vars.outputs.GAMES }} + tooling_repo: ${{ steps.prep-vars.outputs.REPO }} + steps: + - name: Prep Variables + id: prep-vars + run: | + GAMES= + if [[ ${{ inputs.jak1 }} == "true" ]]; then GAMES+=jak1,; fi + if [[ ${{ inputs.jak2 }} == "true" ]]; then GAMES+=jak2,; fi + if [[ ${{ inputs.jak3 }} == "true" ]]; then GAMES+=jak3,; fi + if [[ ${{ inputs.jakx }} == "true" ]]; then GAMES+=jakx,; fi + GAMES=${GAMES%?} + echo "GAMES=$GAMES" >> $GITHUB_OUTPUT + REPO=OpenGOAL-Mods/OG-Mod-Base + if [[ ${{ inputs.binary_source == 'vanilla' }} ]]; then REPO=open-goal/jak-project; fi + echo "REPO=$REPO" >> $GITHUB_OUTPUT + + cut_mod_release: + name: "Cut Mod Release" + needs: prep_vars + uses: ./.github/workflows/mod-release-pipeline.yml with: semverBump: ${{ inputs.bump }} - metadataName: "Test Mod Bundle" - metadataDescription: "This is a test mod bundle. 2" - metadataSupportedGames: "jak1,jak2" - metadataAuthors: "barg,vaser" - metadataTags: "rng,gameplay-mod" - metadataWebsiteUrl: "https://github.com/OpenGOAL-Mods/OG-Fricked/releases" - skipMacOS: true - skipLinux: true - toolingBinaryDir: "out/build/Release/bin" - gameAssetsDir: "game/assets" - copyEntireBinaryDir: true + metadataSupportedGames: ${{ needs.prep_vars.outputs.supported_games }} + buildBinaries: ${{ inputs.binary_source == 'build_binaries'}} + toolingRepo: ${{ needs.prep_vars.outputs.tooling_repo }} secrets: token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/draft-new-release.yaml b/.github/workflows/draft-new-release.yaml deleted file mode 100644 index dffc0f4f64..0000000000 --- a/.github/workflows/draft-new-release.yaml +++ /dev/null @@ -1,35 +0,0 @@ -name: 🏭 Draft Release - -on: - workflow_dispatch: - inputs: - bump: - description: 'Semver Bump Type' - required: true - default: 'patch' - type: choice - options: - - patch - - minor - - major - -jobs: - cut-release: - runs-on: ubuntu-latest - steps: - # Docs - https://github.com/mathieudutour/github-tag-action - # Workflows cannot trigger other workflows implicitly - # - https://github.community/t/github-actions-workflow-not-triggering-with-tag-push/17053/7 - - name: Bump Version and Push Tag - if: github.repository == 'open-goal/jak-project' - id: tag_version - uses: mathieudutour/github-tag-action@v6.2 - 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 diff --git a/.github/workflows/linux-build-clang.yaml b/.github/workflows/linux-build-clang.yaml index 1f5551db53..53a282a6b7 100644 --- a/.github/workflows/linux-build-clang.yaml +++ b/.github/workflows/linux-build-clang.yaml @@ -21,9 +21,19 @@ jobs: timeout-minutes: 60 steps: + # minimal checkout if we're NOT uploading artifacts - name: Checkout Repository + if: ${{ ! inputs.uploadArtifacts }} uses: actions/checkout@v4 + # full checkout with tags if we ARE uploading artifacts + - name: Checkout Repository with Tags + if: ${{ inputs.uploadArtifacts }} + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - name: Install Package Dependencies run: | sudo apt update @@ -35,7 +45,7 @@ jobs: libudev-dev libopenal-dev libflac-dev libogg-dev libvorbis-dev - name: Setup sccache - uses: hendrikmuhs/ccache-action@v1.2.13 + uses: hendrikmuhs/ccache-action@v1.2.14 with: variant: sccache key: linux-ubuntu-20.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }} diff --git a/.github/workflows/linux-build-gcc.yaml b/.github/workflows/linux-build-gcc.yaml index 7cc8d20389..57a8af81e5 100644 --- a/.github/workflows/linux-build-gcc.yaml +++ b/.github/workflows/linux-build-gcc.yaml @@ -19,6 +19,9 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true - name: Install Package Dependencies run: | @@ -34,7 +37,7 @@ jobs: sudo update-alternatives --set g++ /usr/bin/g++-10 - name: Setup sccache - uses: hendrikmuhs/ccache-action@v1.2.13 + uses: hendrikmuhs/ccache-action@v1.2.14 with: variant: sccache key: linux-ubuntu-20.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }} @@ -54,5 +57,5 @@ jobs: - name: Build Project run: cmake --build build --parallel $((`nproc`)) -- -w dupbuild=warn - - name: Run Tests - run: ./test.sh + # - name: Run Tests + # run: ./test.sh diff --git a/.github/workflows/macos-build-arm.yaml b/.github/workflows/macos-build-arm.yaml index 6a730b4b55..63f6c1619c 100644 --- a/.github/workflows/macos-build-arm.yaml +++ b/.github/workflows/macos-build-arm.yaml @@ -13,25 +13,25 @@ on: jobs: build: name: ARM - runs-on: macos-12 + runs-on: macos-15 timeout-minutes: 120 steps: - name: Checkout Repository uses: actions/checkout@v4 - - - name: Set up ARM64 environment - run: sudo softwareupdate --install-rosetta --agree-to-license + with: + fetch-depth: 0 + fetch-tags: true - name: Install Package Dependencies - run: arch -arm64 brew install cmake ninja + run: brew install cmake ninja nasm - name: Setup sccache - uses: hendrikmuhs/ccache-action@v1.2.13 + uses: hendrikmuhs/ccache-action@v1.2.14 with: variant: sccache - key: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }} - restore-keys: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }} + key: macos-15-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }} + restore-keys: macos-15-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }} max-size: 1000M - name: CMake Generation @@ -52,7 +52,7 @@ jobs: - name: Upload artifact uses: actions/upload-artifact@v4 with: - name: opengoal-macos-${{ inputs.cachePrefix }} + name: opengoal-macos-arm-${{ inputs.cachePrefix }} if-no-files-found: error path: | ./build/goalc/goalc diff --git a/.github/workflows/macos-build.yaml b/.github/workflows/macos-build.yaml index 272464cc65..d64d2065d3 100644 --- a/.github/workflows/macos-build.yaml +++ b/.github/workflows/macos-build.yaml @@ -17,22 +17,59 @@ on: jobs: build: name: Intel - runs-on: macos-12 + runs-on: macos-13 timeout-minutes: 120 steps: + # minimal checkout if we're NOT uploading artifacts - name: Checkout Repository + if: ${{ ! inputs.uploadArtifacts }} uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + + # full checkout with tags if we ARE uploading artifacts + - name: Checkout Repository with Tags + if: ${{ inputs.uploadArtifacts }} + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + + # full checkout with tags if we ARE uploading artifacts + - name: Checkout Repository with Tags + if: ${{ inputs.uploadArtifacts }} + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + + # full checkout with tags if we ARE uploading artifacts + - name: Checkout Repository with Tags + if: ${{ inputs.uploadArtifacts }} + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + + # full checkout with tags if we ARE uploading artifacts + - name: Checkout Repository with Tags + if: ${{ inputs.uploadArtifacts }} + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true - name: Install Package Dependencies run: brew install cmake nasm ninja - name: Setup sccache - uses: hendrikmuhs/ccache-action@v1.2.13 + uses: hendrikmuhs/ccache-action@v1.2.14 with: variant: sccache - key: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }} - restore-keys: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }} + key: macos-13-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }} + restore-keys: macos-13-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }} max-size: 1000M - name: CMake Generation @@ -47,8 +84,8 @@ jobs: - name: Build Project run: cmake --build build --parallel $((`sysctl -n hw.logicalcpu`)) - - name: Run Tests - run: ./test.sh + # - name: Run Tests + # run: ./test.sh - name: Prepare artifacts if: ${{ inputs.uploadArtifacts }} diff --git a/.github/workflows/mod-release-pipeline.yml b/.github/workflows/mod-release-pipeline.yml new file mode 100644 index 0000000000..fc7ea524a8 --- /dev/null +++ b/.github/workflows/mod-release-pipeline.yml @@ -0,0 +1,427 @@ +name: "Mod Release Pipeline" +on: + workflow_call: + inputs: + metadataSupportedGames: + description: "The supported games for the mod, can be comma-separated, supports `jak1|jak2|jak3|jakx`" + required: true + default: "jak4" + type: "string" + outputDir: + description: "The directory that the releases assets are created and temporarily stored in. Defaults to `./bundler`" + required: false + default: "./bundler" + type: "string" + semverBump: + description: "What semver bump to use - patch|minor|major. Defaults to patch" + required: false + default: "patch" + type: "string" + releaseBranches: + description: "Comma separated list of branches (JavaScript regular expression accepted) that will generate the release tags. You probably want your default branch in this list." + required: false + default: "master,main" + type: "string" + buildBinaries: + description: "Whether to build binaries from source. Defaults to `false`, pulling binaries from `toolingRepo` instead." + required: false + default: false + type: "boolean" + toolingRepo: + description: "The repository from which the tooling is taken for the bundle. Defaults to open-goal/jak-project." + required: false + default: "open-goal/jak-project" + type: "string" + toolingVersion: + description: "The version of `toolingRepo` to bundle. Defaults to latest version." + required: false + default: "latest" + type: "string" + skipWindows: + description: "Whether to skip Windows builds, defaults to `false`" + required: false + default: false + type: "boolean" + skipLinux: + description: "Whether to skip Linux builds, defaults to `false`" + required: false + default: false + type: "boolean" + skipMacOS: + description: "Whether to skip macOS builds, defaults to `false`" + required: false + default: false + type: "boolean" + secrets: + token: + description: "GitHub token used to create the release and push assets to it." + required: true + outputs: + taggedVersion: + description: "The version that was tagged and pushed for the mod" + value: ${{ jobs.create_release.outputs.bundleTagName }} + +permissions: + contents: write + +jobs: + validate_metadata: + name: "Validate Metadata" + runs-on: ubuntu-latest + steps: + - name: "Checkout Repository" + uses: actions/checkout@v4 + + - name: "Create metadata.json" + env: + SCHEMA_VERSION: "0.1.0" + VERSION: "v0.0.0" + SUPPORTED_GAMES: ${{ inputs.metadataSupportedGames }} + OUT_DIR: "/tmp" + run: | + python ./.github/scripts/create-mod-release/emit-metadata.py + + - name: "Validating Metadata" + run: | + npm install -g ajv-cli + ajv validate -s ./.github/schemas/mods/v2/mod-schema.v2.json -d /tmp/metadata.json + + create_release: + name: "Create Release" + needs: + - validate_metadata + runs-on: ubuntu-latest + outputs: + bundleTagName: ${{ steps.tag_version.outputs.new_tag }} + steps: + - name: Bump Version and Push Tag + id: tag_version + uses: mathieudutour/github-tag-action@v6.2 + with: + github_token: ${{ secrets.token }} + tag_prefix: v + default_bump: ${{ inputs.semverBump }} + release_branches: ${{ inputs.releaseBranches }} + + - name: Create Release + env: + GITHUB_TOKEN: ${{ secrets.token }} + run: gh release create ${{ steps.tag_version.outputs.new_tag }} --generate-notes --draft --repo ${{ github.repository }} + + # if `buildBinaries`, run the workflow to build and generate artifacts + + build_windows_clang: + name: "Windows Build" + needs: create_release + if: ${{ !inputs.skipWindows && inputs.buildBinaries }} + # assumes that this file is defined in your mod repo + uses: ./.github/workflows/windows-build-clang.yaml + with: + cmakePreset: "Release-windows-clang-static" + cachePrefix: "static" + uploadArtifacts: true + secrets: inherit + + bundle_windows_build: + name: "Bundle Windows Build" + needs: + - create_release + - build_windows_clang + if: ${{ !inputs.skipWindows && inputs.buildBinaries }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.create_release.outputs.bundleTagName }} + + - name: "Checkout Repository" + uses: actions/checkout@v4 + + - name: Prepare Artifact Folder + run: mkdir -p ./ci-artifacts + + - uses: actions/download-artifact@v4 + name: Download all Artifacts + with: + path: ./ci-artifacts/ + + - name: Display structure of downloaded files + run: ls -Rl ./ci-artifacts/ + + - name: Prepare Windows Build Assets + run: | + mkdir -p ./ci-artifacts/windows + mkdir -p ${{ inputs.outputDir }}/dist + chmod +x ./.github/scripts/releases/extract_mod_build_windows.sh + ./.github/scripts/releases/extract_mod_build_windows.sh ./ci-artifacts/windows ./ci-artifacts/opengoal-windows-static ./ + TAG_VAL=${{ needs.create_release.outputs.bundleTagName }} + 7z a -tzip ${{ inputs.outputDir }}/dist/windows-${TAG_VAL}.zip ./ci-artifacts/windows/* + + - name: Upload Bundle + uses: actions/upload-artifact@v4 + with: + name: windows + if-no-files-found: error + path: ${{ inputs.outputDir }}/dist + + build_linux_clang: + name: "Linux Build" + needs: create_release + if: ${{ !inputs.skipLinux && inputs.buildBinaries }} + # assumes that this file is defined in your mod repo + uses: ./.github/workflows/linux-build-clang.yaml + with: + cmakePreset: "Release-linux-clang-static" + cachePrefix: "static" + uploadArtifacts: true + secrets: inherit + + bundle_linux_build: + name: "Bundle Linux Build" + needs: + - create_release + - build_linux_clang + if: ${{ !inputs.skipLinux && inputs.buildBinaries }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.create_release.outputs.bundleTagName }} + + - name: "Checkout Repository" + uses: actions/checkout@v4 + + - name: Prepare Artifact Folder + run: mkdir -p ./ci-artifacts + + - uses: actions/download-artifact@v4 + name: Download all Artifacts + with: + path: ./ci-artifacts/ + + - name: Display structure of downloaded files + run: ls -Rl ./ci-artifacts/ + + - name: Prepare Linux Build Assets + run: | + mkdir -p ./ci-artifacts/linux + mkdir -p ${{ inputs.outputDir }}/dist + chmod +x ./.github/scripts/releases/extract_mod_build_unix.sh + ./.github/scripts/releases/extract_mod_build_unix.sh ./ci-artifacts/linux ./ci-artifacts/opengoal-linux-static ./ + pushd ci-artifacts/linux + TAG_VAL=${{ needs.create_release.outputs.bundleTagName }} + tar czf ../../${{ inputs.outputDir }}/dist/linux-${TAG_VAL}.tar.gz . + popd + + - name: Upload Bundle + uses: actions/upload-artifact@v4 + with: + name: linux + if-no-files-found: error + path: ${{ inputs.outputDir }}/dist + + build_macos_intel: + name: "MacOS Build" + needs: create_release + if: ${{ !inputs.skipMacOS && inputs.buildBinaries }} + # assumes that this file is defined in your mod repo + uses: ./.github/workflows/macos-build.yaml + with: + cmakePreset: "Release-macos-x86_64-clang-static" + cachePrefix: "static" + uploadArtifacts: true + secrets: inherit + + bundle_macos_build: + name: "Bundle MacOS Build" + needs: + - create_release + - build_macos_intel + if: ${{ !inputs.skipMacOS && inputs.buildBinaries }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.create_release.outputs.bundleTagName }} + + - name: "Checkout Repository" + uses: actions/checkout@v4 + + - name: Prepare Artifact Folder + run: mkdir -p ./ci-artifacts + + - uses: actions/download-artifact@v4 + name: Download all Artifacts + with: + path: ./ci-artifacts/ + + - name: Display structure of downloaded files + run: ls -Rl ./ci-artifacts/ + + - name: Prepare MacOS Build Assets + run: | + mkdir -p ./ci-artifacts/macos-intel + mkdir -p ${{ inputs.outputDir }}/dist + chmod +x ./.github/scripts/releases/extract_mod_build_unix.sh + ./.github/scripts/releases/extract_mod_build_unix.sh ./ci-artifacts/macos-intel ./ci-artifacts/opengoal-macos-static ./ + pushd ci-artifacts/macos-intel + TAG_VAL=${{ needs.create_release.outputs.bundleTagName }} + tar czf ../../${{ inputs.outputDir }}/dist/macos-intel-${TAG_VAL}.tar.gz . + popd + + - name: Upload Bundle + uses: actions/upload-artifact@v4 + with: + name: macos-intel + if-no-files-found: error + path: ${{ inputs.outputDir }}/dist + + # if not `buildBinaries`, run the steps to build release assets + + bundle_windows_no_build: + name: "Bundle Windows (no build)" + needs: create_release + if: ${{ !inputs.skipWindows && !inputs.buildBinaries }} + runs-on: ubuntu-latest + steps: + - name: "Checkout Repository" + uses: actions/checkout@v4 + + - name: "Create Windows Release" + env: + outputDir: ${{ inputs.outputDir }} + versionName: ${{ needs.create_release.outputs.bundleTagName }} + toolingRepo: ${{ inputs.toolingRepo }} + toolingVersion: ${{ inputs.toolingVersion }} + run: python ./.github/scripts/create-mod-release/bundle-windows.py + + - name: Upload Bundle + uses: actions/upload-artifact@v4 + with: + name: windows + if-no-files-found: error + path: ${{ inputs.outputDir }}/dist + + bundle_linux_no_build: + name: "Bundle Linux (no build)" + needs: create_release + if: ${{ !inputs.skipLinux && !inputs.buildBinaries }} + runs-on: ubuntu-latest + steps: + - name: "Checkout Repository" + uses: actions/checkout@v4 + + - name: "Create Linux Release" + env: + outputDir: ${{ inputs.outputDir }} + versionName: ${{ needs.create_release.outputs.bundleTagName }} + toolingRepo: ${{ inputs.toolingRepo }} + toolingVersion: ${{ inputs.toolingVersion }} + run: python ./.github/scripts/create-mod-release/bundle-linux.py + + - name: Upload Bundle + uses: actions/upload-artifact@v4 + with: + name: linux + if-no-files-found: error + path: ${{ inputs.outputDir }}/dist + + bundle_macos_no_build: + name: "Bundle macOS Intel (no build)" + needs: create_release + if: ${{ !inputs.skipMacOS && !inputs.buildBinaries }} + runs-on: ubuntu-latest + steps: + - name: "Checkout Repository" + uses: actions/checkout@v4 + + - name: "Create MacOS Intel Release" + env: + outputDir: ${{ inputs.outputDir }} + versionName: ${{ needs.create_release.outputs.bundleTagName }} + toolingRepo: ${{ inputs.toolingRepo }} + toolingVersion: ${{ inputs.toolingVersion }} + run: python ./.github/scripts/create-mod-release/bundle-macos.py + + - name: Upload Bundle + uses: actions/upload-artifact@v4 + with: + name: macos-intel + if-no-files-found: error + path: ${{ inputs.outputDir }}/dist + + finalize_release: + name: "Finalize Release" + needs: + - create_release + - bundle_windows_build + - bundle_linux_build + - bundle_macos_build + - bundle_windows_no_build + - bundle_linux_no_build + - bundle_macos_no_build + if: | + always() && + needs.create_release.result == 'success' && + (needs.bundle_windows_build.result == 'skipped' || needs.bundle_windows_build.result == 'success') && + (needs.bundle_linux_build.result == 'skipped' || needs.bundle_linux_build.result == 'success') && + (needs.bundle_macos_build.result == 'skipped' || needs.bundle_macos_build.result == 'success') && + (needs.bundle_windows_no_build.result == 'skipped' || needs.bundle_windows_no_build.result == 'success') && + (needs.bundle_linux_no_build.result == 'skipped' || needs.bundle_linux_no_build.result == 'success') && + (needs.bundle_macos_no_build.result == 'skipped' || needs.bundle_macos_no_build.result == 'success') + runs-on: ubuntu-latest + steps: + - name: "Checkout Repository" + uses: actions/checkout@v4 + + - name: Prepare Output Folder + run: mkdir -p ${{ inputs.outputDir }}/dist + + - name: Download all Artifacts + uses: actions/download-artifact@v4 + with: + path: ${{ inputs.outputDir }}/artifacts + + - name: Display structure of downloaded files + run: ls -Rl ${{ inputs.outputDir }} + + - name: Move Linux Assets + if: ${{ !inputs.skipLinux }} + run: mv ${{ inputs.outputDir }}/artifacts/linux/* ${{ inputs.outputDir }}/dist + + - name: Move Windows Assets + if: ${{ !inputs.skipWindows }} + run: mv ${{ inputs.outputDir }}/artifacts/windows/* ${{ inputs.outputDir }}/dist + + - name: Move MacOS Assets + if: ${{ !inputs.skipMacOS }} + run: mv ${{ inputs.outputDir }}/artifacts/macos-intel/* ${{ inputs.outputDir }}/dist + + - name: Prepare Release Metadata + env: + SCHEMA_VERSION: "0.1.0" + VERSION: ${{ needs.create_release.outputs.bundleTagName }} + SUPPORTED_GAMES: ${{ inputs.metadataSupportedGames }} + OUT_DIR: "${{ inputs.outputDir }}/dist" + run: python ./.github/scripts/create-mod-release/emit-metadata.py + + - name: Validating Metadata + run: | + npm install -g ajv-cli + ajv validate -s ./.github/schemas/mods/v2/mod-schema.v2.json -d ${{ inputs.outputDir }}/dist/metadata.json + + - name: Upload Assets + env: + GITHUB_TOKEN: ${{ secrets.token }} + run: | + TAG_VAL=${{ needs.create_release.outputs.bundleTagName }} + echo $TAG_VAL + gh release upload "${TAG_VAL}" ${{ github.WORKSPACE }}/${{ inputs.outputDir }}/dist/* --repo ${{ github.repository }} --clobber + + - name: Publish Release + env: + GITHUB_TOKEN: ${{ secrets.token }} + run: | + TAG_VAL=${{ needs.create_release.outputs.bundleTagName }} + echo $TAG_VAL + gh release edit ${TAG_VAL} --draft=false --repo ${{ github.repository }} diff --git a/.github/workflows/release-pipeline.yaml b/.github/workflows/release-pipeline.yaml index 7d818bce62..c6ca628ab4 100644 --- a/.github/workflows/release-pipeline.yaml +++ b/.github/workflows/release-pipeline.yaml @@ -1,16 +1,52 @@ -name: 🏭 Release Pipeline +name: 🏭 Draft Release on: - push: - tags: - - v* + workflow_dispatch: + inputs: + bump: + description: 'Semver Bump Type' + required: true + default: 'patch' + type: choice + options: + - patch + - minor + - major permissions: contents: write jobs: + cut_release: + name: Cut Release + runs-on: ubuntu-latest + outputs: + new_tag: ${{ steps.set_tag.outputs.new_tag }} + steps: + # Docs - https://github.com/mathieudutour/github-tag-action + - name: Bump Version and Push Tag + if: github.repository == 'OpenGOAL-Mods/OG-Mod-Base' + id: tag_version + uses: mathieudutour/github-tag-action@v6.2 + 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: @@ -21,6 +57,8 @@ jobs: # Linux build_linux_clang: + needs: + - cut_release name: "🐧 Linux" uses: ./.github/workflows/linux-build-clang.yaml with: @@ -29,26 +67,44 @@ jobs: uploadArtifacts: true secrets: inherit -# # macOS -# build_macos_intel: -# name: "🍎 MacOS" -# uses: ./.github/workflows/macos-build.yaml -# with: -# cmakePreset: "Release-macos-clang-static" -# cachePrefix: "static" -# uploadArtifacts: true -# secrets: inherit + # macOS + build_macos_intel: + needs: + - cut_release + name: "🍎 MacOS" + uses: ./.github/workflows/macos-build.yaml + with: + cmakePreset: "Release-macos-x86_64-clang-static" + cachePrefix: "static" + uploadArtifacts: true + secrets: inherit + + build_macos_arm: + needs: + - cut_release + name: "🍎 MacOS" + uses: ./.github/workflows/macos-build.yaml + with: + cmakePreset: "Release-macos-x86_64-clang-static" + cachePrefix: "static" + uploadArtifacts: true + secrets: inherit # Upload the Artifacts upload_artifacts: needs: + - cut_release - build_windows_clang - build_linux_clang -# - build_macos_intel + - build_macos_intel + - build_macos_arm name: "Upload Artifacts" runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + fetch-tags: true + fetch-depth: 0 - name: Prepare Artifact Folder run: mkdir -p ./ci-artifacts/final @@ -66,7 +122,7 @@ jobs: mkdir -p ./ci-artifacts/linux ./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts/linux ./ci-artifacts/opengoal-linux-static ./ pushd ci-artifacts/linux - TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}') + TAG_VAL=${{ needs.cut_release.outputs.new_tag }} tar czf ../final/opengoal-linux-${TAG_VAL}.tar.gz . popd chmod +x ./ci-artifacts/opengoal-linux-static/lsp/lsp @@ -76,31 +132,40 @@ jobs: run: | mkdir -p ./ci-artifacts/windows ./.github/scripts/releases/extract_build_windows.sh ./ci-artifacts/windows ./ci-artifacts/opengoal-windows-static ./ - TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}') + TAG_VAL=${{ needs.cut_release.outputs.new_tag }} 7z a -tzip ./ci-artifacts/final/opengoal-windows-${TAG_VAL}.zip ./ci-artifacts/windows/* cp ./ci-artifacts/opengoal-windows-static/lsp.exe ./ci-artifacts/final/opengoal-lsp-windows-${TAG_VAL}.exe -# - name: Prepare macOS Build Assets -# run: | -# mkdir -p ./ci-artifacts/macos -# ./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts/macos ./ci-artifacts/opengoal-macos-static ./ -# pushd ci-artifacts/macos -# TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}') -# tar czf ../final/opengoal-macos-intel-${TAG_VAL}.tar.gz . -# popd -# chmod +x ./ci-artifacts/opengoal-macos-static/lsp/lsp -# cp ./ci-artifacts/opengoal-macos-static/lsp/lsp ./ci-artifacts/final/opengoal-lsp-macos-intel-${TAG_VAL}.bin + - name: Prepare Intel macOS Build Assets + run: | + mkdir -p ./ci-artifacts/macos + ./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts/macos ./ci-artifacts/opengoal-macos-static ./ + pushd ci-artifacts/macos + TAG_VAL=${{ needs.cut_release.outputs.new_tag }} + tar czf ../final/opengoal-macos-intel-${TAG_VAL}.tar.gz . + popd + chmod +x ./ci-artifacts/opengoal-macos-static/lsp/lsp + cp ./ci-artifacts/opengoal-macos-static/lsp/lsp ./ci-artifacts/final/opengoal-lsp-macos-intel-${TAG_VAL}.bin + + - name: Prepare ARM macOS Build Assets + run: | + mkdir -p ./ci-artifacts/macos-arm + ./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts/macos-arm ./ci-artifacts/opengoal-macos-arm-static ./ + pushd ci-artifacts/macos-arm + TAG_VAL=${{ needs.cut_release.outputs.new_tag }} + tar czf ../final/opengoal-macos-arm-${TAG_VAL}.tar.gz . + popd + chmod +x ./ci-artifacts/opengoal-macos-arm-static/lsp/lsp + cp ./ci-artifacts/opengoal-macos-arm-static/lsp/lsp ./ci-artifacts/final/opengoal-lsp-macos-arm-${TAG_VAL}.bin - name: Upload Assets env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}') - gh release upload "${TAG_VAL}" ${{ github.WORKSPACE }}/ci-artifacts/final/* --repo ${{ github.repository }} --clobber + gh release upload ${{ needs.cut_release.outputs.new_tag }} ${{ github.WORKSPACE }}/ci-artifacts/final/* --repo ${{ github.repository }} --clobber - name: Publish Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - TAG_VAL=$(echo ${{ github.REF }} | awk -F'refs/tags/' '{print $2}') - gh release edit ${TAG_VAL} --draft=false --repo ${{ github.repository }} + gh release edit ${{ needs.cut_release.outputs.new_tag }} --draft=false --repo ${{ github.repository }} diff --git a/.github/workflows/update-controller-db.yaml b/.github/workflows/update-controller-db.yaml index 705cd04fb5..3f1c0a2776 100644 --- a/.github/workflows/update-controller-db.yaml +++ b/.github/workflows/update-controller-db.yaml @@ -19,7 +19,7 @@ jobs: wget -O ./game/assets/sdl_controller_db.txt https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt - name: Create Pull Request - uses: peter-evans/create-pull-request@v6 + uses: peter-evans/create-pull-request@v7 with: token: ${{ secrets.BOT_PAT }} author: 'OpenGOALBot ' diff --git a/.github/workflows/windows-build-clang.yaml b/.github/workflows/windows-build-clang.yaml index e597603f6a..d14669ea48 100644 --- a/.github/workflows/windows-build-clang.yaml +++ b/.github/workflows/windows-build-clang.yaml @@ -22,9 +22,19 @@ jobs: timeout-minutes: 60 steps: + # minimal checkout if we're NOT uploading artifacts - name: Checkout Repository + if: ${{ ! inputs.uploadArtifacts }} uses: actions/checkout@v4 + # full checkout with tags if we ARE uploading artifacts + - name: Checkout Repository with Tags + if: ${{ inputs.uploadArtifacts }} + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - name: Install NASM # TODO - Simplify this with just the first command once choco 2.0 rolls out everywhere run: | @@ -36,7 +46,7 @@ jobs: } - name: Setup sccache - uses: hendrikmuhs/ccache-action@v1.2.13 + uses: hendrikmuhs/ccache-action@v1.2.14 with: variant: sccache key: windows-2022-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }} diff --git a/.github/workflows/windows-build-msvc.yaml b/.github/workflows/windows-build-msvc.yaml index 95a852a1c2..3277d0f2ba 100644 --- a/.github/workflows/windows-build-msvc.yaml +++ b/.github/workflows/windows-build-msvc.yaml @@ -19,6 +19,9 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true - name: Install NASM # TODO - Simplify this with just the first command once choco 2.0 rolls out everywhere @@ -31,7 +34,7 @@ jobs: } - name: Setup sccache - uses: hendrikmuhs/ccache-action@v1.2.13 + uses: hendrikmuhs/ccache-action@v1.2.14 with: variant: sccache key: windows-2022-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }} @@ -56,10 +59,10 @@ jobs: set CL=/MP cmake --build build --parallel %NUMBER_OF_PROCESSORS% - - name: Run Tests - timeout-minutes: 10 - env: - GTEST_OUTPUT: "xml:opengoal-test-report.xml" - run: | - ./build/bin/goalc-test.exe --gtest_color=yes --gtest_brief=0 --gtest_filter="-*MANUAL_TEST*" + # - name: Run Tests + # timeout-minutes: 10 + # env: + # GTEST_OUTPUT: "xml:opengoal-test-report.xml" + # run: | + # ./build/bin/goalc-test.exe --gtest_color=yes --gtest_brief=0 --gtest_filter="-*MANUAL_TEST*" diff --git a/.gitignore b/.gitignore index ccd6067f58..3fd341d572 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # logs /log prof.json +/gpu-test.json # for CMake /Testing @@ -62,19 +63,9 @@ node_modules/ # custom_assets/jak3/texture_replacements/* # merc replacements -custom_assets/jak1/merc_replacements/* -custom_assets/jak2/merc_replacements/* -custom_assets/jak3/merc_replacements/* - -# merc replacements -custom_assets/jak1/merc_replacements/* -custom_assets/jak2/merc_replacements/* -custom_assets/jak3/merc_replacements/* - -# merc replacements -custom_assets/jak1/merc_replacements/* -custom_assets/jak2/merc_replacements/* -custom_assets/jak3/merc_replacements/* +# custom_assets/jak1/merc_replacements/* +# custom_assets/jak2/merc_replacements/* +# custom_assets/jak3/merc_replacements/* # generated cmake files svnrev.h @@ -113,4 +104,5 @@ unifont-15.0.03.ttf out/jak2/fr3.rar *.diff -goalc-report.html \ No newline at end of file +goalc-report.html +/third-party diff --git a/.vs/launch.vs.json b/.vs/launch.vs.json index a7a463646c..801a04453d 100644 --- a/.vs/launch.vs.json +++ b/.vs/launch.vs.json @@ -138,6 +138,19 @@ "-debug" ] }, + { + "type": "default", + "project": "CMakeLists.txt", + "projectTarget": "gk.exe (bin\\gk.exe)", + "name": "Game - GPU Test", + "args": [ + "-v", + "--gpu-test", + "opengl", + "--gpu-test-out-path", + "./gpu-test.json" + ] + }, { "type": "default", "project": "CMakeLists.txt", diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b17369f03..03fa90cde4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.12) set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) project(jak) include(CTest) @@ -44,6 +45,10 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") -Wall \ -Wno-c++11-narrowing \ -Wno-c++98-compat \ + -Wno-deprecated-this-capture \ + -Wno-missing-field-initializers \ + -Wno-sign-compare \ + -Wno-ignored-qualifiers \ -O3 \ -D_CRT_SECURE_NO_WARNINGS") @@ -53,7 +58,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # Note: this is only _reserved_ memory, not necessarily _committed_ memory set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LDFLAGS} -Xlinker /STACK:16000000") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -g -Wextra") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -g") endif() # additional c++ and linker flags for release mode for our projects @@ -284,6 +289,10 @@ include(test/CMakeLists.txt) build_third_party_lib(lzokay lzokay) build_third_party_lib(stb_image stb_image) +# build draco library for tinygltf compression support +include_directories(third-party/draco/src) +add_subdirectory(third-party/draco) +add_compile_definitions(TINYGLTF_ENABLE_DRACO) build_third_party_lib(tiny_gltf tiny_gltf) build_third_party_lib(xdelta3 xdelta3) diff --git a/CMakePresets.json b/CMakePresets.json index 1fe236756b..3cf4289e9f 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -78,6 +78,22 @@ "CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install/${presetName}" } }, + { + "name": "base-macos-arm64", + "hidden": true, + "cacheVariables": { + "CMAKE_APPLE_SILICON_PROCESSOR": "arm64", + "CMAKE_OSX_ARCHITECTURES": "arm64" + } + }, + { + "name": "base-macos-x86_64", + "hidden": true, + "cacheVariables": { + "CMAKE_APPLE_SILICON_PROCESSOR": "x86_64", + "CMAKE_OSX_ARCHITECTURES": "x86_64" + } + }, { "name": "base-clang", "hidden": true, @@ -159,16 +175,32 @@ "inherits": ["base-linux-release", "base-clang"] }, { - "name": "Release-macos-clang", - "displayName": "MacOS Release (clang)", - "description": "Build with Clang as Release without Debug Symbols", - "inherits": ["base-macos-release", "base-clang"] + "name": "Release-macos-arm64-clang", + "displayName": "MacOS ARM64 Release (clang)", + "description": "Build for ARM64 with Clang as Release without Debug Symbols", + "inherits": ["base-macos-release", "base-macos-arm64", "base-clang"] }, { - "name": "Release-macos-clang-static", - "displayName": "MacOS Static Release (clang)", - "description": "Build with Clang as Release without Debug Symbols but statically linked", - "inherits": ["base-macos-release", "base-clang"], + "name": "Release-macos-x86_64-clang", + "displayName": "MacOS x86_64 Release (clang)", + "description": "Build for x86_64 with Clang as Release without Debug Symbols", + "inherits": ["base-macos-release", "base-macos-x86_64", "base-clang"] + }, + { + "name": "Release-macos-arm64-clang-static", + "displayName": "MacOS ARM64 Static Release (clang)", + "description": "Build for ARM64 with Clang as Release without Debug Symbols but statically linked", + "inherits": ["base-macos-release", "base-macos-arm64", "base-clang"], + "cacheVariables": { + "STATICALLY_LINK": "true", + "ZYDIS_BUILD_SHARED_LIB": "OFF" + } + }, + { + "name": "Release-macos-x86_64-clang-static", + "displayName": "MacOS x86_64 Static Release (clang)", + "description": "Build for x86_64 with Clang as Release without Debug Symbols but statically linked, requires MacOS Sequoia", + "inherits": ["base-macos-release", "base-macos-x86_64", "base-clang"], "cacheVariables": { "STATICALLY_LINK": "true", "ZYDIS_BUILD_SHARED_LIB": "OFF" diff --git a/LICENSE b/LICENSE index ebec2b5eed..5af9d46e37 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ ISC License -Copyright (c) 2020-2022 OpenGOAL Team +Copyright (c) 2020-2025 OpenGOAL Team Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/README.md b/README.md index 453c49e318..6d4c65fdf2 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ Our objectives are: We support both Linux and Windows on x86-64. -> We do not support, or plan to support the ARM architecture. This means that this will not run on devices such as an M1 Mac or a mobile device. +> We do not support, or plan to support the ARM architecture. This means that this will not run on devices such as a mobile device. ### Current Status @@ -282,7 +282,7 @@ Then build the entire project as `Windows Release (clang)`. You can also press C ### MacOS -> NOTE: At this time you can only run the game on macOS if you have an Intel processor. +> NOTE: Running the game requires an Apple Silicon Mac running macOS Sequoia, or an Intel Mac. Ensure that you have Xcode command line tools installed (this installs things like Apple Clang). If you don't, you can run the following command: @@ -290,23 +290,25 @@ Ensure that you have Xcode command line tools installed (this installs things li xcode-select --install ``` -#### Intel Based +On Apple Silicon, Rosetta 2 also must be installed: + +```bash +softwareupdate --install-rosetta +``` + +#### Building for x86_64 ```bash -brew install go-task/tap/go-task brew install cmake nasm ninja go-task clang-format -cmake -B build --preset=Release-macos-clang +cmake -B build --preset=Release-macos-x86_64-clang cmake --build build --parallel $((`sysctl -n hw.logicalcpu`)) ``` -#### Apple Silicon - -**Not Supported at This Time** +#### Building for ARM64 (experimental, unsupported) ```bash -brew install go-task/tap/go-task brew install cmake ninja go-task clang-format -cmake -B build --preset=Release-macos-clang +cmake -B build --preset=Release-macos-arm64-clang cmake --build build --parallel $((`sysctl -n hw.logicalcpu`)) ``` diff --git a/Taskfile.yml b/Taskfile.yml index f691c677de..2235b18043 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -10,33 +10,33 @@ dotenv: tasks: # SETTINGS / CONFIGURATION settings: - - 'python ./scripts/tasks/update-env.py --info' + - '{{.PYTHON}} ./scripts/tasks/update-env.py --info' set-game-jak1: - - 'python ./scripts/tasks/update-env.py --game jak1' + - '{{.PYTHON}} ./scripts/tasks/update-env.py --game jak1' set-game-jak2: - - 'python ./scripts/tasks/update-env.py --game jak2' + - '{{.PYTHON}} ./scripts/tasks/update-env.py --game jak2' set-game-jak3: - - 'python ./scripts/tasks/update-env.py --game jak3' + - '{{.PYTHON}} ./scripts/tasks/update-env.py --game jak3' set-decomp-ntscv1: desc: "aka black label" cmds: - - 'python ./scripts/tasks/update-env.py --decomp_config ntscv1' + - '{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config ntscv1' set-decomp-ntscv2: desc: "aka red label" cmds: - - 'python ./scripts/tasks/update-env.py --decomp_config ntscv2' + - '{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config ntscv2' set-decomp-pal: desc: "PAL region version" cmds: - - 'python ./scripts/tasks/update-env.py --decomp_config pal' + - '{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config pal' set-decomp-ntscjp: desc: "NTSC-J region version" cmds: - - 'python ./scripts/tasks/update-env.py --decomp_config ntscjp' + - '{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config ntscjp' set-decomp-ntscko: desc: "NTSC-K region version" cmds: - - 'python ./scripts/tasks/update-env.py --decomp_config ntscko' + - '{{.PYTHON}} ./scripts/tasks/update-env.py --decomp_config ntscko' # GENERAL extract: desc: "Extracts the game's assets from './iso_data' with the set decompiler config" @@ -67,6 +67,14 @@ tasks: cmds: - "{{.GK_BIN_RELEASE_DIR}}/gk -v --game {{.GAME}} -- -fakeiso -debug" # DEVELOPMENT + gen-cmake: + desc: "Generate the CMake" + cmds: + - "cmake -B build --preset={{.CMAKE_PRESET}}" + build: + desc: "Build the project using the generated CMake" + cmds: + - "cmake --build build --parallel {{.CMAKE_NUM_THREADS}}" repl: desc: "Start the REPL" preconditions: @@ -83,9 +91,9 @@ tasks: format: desc: "Format code" cmds: - - cmd: python ./scripts/cpp/format-includes.py - - cmd: python ./scripts/ci/lint-trailing-whitespace.py --fix - - cmd: python ./third-party/run-clang-format/run-clang-format.py -r common decompiler game goalc test tools lsp -i + - cmd: '{{.PYTHON}} ./scripts/cpp/format-includes.py' + - cmd: '{{.PYTHON}} ./scripts/ci/lint-trailing-whitespace.py --fix' + - cmd: '{{.PYTHON}} ./third-party/run-clang-format/run-clang-format.py -r common decompiler game goalc test tools lsp -i' - task: format-json format-gsrc: desc: "Run formatter on gsrc file" @@ -103,28 +111,28 @@ tasks: - "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler \"./decompiler/config/{{.DECOMP_CONFIG}}\" \"./iso_data\" \"./decompiler_out\" --version \"{{.DECOMP_CONFIG_VERSION}}\" --config-override '{\"decompile_code\": true, \"levels_extract\": false, \"allowed_objects\": [\"{{.FILE}}\"]}'" decomp-clean: cmds: - - python ./scripts/tasks/clean-decomp.py --game "{{.GAME}}" + - '{{.PYTHON}} ./scripts/tasks/clean-decomp.py --game "{{.GAME}}"' lint-gsrc-file: cmds: - - python ./scripts/gsrc/lint-gsrc-file.py --game {{.GAME}} --file "{{.FILE}}" + - '{{.PYTHON}} ./scripts/gsrc/lint-gsrc-file.py --game {{.GAME}} --file "{{.FILE}}"' update-gsrc: cmds: - - python ./scripts/gsrc/update-gsrc-via-refs.py --game "{{.GAME}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" --decompiler_config {{.DECOMP_CONFIG}} --version {{.DECOMP_CONFIG_VERSION}} + - '{{.PYTHON}} ./scripts/gsrc/update-gsrc-via-refs.py --game "{{.GAME}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" --decompiler_config {{.DECOMP_CONFIG}} --version {{.DECOMP_CONFIG_VERSION}}' update-gsrc-glob: cmds: - - python ./scripts/gsrc/update-gsrc-via-refs.py --game "{{.GAME}}" --file_pattern "{{.GLOB}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" --decompiler_config {{.DECOMP_CONFIG}} --version {{.DECOMP_CONFIG_VERSION}} + - '{{.PYTHON}} ./scripts/gsrc/update-gsrc-via-refs.py --game "{{.GAME}}" --file_pattern "{{.GLOB}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" --decompiler_config {{.DECOMP_CONFIG}} --version {{.DECOMP_CONFIG_VERSION}}' update-gsrc-file: cmds: - task: decomp-file - - python ./scripts/gsrc/update-from-decomp.py --game "{{.GAME}}" --file "{{.FILE}}" + - '{{.PYTHON}} ./scripts/gsrc/update-from-decomp.py --game "{{.GAME}}" --file "{{.FILE}}"' - task: lint-gsrc-file copy-common-naming: cmds: - - python ./scripts/gsrc/copy-common-naming.py --file "{{.FILE}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" + - '{{.PYTHON}} ./scripts/gsrc/copy-common-naming.py --file "{{.FILE}}" --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler"' - task: format-json copy-common-naming-from-refs: cmds: - - python ./scripts/gsrc/copy-common-naming.py --update-names-from-refs --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler" + - '{{.PYTHON}} ./scripts/gsrc/copy-common-naming.py --update-names-from-refs --decompiler "{{.DECOMP_BIN_RELEASE_DIR}}/decompiler"' - task: format-json # ASSET RIPPING rip-textures: @@ -139,10 +147,10 @@ tasks: # TOOLS analyze-ee-memory: cmds: - - python ./scripts/tasks/extract-zip.py --file "{{.FILE}}" --out ./savestate_out/ + - '{{.PYTHON}} ./scripts/tasks/extract-zip.py --file "{{.FILE}}" --out ./savestate_out/' - '{{.MEMDUMP_BIN_RELEASE_DIR}}/memory_dump_tool ./savestate_out/eeMemory.bin --output-path ./ --game {{.GAME}} > ee-analysis.log' watch-pcsx2: - # python -m pip install -U "watchdog[watchmedo]" + # {{.PYTHON}} -m pip install -U "watchdog[watchmedo]" cmds: - watchmedo shell-command --drop --patterns="*.p2s" --recursive --command='task analyze-ee-memory FILE="${watch_src_path}"' "{{.SAVESTATE_DIR}}" vars: @@ -155,15 +163,22 @@ tasks: desc: Updates locally built tree-sitter rules cmds: - cd ../tree-sitter-opengoal && yarn gen - - python ./scripts/tasks/cp.py --src "../tree-sitter-opengoal/src/*" --dest "./third-party/tree-sitter/tree-sitter-opengoal" - - python ./scripts/tasks/cp.py --src "../tree-sitter-opengoal/grammar.js" --dest "./third-party/tree-sitter/tree-sitter-opengoal" + - '{{.PYTHON}} ./scripts/tasks/cp.py --src "../tree-sitter-opengoal/src/*" --dest "./third-party/tree-sitter/tree-sitter-opengoal"' + - '{{.PYTHON}} ./scripts/tasks/cp.py --src "../tree-sitter-opengoal/grammar.js" --dest "./third-party/tree-sitter/tree-sitter-opengoal"' fix-translations: desc: Finds and tries to fix invalid translation Characters cmds: - - python ./scripts/ci/lint-characters.py --fix + - '{{.PYTHON}} ./scripts/ci/lint-characters.py --fix' lint: cmds: - - python ./scripts/ci/lint-trailing-whitespace.py + - '{{.PYTHON}} ./scripts/ci/lint-trailing-whitespace.py' + run-gpu-test: + desc: "Runs the game's built in GPU test" + preconditions: + - sh: test -f {{.GK_BIN_RELEASE_DIR}}/gk{{.EXE_FILE_EXTENSION}} + msg: "Couldn't locate runtime executable in '{{.GK_BIN_RELEASE_DIR}}/gk'" + cmds: + - "{{.GK_BIN_RELEASE_DIR}}/gk -v --gpu-test opengl --gpu-test-out-path ./gpu-test.json" # TESTS offline-tests: # ran by jenkins cmds: @@ -177,17 +192,17 @@ tasks: # TODO - amalgamate offline-tests and this task, run twice if the previous step fails update-ref-tests: cmds: - - cmd: python ./scripts/tasks/delete-file-or-folder.py --path failures + - cmd: '{{.PYTHON}} ./scripts/tasks/delete-file-or-folder.py --path failures' - cmd: '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test --iso_data_path "./iso_data/{{.GAME}}" --game {{.GAME}} --pretty-print --num_threads 32 --dump_current_output --fail-on-cmp' ignore_error: true - - python ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}} + - '{{.PYTHON}} ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}}' - task: offline-tests-fast update-ref-file: cmds: - - cmd: python ./scripts/tasks/delete-file-or-folder.py --path failures + - cmd: '{{.PYTHON}} ./scripts/tasks/delete-file-or-folder.py --path failures' - cmd: '{{.OFFLINETEST_BIN_RELEASE_DIR}}/offline-test --iso_data_path "./iso_data/{{.GAME}}" --file {{.FILE}} --game {{.GAME}} --dump_current_output --fail-on-cmp' ignore_error: true - - python ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}} + - '{{.PYTHON}} ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}}' - task: offline-test-file type-test: cmds: diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 69c86b5216..c71cd15432 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -15,6 +15,13 @@ function(write_revision_h) OUTPUT_VARIABLE GIT_TAG OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + # To support being on a commit with mutiple tags + if(${GIT_TAG} MATCHES "\n") + string(REPLACE "\n" ";" GIT_TAG_LIST "${GIT_TAG}") + list(LENGTH GIT_TAG_LIST GIT_TAG_LIST_LENGTH) + math(EXPR GIT_TAG_LAST_INDEX "${GIT_TAG_LIST_LENGTH} - 1") + list(GET GIT_TAG_LIST ${GIT_TAG_LAST_INDEX} GIT_TAG) + endif() endif() file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/versions/revision.h "#define BUILT_TAG \"${GIT_TAG}\"\n#define BUILT_SHA \"${GIT_SHORT_SHA}\"\n") endfunction() @@ -88,6 +95,7 @@ add_library(common util/Timer.cpp util/unicode_util.cpp util/gltf_util.cpp + util/image_resize.cpp versions/versions.cpp ) diff --git a/common/custom_data/TFrag3Data.cpp b/common/custom_data/TFrag3Data.cpp index e50365ad30..939eb39139 100644 --- a/common/custom_data/TFrag3Data.cpp +++ b/common/custom_data/TFrag3Data.cpp @@ -304,13 +304,15 @@ void TieTree::unpack() { for (auto& draw : static_draws) { draw.unpacked.idx_of_first_idx_in_full_buffer = unpacked.indices.size(); - ASSERT(draw.plain_indices.empty()); + // indices can come from either runs or already in plain indices. for (auto& run : draw.runs) { for (u32 ri = 0; ri < run.length; ri++) { unpacked.indices.push_back(run.vertex0 + ri); } unpacked.indices.push_back(UINT32_MAX); } + unpacked.indices.insert(unpacked.indices.end(), draw.plain_indices.begin(), + draw.plain_indices.end()); } } @@ -406,6 +408,8 @@ void TieTree::serialize(Serializer& ser) { colors.serialize(ser); bvh.serialize(ser); + ser.from_ptr(&use_strips); + ser.from_ptr(&has_per_proto_visibility_toggle); ser.from_string_vector(&proto_names); } @@ -850,4 +854,11 @@ std::size_t PreloadedVertex::hash::operator()(const PreloadedVertex& v) const { std::hash()(v.s) ^ std::hash()(v.t) ^ std::hash()(v.color_index); } +std::size_t PackedTieVertices::Vertex::hash::operator()(const Vertex& v) const { + return std::hash()(v.x) ^ std::hash()(v.y) ^ std::hash()(v.z) ^ + std::hash()(v.r) ^ std::hash()(v.g) ^ std::hash()(v.b) ^ + std::hash()(v.a) ^ std::hash()(v.s) ^ std::hash()(v.t) ^ + std::hash()(v.nx) ^ std::hash()(v.ny) ^ std::hash()(v.nz); +} + } // namespace tfrag3 diff --git a/common/custom_data/Tfrag3Data.h b/common/custom_data/Tfrag3Data.h index 35d27f01a1..2dac7cf479 100644 --- a/common/custom_data/Tfrag3Data.h +++ b/common/custom_data/Tfrag3Data.h @@ -18,7 +18,7 @@ namespace tfrag3 { // - if changing any large things (vertices, vis, bvh, colors, textures) update get_memory_usage // - if adding a new category to the memory usage, update extract_level to print it. -constexpr int TFRAG3_VERSION = 41; +constexpr int TFRAG3_VERSION = 43; enum MemoryUsageCategory { TEXTURE, @@ -116,6 +116,16 @@ struct PackedTieVertices { float s, t; s8 nx, ny, nz; u8 r, g, b, a; + + struct hash { + std::size_t operator()(const Vertex& x) const; + }; + + bool operator==(const Vertex& other) const { + return x == other.x && y == other.y && z == other.z && s == other.s && t == other.t && + nx == other.nx && ny == other.ny && nz == other.nz && r == other.r && g == other.g && + b == other.b && a == other.a; + } }; struct MatrixGroup { @@ -231,7 +241,7 @@ struct ShrubDraw { struct InstancedStripDraw { DrawMode mode; // the OpenGL draw settings. - u32 tree_tex_id = 0; // the texture that should be bound for the draw + s32 tree_tex_id = 0; // the texture that should be bound for the draw // the list of vertices in the draw. This includes the restart code of UINT32_MAX that OpenGL // will use to start a new strip. @@ -420,6 +430,8 @@ struct TieTree { bool has_per_proto_visibility_toggle = false; std::vector proto_names; + bool use_strips = true; + struct { std::vector vertices; // mesh vertices std::vector indices; diff --git a/common/dma/dma.h b/common/dma/dma.h index a7d5ec445c..027cf7c332 100644 --- a/common/dma/dma.h +++ b/common/dma/dma.h @@ -37,7 +37,7 @@ struct DmaTag { DmaTag(u64 value) { spr = (value >> 63); addr = (value >> 32) & 0x7fffffff; - qwc = value & 0xfff; + qwc = value & 0xffff; kind = Kind((value >> 28) & 0b111); } diff --git a/common/formatter/formatter_tree.cpp b/common/formatter/formatter_tree.cpp index b03f7c3e66..a249675108 100644 --- a/common/formatter/formatter_tree.cpp +++ b/common/formatter/formatter_tree.cpp @@ -143,7 +143,7 @@ void FormatterTree::construct_formatter_tree_recursive(const std::string& source } for (size_t i = 0; i < ts_node_child_count(curr_node); i++) { const auto child_node = ts_node_child(curr_node, i); - auto debug_child = ts_node_string(child_node); + [[maybe_unused]] auto debug_child = ts_node_string(child_node); const auto contents = get_source_code(source, child_node); bool skip_node = false; for (const auto& skippable_content : skippable_nodes) { diff --git a/common/formatter/rules/rule_config.cpp b/common/formatter/rules/rule_config.cpp index 829e539d88..9c64a6adf7 100644 --- a/common/formatter/rules/rule_config.cpp +++ b/common/formatter/rules/rule_config.cpp @@ -168,6 +168,39 @@ static FormFormattingConfig new_deftype_rule( return cfg; } +static FormFormattingConfig new_defproc_rule( + int start_index, + int num_columns_to_compute_widths, + const std::vector& 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 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(); + 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(); + temp_list_config->force_inline = false; + temp_list_config->hang_forms = false; + temp_config->default_index_config = temp_list_config; + if (index == 3) { + temp_config->determine_column_widths_for_list_elements = true; + temp_config->num_columns_to_compute_widths = num_columns_to_compute_widths; + } + cfg.index_configs.emplace(index, temp_config); + } + return cfg; +} + static FormFormattingConfig new_binding_rule(int form_head_width) { FormFormattingConfig cfg; cfg.config_set = true; @@ -253,6 +286,9 @@ const std::unordered_map opengoal_form_config {"defmethod", new_defmethod_rule(3)}, {"lambda", new_lambda_rule(2)}, {"deftype", new_deftype_rule(3, 1, {3, 4, 5, 6})}, + {"defproc", new_defproc_rule(3, 1, {3, 4, 5, 6})}, + {"suspend-for", new_flow_rule(2)}, + {"spawn-proc", new_flow_rule(2)}, {"defun", new_flow_rule(3)}, {"defun-recursive", new_flow_rule(4)}, {"defun-debug-recursive", new_flow_rule(4)}, @@ -281,12 +317,14 @@ const std::unordered_map opengoal_form_config {"protect", new_binding_rule(4)}, {"let*", new_binding_rule(5)}, {"rlet", new_binding_rule(5)}, + {"mlet", new_binding_rule(5)}, {"when", new_flow_rule(2)}, {"unless", new_flow_rule(2)}, {"with-profiler", new_flow_rule(2)}, {"with-pc", new_flow_rule(0)}, {"#unless", new_flow_rule(2)}, {"#when", new_flow_rule(2)}, + {"#when-game", new_flow_rule(2)}, {"countdown", new_flow_rule(2)}, {"until", new_flow_rule(2)}, {"loop", new_flow_rule(0)}, diff --git a/common/goos/PrettyPrinter2.cpp b/common/goos/PrettyPrinter2.cpp index d0aa416f52..f12e4828e5 100644 --- a/common/goos/PrettyPrinter2.cpp +++ b/common/goos/PrettyPrinter2.cpp @@ -295,7 +295,7 @@ void break_list(Node* node) { } } else if (name == "until" || name == "while" || name == "dotimes" || name == "countdown" || name == "when" || name == "behavior" || name == "lambda" || name == "defpart" || - name == "define") { + name == "define" || name == "suspend-for") { node->top_line_count = 2; } else if (name == "let" || name == "let*" || name == "rlet" || name == "with-dma-buffer-add-bucket") { @@ -341,9 +341,9 @@ void break_list(Node* node) { void insert_required_breaks(const std::vector& bfs_order) { const std::unordered_set always_break = { - "when", "defun-debug", "countdown", "case", "defun", "defmethod", "let", - "until", "while", "if", "dotimes", "cond", "else", "defbehavior", - "with-pp", "rlet", "defstate", "behavior", "defpart", "loop", "let*"}; + "when", "defun-debug", "countdown", "case", "defun", "defmethod", "let", "until", + "while", "if", "dotimes", "cond", "else", "defbehavior", "with-pp", "rlet", + "defstate", "behavior", "defpart", "loop", "let*", "suspend-for"}; for (auto node : bfs_order) { if (!node->break_list && node->kind == Node::Kind::LIST && node->child_nodes.at(0).kind == Node::Kind::ATOM) { diff --git a/common/repl/config.h b/common/repl/config.h index ff1857be72..c0a5334ffa 100644 --- a/common/repl/config.h +++ b/common/repl/config.h @@ -49,6 +49,7 @@ struct Config { {KeyBind::Modifier::CTRL, "N", "Full build of the game", "(mi)"}}; bool per_game_history = true; bool permissive_redefinitions = false; + std::string iso_path; int get_nrepl_port() { if (temp_nrepl_port != -1) { diff --git a/common/repl/repl_wrapper.cpp b/common/repl/repl_wrapper.cpp index fd2b517dec..d85be66fdb 100644 --- a/common/repl/repl_wrapper.cpp +++ b/common/repl/repl_wrapper.cpp @@ -43,6 +43,15 @@ void Wrapper::print_welcome_message(const std::vector& loaded_proje fmt::format(" Project Path: {}\n", fmt::format(fg(fmt::color::gray), file_util::get_jak_project_dir().string())); message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " - :===: -"); + std::string effective_iso_path; + if (repl_config.iso_path.empty()) { + effective_iso_path = file_util::get_file_path({"iso_data"}); + } else { + effective_iso_path = repl_config.iso_path; + } + message += + fmt::format(" ISO Data Path: {}\n", fmt::format(fg(fmt::color::gray), effective_iso_path)); + message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " --. .--: :--. .--"); message += " nREPL:"; if (!nrepl_alive) { message += fmt::format(fg(fmt::color::red), "DISABLED\n"); @@ -50,22 +59,21 @@ void Wrapper::print_welcome_message(const std::vector& loaded_proje message += fmt::format(fg(fmt::color::light_green), " Listening on {}\n", repl_config.get_nrepl_port()); } - message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " --. .--: :--. .--"); + message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .=======. =======."); message += " Source File Search Dirs: "; const auto search_dir_string = fmt::format("{}", fmt::join(repl_config.asm_file_search_dirs, ",")); message += fmt::format("[{}]\n", fmt::format(fg(fmt::color::gray), search_dir_string)); - message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .=======. =======."); - message += fmt::format(" {} or {} for basic help and usage\n", + message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-=====-. .-=====-"); + message += fmt::format(" {} or {} for basic help and usage\n", fmt::format(fg(fmt::color::cyan), "(repl-help)"), fmt::format(fg(fmt::color::cyan), "(repl-keybinds)")); - message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-=====-. .-=====-"); - message += - fmt::format(" {} to connect to the game\n", fmt::format(fg(fmt::color::cyan), "(lt)")); message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-===========-."); - message += fmt::format(" {} to recompile the active project.\n", + message += + fmt::format(" {} to connect to the game\n", fmt::format(fg(fmt::color::cyan), "(lt)")); + message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-===-."); + message += fmt::format(" {} to recompile the active project.\n", fmt::format(fg(fmt::color::cyan), "(mi)")); - message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-===-.\n"); message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .\n"); fmt::print("{}", message); } diff --git a/common/serialization/subtitles/subtitles.cpp b/common/serialization/subtitles/subtitles.cpp index e189de48ac..4ad154b83e 100644 --- a/common/serialization/subtitles/subtitles.cpp +++ b/common/serialization/subtitles/subtitles.cpp @@ -61,7 +61,10 @@ const std::unordered_map> locale_lookup = {GameVersion::Jak1, {"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "jp-JP", "en-GB", "pt-PT", "fi-FI", "sv-SE", "da-DK", "no-NO", "nl-NL", "pt-BR", "hu-HU", "ca-ES", "is-IS"}}, - {GameVersion::Jak2, {"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "jp-JP", "ko-KR", "en-GB"}}}; + {GameVersion::Jak2, {"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "jp-JP", "ko-KR", "en-GB"}}, + {GameVersion::Jak3, + {"en-US", "fr-FR", "de-DE", "es-ES", "it-IT", "cm-CM", "jp-JP", "ko-KR", "ru-RU", "pt-PT", + "nl-NL", "en-GB"}}}; std::string lookup_locale_code(const GameVersion game_version, const int language_id) { if (locale_lookup.find(game_version) == locale_lookup.end() || @@ -73,7 +76,8 @@ std::string lookup_locale_code(const GameVersion game_version, const int languag const std::unordered_map> language_ids_with_audio = { {GameVersion::Jak1, {0, 1, 2, 3, 4, 5, 6}}, - {GameVersion::Jak2, {0, 1, 2, 3, 4, 5, 6, 7}}}; + {GameVersion::Jak2, {0, 1, 2, 3, 4, 5, 6, 7}}, + {GameVersion::Jak3, {0, 1, 2, 3, 4, 5, 11}}}; bool dump_language_with_duplicates_from_base(const GameVersion game_version, const int language_id) { diff --git a/common/serialization/subtitles/subtitles_v2.cpp b/common/serialization/subtitles/subtitles_v2.cpp index afc920c30a..49d8917cbb 100644 --- a/common/serialization/subtitles/subtitles_v2.cpp +++ b/common/serialization/subtitles/subtitles_v2.cpp @@ -93,6 +93,55 @@ const std::unordered_map 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 jak3_speaker_name_to_enum_val = { + {"none", 0}, + {"jak", 1}, + {"darkjak", 2}, + {"daxter", 3}, + {"pecker", 4}, + {"ashelin", 5}, + {"veger", 6}, + {"samos", 7}, + {"damas", 8}, + {"kleiver", 9}, + {"seem", 10}, + {"errol", 11}, + {"errol-hologram", 12}, + {"sig", 13}, + {"torn", 14}, + {"tess", 15}, + {"guard", 16}, + {"guard-a", 17}, + {"guard-b", 18}, + {"keira", 19}, + {"vin", 20}, + {"onin", 21}, + {"jinx", 22}, + {"wastelander-male", 23}, + {"wastelander-female", 24}, + {"citizen-male", 25}, + {"citizen-female", 26}, + {"marauder", 27}, + {"oracle", 28}, + {"precursor", 29}, + {"ottsel-leader", 30}, + {"ottsel-surfer", 31}, + {"ottsel-dummy", 32}, + {"ottsel-veger", 33}, + {"ottsel-tess", 34}, + {"computer", 35}, + {"krew", 36}, + {"baron", 37}, + {"scherr", 38}, + {"arey", 39}, + {"baldwin", 40}, + {"schimpf", 41}, + {"martinsen", 42}, + {"phillips", 43}, + {"yates", 44}, +}; + GameSubtitlePackage read_json_files_v2(const GameSubtitleDefinitionFile& file_info) { GameSubtitlePackage package; SubtitleFile lang_lines; @@ -256,11 +305,21 @@ void GameSubtitleBank::add_scenes_from_files(const GameSubtitlePackage& package) } } -// TODO - for jak 3+, this needs some game version context info (could infer from text version) std::vector GameSubtitleBank::speaker_names_ordered_by_enum_value() { // Create a temporary vector of pairs (key, value) - std::vector> temp_vec(jak2_speaker_name_to_enum_val.begin(), - jak2_speaker_name_to_enum_val.end()); + std::vector> temp_vec; + switch (m_text_version) { + case GameTextVersion::JAK2: + temp_vec = {jak2_speaker_name_to_enum_val.begin(), jak2_speaker_name_to_enum_val.end()}; + break; + case GameTextVersion::JAK3: + temp_vec = {jak3_speaker_name_to_enum_val.begin(), jak3_speaker_name_to_enum_val.end()}; + break; + default: + throw std::runtime_error(fmt::format("GameSubtitleBank: invalid game text version {} ({})", + (int)m_text_version, + get_text_version_name(m_text_version))); + } // Sort the temporary vector based on the enum value in ascending order std::sort(temp_vec.begin(), temp_vec.end(), [](const auto& a, const auto& b) { return a.second < b.second; }); @@ -279,13 +338,25 @@ std::vector GameSubtitleBank::speaker_names_ordered_by_enum_value() } u16 GameSubtitleBank::speaker_enum_value_from_name(const std::string& speaker_id) { - if (jak2_speaker_name_to_enum_val.find(speaker_id) == jak2_speaker_name_to_enum_val.end()) { + std::unordered_map enum_map; + switch (m_text_version) { + case GameTextVersion::JAK2: + enum_map = jak2_speaker_name_to_enum_val; + break; + case GameTextVersion::JAK3: + enum_map = jak3_speaker_name_to_enum_val; + break; + default: + throw std::runtime_error(fmt::format("GameSubtitleBank: invalid game text version {}", + get_text_version_name(m_text_version))); + } + if (enum_map.find(speaker_id) == enum_map.end()) { throw std::runtime_error( fmt::format("'{}' speaker could not be found in the enum value mapping, update it or fix " "the invalid speaker!", speaker_id)); } - return u16(jak2_speaker_name_to_enum_val.at(speaker_id)); + return u16(enum_map.at(speaker_id)); } SubtitleMetadataFile dump_bank_meta_v2(const GameVersion game_version, diff --git a/common/util/gltf_util.cpp b/common/util/gltf_util.cpp index 4ec71e4e70..8c6c8895f3 100644 --- a/common/util/gltf_util.cpp +++ b/common/util/gltf_util.cpp @@ -1,5 +1,7 @@ #include "gltf_util.h" +#include "image_resize.h" + #include "common/log/log.h" namespace gltf_util { @@ -323,7 +325,8 @@ ExtractedVertices gltf_vertices(const tinygltf::Model& model, normals = extract_vec3f(data_ptr, count, byte_stride); for (auto& nrm : normals) { math::Vector4f nrm4(nrm.x(), nrm.y(), nrm.z(), 0.f); - nrm = (w_T_local * nrm4).xyz(); + // we found that normals aren't normalized if an object is scaled in blender. + nrm = (w_T_local * nrm4).xyz().normalized(); } ASSERT(normals.size() == result.size()); } else { @@ -387,7 +390,7 @@ int texture_pool_debug_checker(TexturePool* pool) { } } -int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex) { +int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex, int alpha_shift) { const auto& existing = pool->textures_by_name.find(tex.name); if (existing != pool->textures_by_name.end()) { lg::info("Reusing image: {}", tex.name); @@ -412,6 +415,72 @@ int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex) { tt.data.resize(tt.w * tt.h); ASSERT(tex.image.size() >= tt.data.size()); memcpy(tt.data.data(), tex.image.data(), tt.data.size() * 4); + + // adjust alpha colors for PS2/PC difference + for (auto& color : tt.data) { + u32 alpha = color >> 24; + alpha >>= alpha_shift; + color &= 0xff'ff'ff; + color |= (alpha << 24); + } + return idx; +} + +int texture_pool_add_envmap_control_texture(TexturePool* pool, + const tinygltf::Model& model, + int rgb_image_id, + int mr_image_id, + bool wrap_w, + bool wrap_h) { + const auto& existing = pool->envmap_textures_by_gltf_id.find({rgb_image_id, mr_image_id}); + if (existing != pool->envmap_textures_by_gltf_id.end()) { + lg::info("Reusing envmap textures"); + return existing->second; + } + const auto& rgb_tex = model.images.at(rgb_image_id); + const auto& mr_tex = model.images.at(mr_image_id); + lg::info("new envmap texture {} {}", rgb_tex.name, mr_tex.name); + ASSERT(rgb_tex.bits == 8); + ASSERT(rgb_tex.component == 4); + ASSERT(rgb_tex.pixel_type == TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE); + + ASSERT(mr_tex.bits == 8); + ASSERT(mr_tex.pixel_type == TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE); + ASSERT(mr_tex.component == 4); + + std::vector resized_mr_tex; + const u8* mr_src; + if (rgb_tex.width == mr_tex.width && rgb_tex.height == mr_tex.height) { + mr_src = mr_tex.image.data(); + } else { + resized_mr_tex.resize(rgb_tex.width * rgb_tex.height * 4); + resize_rgba_image(resized_mr_tex.data(), rgb_tex.width, rgb_tex.height, mr_tex.image.data(), + mr_tex.width, mr_tex.height, wrap_w, wrap_h); + mr_src = resized_mr_tex.data(); + } + + size_t idx = pool->textures_by_idx.size(); + pool->envmap_textures_by_gltf_id[{rgb_image_id, mr_image_id}] = idx; + auto& tt = pool->textures_by_idx.emplace_back(); + tt.w = rgb_tex.width; + tt.h = rgb_tex.height; + tt.debug_name = rgb_tex.name; + tt.debug_tpage_name = "custom-level"; + tt.load_to_pool = false; + tt.combo_id = 0; // doesn't matter, not a pool tex + tt.data.resize(tt.w * tt.h); + ASSERT(rgb_tex.image.size() >= tt.data.size()); + memcpy(tt.data.data(), rgb_tex.image.data(), tt.data.size() * 4); + + // adjust alpha from metallic channel + for (size_t i = 0; i < tt.data.size(); i++) { + u32 rgb = tt.data[i]; + u32 metal = mr_src[4 * i + 2] / 4; + rgb &= 0xff'ff'ff; + rgb |= (metal << 24); + tt.data[i] = rgb; + } + return idx; } @@ -549,22 +618,38 @@ void dedup_vertices(const std::vector& vertices_in, } } -DrawMode draw_mode_from_sampler(const tinygltf::Sampler& sampler) { - DrawMode mode = make_default_draw_mode(); +void setup_alpha_from_material(const tinygltf::Material& material, DrawMode* mode) { + if (material.alphaMode == "OPAQUE") { + mode->disable_ab(); + } else if (material.alphaMode == "MASK") { + mode->enable_at(); + mode->set_alpha_test(DrawMode::AlphaTest::GEQUAL); + mode->set_alpha_fail(GsTest::AlphaFail::KEEP); + mode->set_aref(material.alphaCutoff * 127); + } else if (material.alphaMode == "BLEND") { + mode->enable_ab(); + mode->set_alpha_blend(DrawMode::AlphaBlend::SRC_DST_SRC_DST); + mode->set_depth_write_enable(false); + } else { + lg::die("Unknown GLTF alphaMode {}", material.alphaMode); + } +} + +void setup_draw_mode_from_sampler(const tinygltf::Sampler& sampler, DrawMode* mode) { if (sampler.magFilter == TINYGLTF_TEXTURE_FILTER_NEAREST) { - ASSERT(sampler.minFilter == TINYGLTF_TEXTURE_FILTER_NEAREST); - mode.set_filt_enable(false); + ASSERT(sampler.minFilter == TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST); + mode->set_filt_enable(false); } else { ASSERT(sampler.minFilter != TINYGLTF_TEXTURE_FILTER_NEAREST); - mode.set_filt_enable(true); + mode->set_filt_enable(true); } switch (sampler.wrapS) { case TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE: - mode.set_clamp_s_enable(true); + mode->set_clamp_s_enable(true); break; case TINYGLTF_TEXTURE_WRAP_REPEAT: - mode.set_clamp_s_enable(false); + mode->set_clamp_s_enable(false); break; default: ASSERT(false); @@ -572,16 +657,27 @@ DrawMode draw_mode_from_sampler(const tinygltf::Sampler& sampler) { switch (sampler.wrapT) { case TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE: - mode.set_clamp_t_enable(true); + mode->set_clamp_t_enable(true); break; case TINYGLTF_TEXTURE_WRAP_REPEAT: - mode.set_clamp_t_enable(false); + mode->set_clamp_t_enable(false); break; default: ASSERT(false); } +} - return mode; +EnvmapSettings envmap_settings_from_gltf(const tinygltf::Material& mat) { + EnvmapSettings settings; + + ASSERT(mat.extensions.contains("KHR_materials_specular")); + const auto& specular_extension = mat.extensions.at("KHR_materials_specular"); + ASSERT(specular_extension.Has("specularColorTexture")); + + auto& texture = specular_extension.Get("specularColorTexture"); + ASSERT(texture.Has("index")); + settings.texture_idx = texture.Get("index").Get(); + return settings; } std::optional find_single_skin(const tinygltf::Model& model, @@ -622,4 +718,22 @@ std::vector extract_floats(const tinygltf::Model& model, int accessor_idx return result; } +std::size_t TieFullVertex::hash::operator()(const TieFullVertex& x) const { + return tfrag3::PackedTieVertices::Vertex::hash()(x.vertex) ^ std::hash()(x.color_index); +} + +tfrag3::PackedTimeOfDay pack_time_of_day(const std::vector>& color_palette) { + tfrag3::PackedTimeOfDay colors; + colors.color_count = (color_palette.size() + 3) & (~3); + colors.data.resize(colors.color_count * 8 * 4); + for (u32 color_index = 0; color_index < color_palette.size(); color_index++) { + for (u32 palette = 0; palette < 8; palette++) { + for (u32 channel = 0; channel < 4; channel++) { + colors.read(color_index, palette, channel) = color_palette[color_index][channel]; + } + } + } + return colors; +} + } // namespace gltf_util \ No newline at end of file diff --git a/common/util/gltf_util.h b/common/util/gltf_util.h index 4428394bdb..d52f4780a2 100644 --- a/common/util/gltf_util.h +++ b/common/util/gltf_util.h @@ -61,9 +61,16 @@ DrawMode make_default_draw_mode(); struct TexturePool { std::unordered_map textures_by_name; std::vector textures_by_idx; + std::map, int> envmap_textures_by_gltf_id; }; -int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex); +int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex, int alpha_shift = 1); +int texture_pool_add_envmap_control_texture(TexturePool* pool, + const tinygltf::Model& model, + int rgb_image_id, + int mr_image_id, + bool wrap_w, + bool wrap_h); int texture_pool_debug_checker(TexturePool* pool); struct NodeWithTransform { @@ -71,13 +78,53 @@ struct NodeWithTransform { math::Matrix4f w_T_node; }; -void dedup_vertices(const std::vector& vertices_in, - std::vector& vertices_out, - std::vector& old_to_new_out); +struct TieFullVertex { + tfrag3::PackedTieVertices::Vertex vertex; + u16 color_index = 0; + struct hash { + std::size_t operator()(const TieFullVertex& x) const; + }; + + bool operator==(const TieFullVertex& other) const { + return vertex == other.vertex && color_index == other.color_index; + } +}; + +template +void dedup_vertices(const std::vector& vertices_in, + std::vector& vertices_out, + std::vector& old_to_new_out) { + ASSERT(vertices_out.empty()); + ASSERT(old_to_new_out.empty()); + old_to_new_out.resize(vertices_in.size(), -1); + + std::unordered_map vtx_to_new; + + for (size_t in_idx = 0; in_idx < vertices_in.size(); in_idx++) { + auto& vtx = vertices_in[in_idx]; + const auto& lookup = vtx_to_new.find(vtx); + if (lookup == vtx_to_new.end()) { + // first time seeing this one + size_t new_idx = vertices_out.size(); + vertices_out.push_back(vtx); + old_to_new_out[in_idx] = new_idx; + vtx_to_new[vtx] = new_idx; + } else { + old_to_new_out[in_idx] = lookup->second; + } + } +} std::vector flatten_nodes_from_all_scenes(const tinygltf::Model& model); -DrawMode draw_mode_from_sampler(const tinygltf::Sampler& sampler); +void setup_alpha_from_material(const tinygltf::Material& material, DrawMode* mode); +void setup_draw_mode_from_sampler(const tinygltf::Sampler& sampler, DrawMode* mode); + +struct EnvmapSettings { + int texture_idx = -1; +}; + +EnvmapSettings envmap_settings_from_gltf(const tinygltf::Material& mat); /*! * Find the index of the skin for this model. Returns nullopt if there is no skin, the index of the @@ -127,4 +174,7 @@ std::vector extract_floats(const tinygltf::Model& model, int accessor_idx math::Matrix4f matrix_from_trs(const math::Vector3f& trans, const math::Vector4f& quat, const math::Vector3f& scale); + +tfrag3::PackedTimeOfDay pack_time_of_day(const std::vector>& color_palette); + } // namespace gltf_util \ No newline at end of file diff --git a/common/util/image_resize.cpp b/common/util/image_resize.cpp new file mode 100644 index 0000000000..49ace91603 --- /dev/null +++ b/common/util/image_resize.cpp @@ -0,0 +1,101 @@ +#include "image_resize.h" + +#include + +#include "common/math/Vector.h" + +namespace { +struct BilinearSample { + int i0, i1; + double w0, w1; +}; + +BilinearSample bilinear(int src_i, double sample, bool wrap) { + BilinearSample result; + + const double px_size = 1. / double(src_i); + const double px_center_f = (sample - 0.5 * px_size) / px_size; + const int px_floor = std::floor(px_center_f); + const double frac = px_center_f - double(px_floor); + + if (px_center_f < 0) { // off the bottom + if (wrap) { + // wrap around! + result.i0 = 0; + result.i1 = src_i - 1; + result.w1 = -px_center_f; + result.w0 = 1. - result.w1; + } else { + // clamp to edge + result.i0 = 0; + result.i1 = 0; + result.w0 = 1; + result.w1 = 0; + } + } else if (px_floor >= (src_i - 1)) { // off the top + if (wrap) { + result.i0 = src_i - 1; + result.i1 = 0; + result.w0 = 1. - frac; + result.w1 = frac; + } else { + // clamp + result.i0 = src_i - 1; + result.i1 = src_i - 1; + result.w0 = 1; + result.w1 = 0; + } + } else { + result.i0 = px_floor; + result.i1 = px_floor + 1; + result.w0 = 1. - frac; + result.w1 = frac; + } + + return result; +} + +math::Vector4 sample1(const u8* src, int w, int h, int x, int y) { + (void)h; + int offset = 4 * (y * w + x); + return math::Vector4(src[offset], src[offset + 1], src[offset + 2], src[offset + 3]); +} + +math::Vector4 sample_bilinear(const u8* src, + int w, + int h, + const BilinearSample& x, + const BilinearSample& y) { + auto p00 = sample1(src, w, h, x.i0, y.i0).cast(); + auto p01 = sample1(src, w, h, x.i0, y.i1).cast(); + auto p10 = sample1(src, w, h, x.i1, y.i0).cast(); + auto p11 = sample1(src, w, h, x.i1, y.i1).cast(); + auto p_interp = (p00 * x.w0 * y.w0 + p01 * x.w0 * y.w1 + p10 * x.w1 * y.w0 + p11 * x.w1 * y.w1); + return p_interp.cast(); +} +} // namespace + +void resize_rgba_image(u8* dst, + int dst_w, + int dst_h, + const u8* src, + int src_w, + int src_h, + bool wrap_w, + bool wrap_h) { + const double dst_px_h = 1. / dst_h; + const double dst_px_w = 1. / dst_w; + for (int h = 0; h < dst_h; h++) { + const float h_pos = (double(h) + 0.5) * dst_px_h; + const auto h_sample = bilinear(src_h, h_pos, wrap_h); + for (int w = 0; w < dst_w; w++) { + const float w_pos = (double(w) + 0.5) * dst_px_w; + const auto w_sample = bilinear(src_w, w_pos, wrap_w); + auto result = sample_bilinear(src, src_w, src_h, w_sample, h_sample); + for (int i = 0; i < 4; i++) { + *dst = result[i]; + dst++; + } + } + } +} diff --git a/common/util/image_resize.h b/common/util/image_resize.h new file mode 100644 index 0000000000..f6430da704 --- /dev/null +++ b/common/util/image_resize.h @@ -0,0 +1,12 @@ +#pragma once + +#include "common/common_types.h" + +void resize_rgba_image(u8* dst, + int dst_w, + int dst_h, + const u8* src, + int src_w, + int src_h, + bool wrap_w, + bool wrap_h); \ No newline at end of file diff --git a/common/util/os.cpp b/common/util/os.cpp index 397a0b62fd..f77491c1c4 100644 --- a/common/util/os.cpp +++ b/common/util/os.cpp @@ -3,6 +3,13 @@ #include "common/common_types.h" #include "common/log/log.h" +#ifdef __APPLE__ +#include + +#include +#include +#endif + #ifdef _WIN32 // clang-format off #define NOMINMAX @@ -104,3 +111,23 @@ void setup_cpu_info() { CpuInfo& get_cpu_info() { return gCpuInfo; } + +std::optional get_macos_version() { +#ifndef __APPLE__ + return {}; +#else + char buffer[128]; + size_t bufferlen = 128; + auto ok = sysctlbyname("kern.osproductversion", &buffer, &bufferlen, NULL, 0); + if (ok != 0) { + lg::warn("Unable to check for `kern.osproductversion` to determine macOS version"); + return {}; + } + try { + return std::stod(buffer); + } catch (std::exception& e) { + lg::error("Error occured when attempting to convert sysctl value {} to number", buffer); + return {}; + } +#endif +} \ No newline at end of file diff --git a/common/util/os.h b/common/util/os.h index de779ee67e..79dc63b029 100644 --- a/common/util/os.h +++ b/common/util/os.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include size_t get_peak_rss(); @@ -16,3 +17,5 @@ struct CpuInfo { }; CpuInfo& get_cpu_info(); + +std::optional get_macos_version(); diff --git a/custom_assets/blender_plugins/opengoal.py b/custom_assets/blender_plugins/opengoal.py index e875ad36ee..4452ddc432 100644 --- a/custom_assets/blender_plugins/opengoal.py +++ b/custom_assets/blender_plugins/opengoal.py @@ -90,6 +90,7 @@ def draw_func_ob(self, context): layout = self.layout ob = context.object layout.prop(ob, "set_invisible") + layout.prop(ob, "enable_custom_weights") layout.prop(ob, "set_collision") if (ob.set_collision): layout.prop(ob, "ignore") @@ -116,6 +117,7 @@ def register(): bpy.types.Object.set_invisible = bpy.props.BoolProperty(name="Invisible") bpy.types.Object.set_collision = bpy.props.BoolProperty(name="Apply Collision Properties") + bpy.types.Object.enable_custom_weights = bpy.props.BoolProperty(name="Use Custom Bone Weights") bpy.types.Object.ignore = bpy.props.BoolProperty(name="ignore") bpy.types.Object.noedge = bpy.props.BoolProperty(name="No-Edge") bpy.types.Object.noentity = bpy.props.BoolProperty(name="No-Entity") diff --git a/custom_assets/jak1/audio/sound_replacements/example-money-pickup.mp3 b/custom_assets/jak1/audio/sound_replacements/example-money-pickup.mp3 new file mode 100644 index 0000000000..2308f83397 Binary files /dev/null and b/custom_assets/jak1/audio/sound_replacements/example-money-pickup.mp3 differ diff --git a/custom_assets/jak1/levels/test-zone/test-zone.jsonc b/custom_assets/jak1/levels/test-zone/test-zone.jsonc index 21e7990e21..356bb94275 100644 --- a/custom_assets/jak1/levels/test-zone/test-zone.jsonc +++ b/custom_assets/jak1/levels/test-zone/test-zone.jsonc @@ -56,33 +56,72 @@ // "symbol-list": ["symbol", "sym-1", "sym-2"] // The base actor id for your custom level. If you have multiple levels, this should be unique! - "base_id": 100, + "base_id": 10000, // All art groups you want to use in your custom level. Will add their models and corresponding textures to the FR3 file. // Note: You will still have to add them to your level's .gd file. // "art_groups": ["plat-ag"], - "art_groups": ["babak-ag"], + "art_groups": ["babak-ag", "plat-ag", "plat-eco-ag"], // If you have any custom models in the "custom_assets/jak1/models/custom_levels" folder that you want to use in your level, add them to this list. // Note: Like with art groups, these should also be added to your level's .gd file. "custom_models": ["test-actor"], // Any textures you want to include in your custom level. This is mainly useful for things such as the zoomer HUD, - // which is not in the common level files and has no art group associated with it. + // sky textures and cases where you want to use objects drawn with the generic renderer, + // which also requires you to set a texture remap table and a list of tpages. // To get a list of all the textures, you can extract all of the game's textures // by setting "save_texture_pngs" to true in the decompiler config. + // The format is ["tpage-name", "texture-name1", "texture-name2", ...]. + // If you want all textures from a tpage, you can just do ["tpage-name"]. "textures": [ - // all textures required for the zoomer HUD - // "zoomerhud", - // "zoomerhud-dial", - // "zoomerhud-main-02", - // "zoomerhud-main-03", - // "zoomerhud-pieslice", - // "zoomerhud-heatbg-01", - // "zoomerhud-main-03arrow", - // "zoomerhud-main-03knob" + // Zoomer HUD textures + // ["zoomerhud"], + // Sandover sky textures + ["village1-vis-alpha"] ], + // Which vanilla level's texture remap table to use. + // This is needed if you want to have proper textures for objects that are drawn using generic, such as + // dark eco pools or dying enemies. If you choose to use this, + // the order of art groups and tpages in your level's .gd MUST match the vanilla level's for the textures to work. + "tex_remap": "village1", + + // Which sky to use for your custom level. This needs to be the name of a vanilla level with sky textures. + // Your level's mood update needs to be set up to copy the sky texture (update-mood-default already handles this as an example). + // You also need to add a specific tpage to your level .gd depending on the level you chose: + // training: tpage-1308.go + // village1: tpage-401.go + // beach: tpage-215.go + // jungle: tpage-388.go + // misty: tpage-520.go + // firecanyon: tpage-1123.go + // village2: tpage-921.go + // rolling: tpage-925.go + // sunkenb: tpage-162.go + // swamp: tpage-630.go + // ogre: tpage-1117.go + // village3: tpage-1194.go + // snow: tpage-712.go + // finalboss: tpage-1418.go + // The tpage you choose also has to be in the alpha (4th) slot in the "tpages" list below. + "sky": "village1", + + // Any texture pages that are added to the level's "texture-ids" array. + // These will be logged in and linked as part of level loading. + // There are five tpage categories, in this order: + // - tfrag + // - pris + // - shrub + // - alpha + // - water + // This is also (with the exception of levels that use the zoomer) the order that the tpages are listed in in the vanilla .gd files. + // You need to also add these to your level .gd as well. + // Sky textures use the alpha slot. + // If this is empty and "tex_remap" and "sky" are the same level, this will be auto-filled with the tpages from the + // corresponding level (check its .gd file for the art group/tpage order to copy over). + "tpages": [], + // Ambients you want to use in your custom level. Ambients can be used for various things like changing the music variation (flava), // adding ambient sounds, level name hints, etc. "ambients": [ @@ -98,10 +137,10 @@ } ], - "actors" : [ + "actors": [ { "trans": [-21.6238, 20.0496, 17.1191], // translation - "etype": "fuel-cell", // actor type + "etype": "fuel-cell", // actor type "game_task": "(game-task none)", // associated game task (for powercells, etc) "quat": [0, 0, 0, 1], // quaternion "bsphere": [-21.6238, 19.3496, 17.1191, 10], // bounding sphere @@ -112,11 +151,11 @@ }, { - "trans": [-15.2818, 15.2461, 17.1360], // translation - "etype": "crate", // actor type + "trans": [-15.2818, 15.2461, 17.136], // translation + "etype": "crate", // actor type "game_task": "(game-task none)", // associated game task (for powercells, etc) "quat": [0, 0, 0, 1], // quaternion - "bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere + "bsphere": [-15.2818, 15.2461, 17.136, 10], // bounding sphere "lump": { "name": "test-crate", "crate-type": "'steel", @@ -125,11 +164,11 @@ }, { - "trans": [-5.4630, 17.4553, 1.6169], // translation - "etype": "eco-yellow", // actor type + "trans": [-5.463, 17.4553, 1.6169], // translation + "etype": "eco-yellow", // actor type "game_task": "(game-task none)", // associated game task (for powercells, etc) "quat": [0, 0, 0, 1], // quaternion - "bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere + "bsphere": [-5.463, 17.4553, 1.6169, 10], // bounding sphere "lump": { "name": "test-eco" } @@ -160,23 +199,134 @@ }, { "trans": [-5.41, 3.5, 28.42], // translation - "etype": "test-actor", // actor type + "etype": "test-actor", // actor type "game_task": 0, // associated game task (for powercells, etc) "quat": [0, 0, 0, 1], // quaternion "bsphere": [-7.41, 3.5, 28.42, 10], // bounding sphere "lump": { "name": "test-actor" } + }, + + { + "trans": [0.0, 50.0, 10.0], + "etype": "linear-plat", + "game_task": 0, + "quat": [0, 0, 0, 1], + "bsphere": [0.0, 50.0, 10.0, 10], + "lump": { + "name": "linear-plat-0", + "path": ["vector4m", + [0.0, 50.0, 10.0, 1.0], + [0.0, 50.0, 10.0, 1.0], + [0.0, 60.0, 10.0, 1.0], + [0.0, 50.0, 10.0, 1.0], + [0.0, 50.0, 10.0, 1.0], + [0.0, 60.0, 10.0, 1.0], + [0.0, 50.0, 10.0, 1.0] + ], + "timings": ["float", + 0.0, // offset before starting + 2.0, // down to up (out) + 2.0, // up to down (out) + 6.0, // stay down + 2.0, // down to up (back) + 2.0, // up to down (back) + 0.0 // immediately start back up + ], + "sync": ["float", 14, 0.0] + } + }, + + { + "trans": [0.0, 50.0, 17.0], + "etype": "linear-plat", + "game_task": 0, + "quat": [0, 0, 0, 1], + "bsphere": [0.0, 50.0, 17.0, 10], + "lump": { + "name": "linear-plat-1", + "path": ["vector4m", + [0.0, 50.0, 17.0, 1.0], + [0.0, 50.0, 17.0, 1.0], + [0.0, 60.0, 17.0, 1.0], + [0.0, 50.0, 17.0, 1.0], + [0.0, 50.0, 17.0, 1.0], + [0.0, 60.0, 17.0, 1.0], + [0.0, 50.0, 17.0, 1.0] + ], + "timings": ["float", + 1.0, // offset before starting + 2.0, // down to up (out) + 2.0, // up to down (out) + 4.0, // stay down + 2.0, // down to up (back) + 2.0, // up to down (back) + 1.0 // immediately start back up + ], + "sync": ["float", 14, 0.0] + } + }, + + { + "trans": [0.0, 50.0, 24.0], + "etype": "linear-plat", + "game_task": 0, + "quat": [0, 0, 0, 1], + "bsphere": [0.0, 50.0, 24.0, 10], + "lump": { + "name": "linear-plat-2", + "path": ["vector4m", + [0.0, 50.0, 24.0, 1.0], + [0.0, 50.0, 24.0, 1.0], + [0.0, 60.0, 24.0, 1.0], + [0.0, 50.0, 24.0, 1.0], + [0.0, 50.0, 24.0, 1.0], + [0.0, 60.0, 24.0, 1.0], + [0.0, 50.0, 24.0, 1.0] + ], + "timings": ["float", + 2.0, // offset before starting + 2.0, // down to up (out) + 2.0, // up to down (out) + 2.0, // stay down + 2.0, // down to up (back) + 2.0, // up to down (back) + 2.0 // immediately start back up + ], + "sync": ["float", 14, 0.0] + } + }, + + { + "trans": [0.0, 50.0, 31.0], + "etype": "linear-plat", + "game_task": 0, + "quat": [0, 0, 0, 1], + "bsphere": [0.0, 50.0, 31.0, 10], + "lump": { + "name": "linear-plat-3", + "path": ["vector4m", + [0.0, 50.0, 31.0, 1.0], + [0.0, 50.0, 31.0, 1.0], + [0.0, 60.0, 31.0, 1.0], + [0.0, 50.0, 31.0, 1.0], + [0.0, 50.0, 31.0, 1.0], + [0.0, 60.0, 31.0, 1.0], + [0.0, 50.0, 31.0, 1.0] + ], + "timings": ["float", + 3.0, // offset before starting + 2.0, // down to up (out) + 2.0, // up to down (out) + 0.0, // stay down + 2.0, // down to up (back) + 2.0, // up to down (back) + 0.0 // immediately start back up + ], + "sync": ["float", 14, 0.0] + } } - // { - // "trans": [-7.41, 3.5, 28.42], // translation - // "etype": "plat", // actor type - // "game_task": "(game-task none)", // associated game task (for powercells, etc) - // "quat": [0, 0, 0, 1], // quaternion - // "bsphere": [-7.41, 3.5, 28.42, 10], // bounding sphere - // "lump": { - // "name": "test-plat" - // } - // } + ] -} \ No newline at end of file +} diff --git a/custom_assets/jak1/levels/test-zone/testzone.gd b/custom_assets/jak1/levels/test-zone/testzone.gd index c9acca2a04..8c2a6422cc 100644 --- a/custom_assets/jak1/levels/test-zone/testzone.gd +++ b/custom_assets/jak1/levels/test-zone/testzone.gd @@ -3,10 +3,17 @@ ;; the actual file name still needs to be 8.3 ("TSZ.DGO" - ("static-screen.o" - "test-zone-obs.o" + ("test-zone-obs.o" + "linear-plat.o" + "tpage-398.go" + "tpage-400.go" + "tpage-399.go" + "tpage-401.go" + "tpage-1470.go" "plat-ag.go" + "plat-eco-ag.go" "test-actor-ag.go" "babak-ag.go" "test-zone.go" - )) \ No newline at end of file + ) + ) \ No newline at end of file diff --git a/custom_assets/jak2/audio/sound_replacements/example-skill-pickup.mp3 b/custom_assets/jak2/audio/sound_replacements/example-skill-pickup.mp3 new file mode 100644 index 0000000000..2308f83397 Binary files /dev/null and b/custom_assets/jak2/audio/sound_replacements/example-skill-pickup.mp3 differ diff --git a/custom_assets/jak2/levels/test-zone/test-zone.jsonc b/custom_assets/jak2/levels/test-zone/test-zone.jsonc index 56f08a3adc..1c9319b5a4 100644 --- a/custom_assets/jak2/levels/test-zone/test-zone.jsonc +++ b/custom_assets/jak2/levels/test-zone/test-zone.jsonc @@ -49,27 +49,29 @@ // adds a 'type' tag (using the "symbol" and "string" lump types works the same way): // "spawn-types": ["type", "spyder", "juicer"] - // The base actor id for your custom level. If you have multiple levels, this should be unique! - "base_id": 100, + // The base actor id for your custom level. If you have multiple levels, this should be unique! + "base_id": 100, // All art groups you want to use in your custom level. Will add their models and corresponding textures to the FR3 file. // Removed so that the release builds don't have to double-decompile the game // "art_groups": ["prsn-torture-ag"], - // Any textures you want to include in your custom level. - // This is mainly useful for textures which are not in the common level files and have no art group associated with them. - // To get a list of all the textures, you can extract all of the game's textures - // by setting "save_texture_pngs" to true in the decompiler config. - "textures": [], + // Any textures you want to include in your custom level. + // This is mainly useful for textures which are not in the common level files and have no art group associated with them. + // To get a list of all the textures, you can extract all of the game's textures + // by setting "save_texture_pngs" to true in the decompiler config. + // The format is ["tpage-name", "texture-name1", "texture-name2", ...]. + // If you want all textures from a tpage, you can just do ["tpage-name"]. + "textures": [], - "actors" : [ + "actors": [ { - "trans": [-15.2818, 15.2461, 17.1360], // translation - "etype": "crate", // actor type + "trans": [-15.2818, 15.2461, 17.136], // translation + "etype": "crate", // actor type "game_task": 0, // associated game task (for powercells, etc) "kill_mask": 0, "quat": [0, 0, 0, 1], // quaternion - "bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere + "bsphere": [-15.2818, 15.2461, 17.136, 10], // bounding sphere "lump": { "name": "test-crate", "eco-info": ["eco-info", "(pickup-type health)", 2] @@ -77,12 +79,12 @@ }, { - "trans": [-5.4630, 17.4553, 1.6169], // translation - "etype": "eco-yellow", // actor type + "trans": [-5.463, 17.4553, 1.6169], // translation + "etype": "eco-yellow", // actor type "game_task": "(game-task none)", // associated game task (for powercells, etc) "kill_mask": 0, "quat": [0, 0, 0, 1], // quaternion - "bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere + "bsphere": [-5.463, 17.4553, 1.6169, 10], // bounding sphere "lump": { "name": "test-eco" } @@ -90,7 +92,7 @@ { "trans": [-7.41, 13.5, 28.42], // translation - "etype": "prsn-torture", // actor type + "etype": "prsn-torture", // actor type "game_task": "(game-task none)", // associated game task (for powercells, etc) "quat": [0, 0, 0, 1], // quaternion "bsphere": [-7.41, 13.5, 28.42, 10], // bounding sphere @@ -99,4 +101,4 @@ } } ] -} \ No newline at end of file +} diff --git a/custom_assets/jak3/audio/sound_replacements/example-skill-pickup.mp3 b/custom_assets/jak3/audio/sound_replacements/example-skill-pickup.mp3 new file mode 100644 index 0000000000..2308f83397 Binary files /dev/null and b/custom_assets/jak3/audio/sound_replacements/example-skill-pickup.mp3 differ diff --git a/custom_assets/jak3/levels/test-zone/test-zone.jsonc b/custom_assets/jak3/levels/test-zone/test-zone.jsonc index 1b4b9948dd..dc3d86672a 100644 --- a/custom_assets/jak3/levels/test-zone/test-zone.jsonc +++ b/custom_assets/jak3/levels/test-zone/test-zone.jsonc @@ -49,26 +49,28 @@ // adds a 'type' tag (using the "symbol" and "string" lump types works the same way): // "spawn-types": ["type", "spyder", "juicer"] - // The base actor id for your custom level. If you have multiple levels, this should be unique! - "base_id": 100, + // The base actor id for your custom level. If you have multiple levels, this should be unique! + "base_id": 100, // All art groups you want to use in your custom level. Will add their models and corresponding textures to the FR3 file. // "art_groups": [], - // Any textures you want to include in your custom level. - // This is mainly useful for textures which are not in the common level files and have no art group associated with them. - // To get a list of all the textures, you can extract all of the game's textures - // by setting "save_texture_pngs" to true in the decompiler config. - // "textures": [], + // Any textures you want to include in your custom level. + // This is mainly useful for textures which are not in the common level files and have no art group associated with them. + // To get a list of all the textures, you can extract all of the game's textures + // by setting "save_texture_pngs" to true in the decompiler config. + // The format is ["tpage-name", "texture-name1", "texture-name2", ...]. + // If you want all textures from a tpage, you can just do ["tpage-name"]. + "textures": [], - "actors" : [ + "actors": [ { - "trans": [-15.2818, 15.2461, 17.1360], // translation - "etype": "crate", // actor type + "trans": [-15.2818, 15.2461, 17.136], // translation + "etype": "crate", // actor type "game_task": "(game-task none)", // associated game task (for powercells, etc) "kill_mask": 0, "quat": [0, 0, 0, 1], // quaternion - "bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere + "bsphere": [-15.2818, 15.2461, 17.136, 10], // bounding sphere "lump": { "name": "test-crate", "eco-info": ["eco-info", "(pickup-type gem)", 1] @@ -76,15 +78,15 @@ }, { - "trans": [-5.4630, 17.4553, 1.6169], // translation - "etype": "eco-yellow", // actor type + "trans": [-5.463, 17.4553, 1.6169], // translation + "etype": "eco-yellow", // actor type "game_task": "(game-task none)", // associated game task (for powercells, etc) "kill_mask": 0, "quat": [0, 0, 0, 1], // quaternion - "bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere + "bsphere": [-5.463, 17.4553, 1.6169, 10], // bounding sphere "lump": { "name": "test-eco" } } ] -} \ No newline at end of file +} diff --git a/decompiler/IR2/Form.cpp b/decompiler/IR2/Form.cpp index 3cfb897524..723e088ddb 100644 --- a/decompiler/IR2/Form.cpp +++ b/decompiler/IR2/Form.cpp @@ -3175,7 +3175,7 @@ goos::Object DefskelgroupElement::ClothParams::to_list(const std::string& ag_nam pretty_print::to_symbol(std::to_string(timestep_freq))})); } if (secret != 0) { - auto bits = decompile_bitfield_enum_from_int(TypeSpec("game-secrets"), env.dts->ts, flags); + auto bits = decompile_bitfield_enum_from_int(TypeSpec("game-secrets"), env.dts->ts, secret); result.push_back(pretty_print::build_list( {pretty_print::to_symbol("secret-disable"), pretty_print::to_symbol(fmt::format("(game-secrets {})", fmt::join(bits, " ")))})); diff --git a/decompiler/IR2/GenericElementMatcher.cpp b/decompiler/IR2/GenericElementMatcher.cpp index 54fd5a733a..65a7e796c2 100644 --- a/decompiler/IR2/GenericElementMatcher.cpp +++ b/decompiler/IR2/GenericElementMatcher.cpp @@ -211,6 +211,13 @@ Matcher Matcher::while_loop(const Matcher& condition, const Matcher& body) { return m; } +Matcher Matcher::until_loop(const Matcher& condition, const Matcher& body) { + Matcher m; + m.m_kind = Kind::UNTIL_LOOP; + m.m_sub_matchers = {condition, body}; + return m; +} + Matcher Matcher::any_constant_token(int match_id) { Matcher m; m.m_kind = Kind::ANY_CONSTANT_TOKEN; @@ -671,6 +678,22 @@ bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out, const Env* cons return true; } break; + case Kind::UNTIL_LOOP: { + auto as_until = dynamic_cast(input->try_as_single_active_element()); + if (!as_until) { + return false; + } + + if (!m_sub_matchers.at(0).do_match(as_until->condition, maps_out, env)) { + return false; + } + + if (!m_sub_matchers.at(1).do_match(as_until->body, maps_out, env)) { + return false; + } + return true; + } break; + case Kind::BEGIN: { if ((int)m_sub_matchers.size() != input->size()) { return false; diff --git a/decompiler/IR2/GenericElementMatcher.h b/decompiler/IR2/GenericElementMatcher.h index d1c9d0fca9..66b9a2b1bc 100644 --- a/decompiler/IR2/GenericElementMatcher.h +++ b/decompiler/IR2/GenericElementMatcher.h @@ -69,6 +69,7 @@ class Matcher { const Matcher& false_case); static Matcher if_no_else(const Matcher& condition, const Matcher& true_case); static Matcher while_loop(const Matcher& condition, const Matcher& body); + static Matcher until_loop(const Matcher& condition, const Matcher& body); static Matcher any_constant_token(int match_id = -1); static Matcher constant_token(const std::string& name); static Matcher or_expression(const std::vector& elts); @@ -100,6 +101,7 @@ class Matcher { IF_WITH_ELSE, IF_NO_ELSE, WHILE_LOOP, + UNTIL_LOOP, ANY_CONSTANT_TOKEN, CONSTANT_TOKEN, SC_OR, diff --git a/decompiler/ObjectFile/ObjectFileDB.cpp b/decompiler/ObjectFile/ObjectFileDB.cpp index 393cb113f5..a7af5c823f 100644 --- a/decompiler/ObjectFile/ObjectFileDB.cpp +++ b/decompiler/ObjectFile/ObjectFileDB.cpp @@ -231,10 +231,11 @@ ObjectFileDB::ObjectFileDB(const std::vector& _dgos, StrFileReader reader(obj, version()); // name from the file name std::string base_name = obj_filename_to_name(obj.string()); - ASSERT(reader.chunk_count() == 1); - auto name = reader.get_texture_name(); - add_obj_from_dgo(name, name, reader.get_chunk(0).data(), reader.get_chunk(0).size(), - "TEXSPOOL", config, name); + for (int i = 0; i < reader.chunk_count(); i++) { + auto name = reader.get_chunk_texture_name(i); + add_obj_from_dgo(name, name, reader.get_chunk(i).data(), reader.get_chunk(i).size(), + "TEXSPOOL", config, name); + } } } diff --git a/decompiler/ObjectFile/ObjectFileDB.h b/decompiler/ObjectFile/ObjectFileDB.h index 574e6e28a8..9c0e40cf06 100644 --- a/decompiler/ObjectFile/ObjectFileDB.h +++ b/decompiler/ObjectFile/ObjectFileDB.h @@ -79,12 +79,14 @@ struct LetRewriteStats { int with_dma_buf_add_bucket = 0; int dma_buffer_add_gs_set = 0; int launch_particles = 0; + int call_parent_state_handler = 0; + int suspend_for = 0; int total() const { return dotimes + countdown + abs + abs2 + unused + ja + case_no_else + case_with_else + set_vector + set_vector2 + send_event + font_context_meth + proc_new + attack_info + vector_dot + rand_float_gen + set_let + with_dma_buf_add_bucket + dma_buffer_add_gs_set + - launch_particles; + launch_particles + call_parent_state_handler + suspend_for; } std::string print() const { @@ -111,6 +113,8 @@ struct LetRewriteStats { out += fmt::format(" with_dma_buf_add_bucket: {}\n", with_dma_buf_add_bucket); out += fmt::format(" dma_buffer_add_gs_set: {}\n", dma_buffer_add_gs_set); out += fmt::format(" launch_particles: {}\n", launch_particles); + out += fmt::format(" call_parent_state_handler: {}\n", call_parent_state_handler); + out += fmt::format(" suspend_for: {}\n", suspend_for); return out; } @@ -135,6 +139,8 @@ struct LetRewriteStats { result.set_let = rand_float_gen + other.set_let; result.with_dma_buf_add_bucket = rand_float_gen + other.with_dma_buf_add_bucket; result.launch_particles = launch_particles + other.launch_particles; + result.call_parent_state_handler = call_parent_state_handler + other.call_parent_state_handler; + result.suspend_for = suspend_for + other.suspend_for; return result; } @@ -158,6 +164,8 @@ struct LetRewriteStats { set_let += other.set_let; with_dma_buf_add_bucket += other.with_dma_buf_add_bucket; launch_particles += other.launch_particles; + call_parent_state_handler += other.call_parent_state_handler; + suspend_for += other.suspend_for; return *this; } }; diff --git a/decompiler/analysis/insert_lets.cpp b/decompiler/analysis/insert_lets.cpp index 29d5a420e4..6328f6e34e 100644 --- a/decompiler/analysis/insert_lets.cpp +++ b/decompiler/analysis/insert_lets.cpp @@ -1673,6 +1673,99 @@ FormElement* rewrite_part_tracker_new(const std::string& type, ->try_as_single_element(); } +FormElement* rewrite_call_parent_state_handler(LetElement* in, const Env& env, FormPool& pool) { + // (let ((t9-3 (-> (find-parent-state) code))) + // (if t9-3 + // ((the-as (function none) t9-3)) + // ) + // ) + auto mr = + Matcher::let(false, + {LetEntryMatcher::any(Matcher::deref(Matcher::func("find-parent-state", {}), + false, {DerefTokenMatcher::any_string(1)}), + 0)}, + {Matcher::if_no_else(Matcher::any(), Matcher::any(2))}); + auto let_mr = match(mr, in); + if (!let_mr.matched) { + return nullptr; + } + auto handler = let_mr.maps.strings.at(1); + auto valid_handlers = {"enter", "trans", "code", "post"}; + if (std::find(valid_handlers.begin(), valid_handlers.end(), handler) != valid_handlers.end()) { + std::vector macro_args; + macro_args.push_back(pool.form(handler)); + // there are no examples of this being used with args, so that is not handled for now... + // auto func = let_mr.maps.forms.at(2); + return pool + .form(GenericOperator::make_function( + pool.form("call-parent-state-handler")), + macro_args) + ->try_as_single_element(); + } + return nullptr; +} + +FormElement* rewrite_suspend_for(LetElement* in, const Env& env, FormPool& pool) { + // (let ((gp-1 (current-time))) + // (until (time-elapsed? gp-1 (seconds 0.5)) + // (suspend) + // ) + // ) + // -> + // (suspend-for (seconds 0.5)) + auto until = dynamic_cast(in->body()->at(0)); + if (!until) { + return nullptr; + } + auto mr = Matcher::let( + false, {LetEntryMatcher::any(Matcher::func("current-time", {}), 0)}, + {Matcher::until_loop(Matcher::func("time-elapsed?", {Matcher::any_reg(1), Matcher::any(2)}), + Matcher::any(3))}); + auto let_mr = match(mr, in); + if (!let_mr.matched) { + return nullptr; + } + auto var = let_mr.maps.regs.at(1); + auto time = let_mr.maps.forms.at(2); + auto body = let_mr.maps.forms.at(3); + std::vector macro_args; + std::vector macro_elts; + macro_args.push_back(time); + for (auto& elt : body->elts()) { + auto op = dynamic_cast(elt); + auto suspend = op && op->op() && dynamic_cast(op->op()) && + dynamic_cast(op->op())->kind() == SpecialOp::Kind::SUSPEND; + if (!suspend || elt != body->elts().back()) { + elt->apply_form([&](Form* form) { + for (auto& e : form->elts()) { + auto as_expr = dynamic_cast(e); + if (as_expr) { + RegAccessSet regs; + as_expr->collect_vars(regs, false); + for (auto reg : regs) { + if (reg.to_string(env, RegisterAccess::Print::AS_VARIABLE) == + var.value().to_string(env, RegisterAccess::Print::AS_VARIABLE)) { + e = pool.alloc_element("time"); + } + } + } + } + }); + macro_elts.push_back(elt); + } + } + if (!macro_elts.empty()) { + for (auto elt : macro_elts) { + macro_args.push_back(pool.alloc_single_form(nullptr, elt)); + } + } + return pool + .form( + GenericOperator::make_function(pool.form("suspend-for")), + macro_args) + ->try_as_single_element(); +} + FormElement* rewrite_proc_new(LetElement* in, const Env& env, FormPool& pool) { // this function checks for the process-spawn macros. // it uses recursive form scanning to wrap the macro inside a potential "shell" @@ -2185,6 +2278,12 @@ FormElement* rewrite_let(LetElement* in, const Env& env, FormPool& pool, LetRewr return as_set_vector3; } + auto suspend_for = rewrite_suspend_for(in, env, pool); + if (suspend_for) { + stats.suspend_for++; + return suspend_for; + } + auto as_abs_2 = fix_up_abs_2(in, env, pool); if (as_abs_2) { stats.abs2++; @@ -2215,6 +2314,12 @@ FormElement* rewrite_let(LetElement* in, const Env& env, FormPool& pool, LetRewr return as_attack_info; } + auto as_call_parent_state = rewrite_call_parent_state_handler(in, env, pool); + if (as_call_parent_state) { + stats.call_parent_state_handler++; + return as_call_parent_state; + } + // nothing matched. return nullptr; } diff --git a/decompiler/config.cpp b/decompiler/config.cpp index a47df7c4b6..d3fea94537 100644 --- a/decompiler/config.cpp +++ b/decompiler/config.cpp @@ -329,6 +329,10 @@ Config make_config_via_json(nlohmann::json& json) { inputs_json.at("animated_textures").get>(); } + if (json.contains("common_art_groups")) { + config.common_art_groups = json.at("common_art_groups").get>(); + } + if (inputs_json.contains("common_tpages")) { config.common_tpages = inputs_json.at("common_tpages").get>(); } diff --git a/decompiler/config.h b/decompiler/config.h index 7ac7793a25..12c0bae09e 100644 --- a/decompiler/config.h +++ b/decompiler/config.h @@ -168,6 +168,7 @@ struct Config { std::unordered_map bad_format_strings; std::unordered_set animated_textures; + std::unordered_set common_art_groups; std::unordered_set common_tpages; std::vector levels_to_extract; diff --git a/decompiler/config/jak1/all-types.gc b/decompiler/config/jak1/all-types.gc index 32afabe93b..3a4e8aa1bd 100644 --- a/decompiler/config/jak1/all-types.gc +++ b/decompiler/config/jak1/all-types.gc @@ -287,25 +287,41 @@ ) (defenum pad-buttons - :bitfield #t - :type uint32 - (select 0) - (l3 1) - (r3 2) - (start 3) - (up 4) - (right 5) - (down 6) - (left 7) - (l2 8) - (r2 9) - (l1 10) - (r1 11) - (triangle 12) - (circle 13) - (x 14) - (square 15) - ) + :bitfield #t + :type uint32 + (select 0) + (l3 1) + (r3 2) + (start 3) + (up 4) + (right 5) + (down 6) + (left 7) + (l2 8) + (r2 9) + (l1 10) + (r1 11) + (triangle 12) + (circle 13) + (x 14) + (square 15) + ) + +(defenum abutton-idx + :type uint8 + (right 0) + (left 1) + (up 2) + (down 3) + (triangle 4) + (circle 5) + (x 6) + (square 7) + (l1 8) + (r1 9) + (l2 10) + (r2 11) + ) (defenum gs-psm :bitfield #f @@ -19614,6 +19630,57 @@ (wt31) ) +(defenum water-look + (water-anim-sunken-big-room 0) + (water-anim-sunken-first-room-from-entrance 1) + (water-anim-sunken-qbert-room 2) + (water-anim-sunken-first-right-branch 3) + (water-anim-sunken-circular-with-bullys 4) + (water-anim-sunken-hall-with-one-whirlpool 5) + (water-anim-sunken-hall-with-three-whirlpools 6) + (water-anim-sunken-start-of-helix-slide 7) + (water-anim-sunken-room-above-exit-chamber 8) + (water-anim-sunken-hall-before-big-room 9) + (water-anim-sunken-dark-eco-qbert 10) + (water-anim-sunken-short-piece 11) + (water-anim-sunken-big-room-upper-water 12) + (water-anim-sunken-dark-eco-platform-room 13) + (water-anim-maincave-water-with-crystal 14) + (water-anim-maincave-center-pool 15) + (water-anim-maincave-lower-right-pool 16) + (water-anim-maincave-mid-right-pool 17) + (water-anim-maincave-lower-left-pool 18) + (water-anim-maincave-mid-left-pool 19) + (water-anim-robocave-main-pool 20) + (water-anim-misty-mud-by-arena 21) + (water-anim-misty-mud-above-skeleton 22) + (water-anim-misty-mud-behind-skeleton 23) + (water-anim-misty-mud-above-skull-back 24) + (water-anim-misty-mud-above-skull-front 25) + (water-anim-misty-mud-other-near-skull 26) + (water-anim-misty-mud-near-skull 27) + (water-anim-misty-mud-under-spine 28) + (water-anim-misty-mud-by-dock 29) + (water-anim-misty-mud-island-near-dock 30) + (water-anim-misty-mud-lonely-island 31) + (water-anim-misty-dark-eco-pool 32) + (water-anim-ogre-lava 33) + (water-anim-jungle-river 34) + (water-anim-village3-lava 35) + (water-anim-training-lake 36) + (water-anim-darkcave-water-with-crystal 37) + (water-anim-rolling-water-back 38) + (water-anim-rolling-water-front 39) + (water-anim-sunken-dark-eco-helix-room 40) + (water-anim-finalboss-dark-eco-pool 41) + (water-anim-lavatube-energy-lava 42) + (water-anim-village1-rice-paddy 43) + (water-anim-village1-fountain 44) + (water-anim-village1-rice-paddy-mid 45) + (water-anim-village1-rice-paddy-top 46) + (water-anim-village2-bucket 47) + ) + (deftype water-control (basic) ((flags water-flags :offset-assert 4) (process process-drawable :offset-assert 8) diff --git a/decompiler/config/jak1/jak1_config.jsonc b/decompiler/config/jak1/jak1_config.jsonc index ed1be81595..b0f5b74655 100644 --- a/decompiler/config/jak1/jak1_config.jsonc +++ b/decompiler/config/jak1/jak1_config.jsonc @@ -125,6 +125,12 @@ // whether or not to dump out streamed audio files to decompiler_out//audio "rip_streamed_audio": false, + // art groups that should always be possible to access, e.g. "common_art_groups": ["eichar-racer+0-ag", "racer-ag", "ef-plane-ag"] + "common_art_groups": [], + + // tpages that should always be possible to access, e.g. "common_tpages": [1119], + "common_tpages": [], + //////////////////////////// // PATCHING OPTIONS //////////////////////////// diff --git a/decompiler/config/jak2/all-types.gc b/decompiler/config/jak2/all-types.gc index 781d06623b..3d7cd98e5e 100644 --- a/decompiler/config/jak2/all-types.gc +++ b/decompiler/config/jak2/all-types.gc @@ -4202,6 +4202,22 @@ and the state of the VU memory buffers at the end of the bucket." (confirm 24) ) +(defenum abutton-idx + :type uint8 + (right 0) + (left 1) + (up 2) + (down 3) + (triangle 4) + (circle 5) + (x 6) + (square 7) + (l1 8) + (r1 9) + (l2 10) + (r2 11) + ) + (defenum mouse-buttons :bitfield #t :type uint32 @@ -8802,6 +8818,7 @@ Unlike [[engine]], users can use [[engine-pers]] as a parent class." (progress-graphics-msaa-off #x1338) (progress-graphics-display #x1339) (language-name-finnish #x133a) + (progress-hint-subtitles #x133b) ) ;; ---text-id-h:text-id diff --git a/decompiler/config/jak3/all-types.gc b/decompiler/config/jak3/all-types.gc index 3c168afed3..6737367630 100644 --- a/decompiler/config/jak3/all-types.gc +++ b/decompiler/config/jak3/all-types.gc @@ -4603,6 +4603,24 @@ ) ;; ---pad:pad-buttons +;; +++pad:abutton-idx +(defenum abutton-idx + :type uint8 + (right 0) + (left 1) + (up 2) + (down 3) + (triangle 4) + (circle 5) + (x 6) + (square 7) + (l1 8) + (r1 9) + (l2 10) + (r2 11) + ) +;; ---pad:abutton-idx + ;; +++pad:mouse-buttons (defenum mouse-buttons :bitfield #t @@ -7523,27 +7541,27 @@ ;; +++level-h:bigmap-id (defenum bigmap-id :type uint32 - (bigmap-id-0 0) - (bigmap-id-1 1) + (city 0) + (comb 1) (desert 2) (factory 3) (forest 4) (mhcity 5) (mine 6) (nest 7) - (bigmap-id-8 8) - (no-map 9) - (precursor 10) - (bigmap-id-11 11) + (nest2 8) + (none 9) + (precursor1 10) + (precursor2 11) (rubble 12) - (sewer0 13) - (sewer1 14) - (sewer2 15) + (sewer-hum-kg 13) + (sewer-kg-met 14) + (sewer-met-hum 15) (stadium 16) - (temple 17) - (bigmap-id-18 18) - (bigmap-id-19 19) - (bigmap-id-20 20) + (temple1 17) + (temple2 18) + (temple3 19) + (temple4 20) (tower 21) (volcano 22) (wascity 23) @@ -8288,7 +8306,7 @@ (define-extern *font-default-matrix* matrix) (define-extern *font-work* font-work) (define-extern font-set-tex0 (function (pointer gs-tex0) texture int int int none)) -(define-extern set-font-color (function font-color int rgba rgba rgba int)) +(define-extern set-font-color (function font-color rgba rgba rgba rgba int)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; decomp-h ;; @@ -10724,16 +10742,55 @@ :flag-assert #x900000180 ) +;; +++bigmap-h:bigmap-flag +(defenum bigmap-flag + :type uint32 + :bitfield #t + (bf00 0) + (bf01 1) + (bf02 2) + (bf03 3) + (bf04 4) + (bf05 5) + (bf06 6) + (bf07 7) + (bf08 8) + (bf09 9) + (bf10 10) + (bf11 11) + (bf12 12) + (bf13 13) + (bf14 14) + (bf15 15) + (bf16 16) + (bf17 17) + (ctywide 18) + (waswide 19) + (wasall 20) + (desert 21) + (bf22 22) + (bf23 23) + (bf24 24) + (bf25 25) + (bf26 26) + (bf27 27) + (bf28 28) + (bf29 29) + (bf30 30) + (bf31 31) + ) +;; ---bigmap-h:bigmap-flag + (deftype bigmap (basic) ((drawing-flag symbol :offset-assert 4) ;; guessed by decompiler (loading-flag symbol :offset-assert 8) ;; guessed by decompiler - (bigmap-index uint32 :offset-assert 12) + (bigmap-index bigmap-id :offset-assert 12) (bigmap-image external-art-buffer :offset-assert 16) ;; guessed by decompiler (tpage external-art-buffer :offset-assert 20) ;; guessed by decompiler - (tpage2 basic :offset-assert 24) + (tpage2 external-art-buffer :offset-assert 24) (progress-minimap texture-page :offset-assert 28) ;; guessed by decompiler (progress-minimap2 texture-page :offset-assert 32) - (load-index uint32 :offset-assert 36) + (load-index bigmap-id :offset-assert 36) (x0 int32 :offset-assert 40) (y0 int32 :offset-assert 44) (x1 int32 :offset-assert 48) @@ -10748,29 +10805,29 @@ (scroll vector :inline :offset-assert 176) (pos vector4w :inline :offset-assert 192) (color vector4w :inline :offset-assert 208) - (corner vector 4 :inline :offset-assert 224) ;; guessed by decompiler + (corner vector 4 :inline :offset-assert 224) ;; guessed by decompiler (auto-save-icon-flag symbol :offset-assert 288) ;; guessed by decompiler - (global-flags uint32 :offset-assert 292) + (global-flags bigmap-flag :offset-assert 292) ) :method-count-assert 23 :size-assert #x128 :flag-assert #x1700000128 (:methods - (new (symbol type) _type_) ;; 0 ;; (new (symbol type) _type_) - (bigmap-method-9 () none) ;; 9 ;; (initialize (_type_) none) + (new (symbol type) _type_) ;; 0 + (initialize (_type_) none) ;; 9 (update (_type_) none) ;; 10 - (bigmap-method-11 (_type_) symbol) ;; 11 - (bigmap-method-12 () none) ;; 12 ;; (handle-cpad-inputs (_type_) int) - (bigmap-method-13 () none) ;; 13 ;; (compress-all (_type_) int) + (loaded? (_type_) symbol) ;; 11 + (draw! (_type_ int int int int) none) ;; 12 ;; (handle-cpad-inputs (_type_) int) + (handle-cpad-input (_type_) none) ;; 13 ;; (compress-all (_type_) int) (enable-drawing (_type_) none) ;; 14 (disable-drawing (_type_) int) ;; 15 - (bigmap-method-16 (_type_) none) ;; 16 ;; (dump-to-file (_type_) file-stream) - (bigmap-method-17 () none) ;; 17 ;; (set-pos! (_type_ vector) int) - (bigmap-method-18 () none) ;; 18 ;; (decompress-current-masks! (_type_) int) - (bigmap-method-19 () none) ;; 19 ;; (compress-current-masks! (_type_) int) - (bigmap-method-20 () none) ;; 20 ;; (set-enable-from-position! (_type_) int) - (bigmap-method-21 () none) ;; 21 ;; (maybe-fill-for-position (_type_ int int) int) - (bigmap-method-22 () none) ;; 22 ;; (texture-upload-dma (_type_ dma-buffer (pointer uint32) int int int gs-psm) none) + (set-map-indices! (_type_) none) ;; 16 ;; (dump-to-file (_type_) file-stream) + (set-pos! (_type_ vector) none) ;; 17 + (bigmap-method-18 (_type_ (pointer int32)) none) ;; 18 ;; (decompress-current-masks! (_type_) int) + (texture-upload-dma (_type_ dma-buffer (pointer uint32) int int int gs-psm) none) ;; 19 ;; (compress-current-masks! (_type_) int) + (bigmap-method-20 (_type_ dma-buffer) symbol) ;; 20 ;; (set-enable-from-position! (_type_) int) + (sprite-dma (_type_ dma-buffer int int int int int int) object) ;; 21 ;; (maybe-fill-for-position (_type_ int int) int) + (draw-from-minimap (_type_ dma-buffer connection-minimap) none) ;; 22 ) ) @@ -11485,13 +11542,13 @@ (scan-tmpl dma-gif-packet :inline :offset-assert 192) (color vector4w :inline :offset-assert 224) (line-color uint64 :offset-assert 240) - (scan-colors vector4w 15 :inline :offset-assert 256) ;; guessed by decompiler + (scan-colors vector4w 15 :inline :offset-assert 256) ;; guessed by decompiler (zoom-blur-pos vector :inline :offset-assert 496) (zoom-blur-count int32 :offset-assert 512) (zoom-blur-texels int32 :offset-assert 516) (zoom-blur-alpha-target float :offset-assert 520) (zoom-blur-alpha-current float :offset-assert 524) - (zoom-blur-2d basic :offset-assert 528) + (zoom-blur-2d symbol :offset-assert 528) (menu-mode symbol :offset-assert 532) ;; guessed by decompiler (screen-copied symbol :offset-assert 536) ;; guessed by decompiler (vu1-enable-user-menu vu1-renderer-mask :offset-assert 544) @@ -11509,18 +11566,18 @@ :size-assert #x24c :flag-assert #x1b0000024c (:methods - (blit-displays-work-method-9 () none) ;; 9 - (blit-displays-work-method-10 () none) ;; 10 - (blit-displays-work-method-11 () none) ;; 11 - (blit-displays-work-method-12 () none) ;; 12 - (blit-displays-work-method-13 () none) ;; 13 - (blit-displays-work-method-14 () none) ;; 14 - (blit-displays-work-method-15 () none) ;; 15 - (blit-displays-work-method-16 () none) ;; 16 - (blit-displays-work-method-17 (_type_ vector int float symbol) none) ;; 17 - (blit-displays-work-method-18 () none) ;; 18 - (blit-displays-work-method-19 (_type_) none) ;; 19 (called from main.gc) - (blit-displays-work-method-20 (_type_) none) ;; 20 + (blit-displays-work-method-9 (_type_ dma-buffer int int int) none) ;; 9 + (blit-displays-work-method-10 (_type_ dma-buffer int int int) none) ;; 10 + (blit-displays-work-method-11 (_type_ dma-buffer int) none) ;; 11 + (draw-letterbox (_type_ dma-buffer float int float) none) ;; 12 + (blit-displays-work-method-13 (_type_ dma-buffer int int int) none) ;; 13 + (blit-displays-work-method-14 (_type_ dma-buffer vector) none) ;; 14 + (blit-displays-work-method-15 (_type_ dma-buffer) none) ;; 15 + (draw-zoom-blur (_type_ dma-buffer int) none) ;; 16 + (setup-zoom-blur-2d (_type_ vector int float symbol) none) ;; 17 + (setup-brightness-and-contrast (_type_ dma-buffer float float) none) ;; 18 + (do-blit-displays (_type_) none) ;; 19 (called from main.gc) + (draw-sky (_type_ dma-buffer) none) ;; 20 (get-menu-mode (_type_) symbol) ;; 21 (get-screen-copied (_type_) symbol) ;; 22 (get-horizontal-flip-flag (_type_) symbol) ;; 23 @@ -23068,7 +23125,7 @@ (disable-for-duration (_type_ time-frame) none) ;; 16 (ragdoll-proc-method-17 (_type_ ragdoll-edit-info) none) ;; 17 (ragdoll-proc-method-18 (_type_ ragdoll-edit-info) none) ;; 18 - (ragdoll-proc-method-19 (_type_) none) ;; 19 + (ragdoll-proc-method-19 (_type_) symbol) ;; 19 ) ) @@ -31064,7 +31121,7 @@ (define-extern *blit-displays-work* blit-displays-work) (define-extern draw-color-bars (function blit-displays-work none)) -(define-extern draw-raw-image (function bucket-id art-group int vector vector level int none)) +(define-extern draw-raw-image (function blit-displays-work bucket-id art-group vector vector level int none)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; font-data ;; @@ -39229,7 +39286,7 @@ ;; bigmap ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; (define-extern *bigmap-info-array* object) ;; bigmap-info-array +(define-extern *bigmap-info-array* bigmap-info-array) (define-extern *bigmap* bigmap) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -42123,6 +42180,12 @@ ;; rigid-body ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(deftype rigid-body-stack (structure) + ((vec vector :inline) + (mat matrix :inline) + ) + ) + (deftype rigid-body-work (structure) ((max-ang-momentum float :offset-assert 0) (max-ang-velocity float :offset-assert 4) @@ -44394,9 +44457,9 @@ (within-outer-ring symbol :offset-assert 136) (within-inner-ring symbol :offset-assert 140) (ouched symbol :offset-assert 144) - (bound-cam basic :offset-assert 148) + (bound-cam string :offset-assert 148) (trans vector :inline :offset-assert 160) - (state-time uint64 :offset-assert 176) + (state-time time-frame :offset-assert 176) (jak-in-hint-region symbol :offset-assert 184) (watchers-vulnerable symbol :offset-assert 188) ) @@ -44429,7 +44492,7 @@ standing-down ;; 31 ) (:methods - (tpl-watcher-method-32 (_type_) none) ;; 32 + (init-collision! (_type_) none) ;; 32 ) ) diff --git a/decompiler/config/jak3/jak3_config.jsonc b/decompiler/config/jak3/jak3_config.jsonc index 710820c0c4..7551fcfddc 100644 --- a/decompiler/config/jak3/jak3_config.jsonc +++ b/decompiler/config/jak3/jak3_config.jsonc @@ -73,7 +73,7 @@ "write_hex_near_instructions": false, // to write out "scripts", which are currently just all the linked lists found. mostly a jak 2/3 thing - "write_scripts": true, + "write_scripts": false, // hex dump of code/data files. "hexdump_code": false, diff --git a/decompiler/config/jak3/ntsc_v1/anonymous_function_types.jsonc b/decompiler/config/jak3/ntsc_v1/anonymous_function_types.jsonc index a3d99d12e5..c9e74c36ba 100644 --- a/decompiler/config/jak3/ntsc_v1/anonymous_function_types.jsonc +++ b/decompiler/config/jak3/ntsc_v1/anonymous_function_types.jsonc @@ -1000,5 +1000,10 @@ [12, "(function none :behavior scene-player)"], [13, "(function none :behavior scene-player)"], [14, "(function none :behavior scene-player)"] + ], + "bigmap": [ + [15, "(function external-art-buffer object)"], + [16, "(function external-art-buffer object)"], + [17, "(function external-art-buffer object)"] ] } diff --git a/decompiler/config/jak3/ntsc_v1/hacks.jsonc b/decompiler/config/jak3/ntsc_v1/hacks.jsonc index 9707fcb79c..de1f4f5540 100644 --- a/decompiler/config/jak3/ntsc_v1/hacks.jsonc +++ b/decompiler/config/jak3/ntsc_v1/hacks.jsonc @@ -735,10 +735,6 @@ // there are some missing textures. I don't know what the game actually does here. // the format for entries is [level, tpage, index] "missing_textures": [ - ["lfac", 0, 0], - ["ltow", 0, 0], - ["lcit", 0, 0], - ["pow", 0, 0], ["wasintro", 0, 0], ["lfacctyb", 0, 0], ["intpfall", 0, 0], diff --git a/decompiler/config/jak3/ntsc_v1/inputs.jsonc b/decompiler/config/jak3/ntsc_v1/inputs.jsonc index b83f112576..2f819b6d42 100644 --- a/decompiler/config/jak3/ntsc_v1/inputs.jsonc +++ b/decompiler/config/jak3/ntsc_v1/inputs.jsonc @@ -186,18 +186,18 @@ "DGO/PRECA.DGO", "DGO/PRECB.DGO", "DGO/PRECC.DGO", - // "DGO/PRECD.DGO", - // // title/intro + "DGO/PRECD.DGO", + // title/intro "DGO/WIN.DGO", // wasintro "DGO/TITLE.DGO", "DGO/INTTITLE.DGO", "DGO/INTPALRF.DGO", // intro-palace-roof "DGO/IPF.DGO", // intro-palace-fall "DGO/INTROCST.DGO", - // // outro + // outro "DGO/OUTCAST3.DGO", "DGO/OUTROCST.DGO", - // // museum + // museum "DGO/MUSEUM.DGO", "DGO/MUSEUM2.DGO", "DGO/MUSEUM3.DGO", @@ -311,8 +311,245 @@ "DGO/LWSTDPCK.DGO" ], + // STR files containing a texture that should be used by + // FR3 creation. + "str_texture_file_names": ["STR/PRMINIMA.STR"], + // some objects are part of STR files (streaming data). - "str_file_names": [], + "str_file_names": [ + "STR/ARF1INTR.STR", + "STR/ARF1RES.STR", + "STR/ARF2INTR.STR", + "STR/ARF2RES.STR", + "STR/ARF3INTR.STR", + "STR/ARF3RES.STR", + "STR/AROUTRO.STR", + "STR/ART1INTR.STR", + "STR/CAGSHIEL.STR", + "STR/CATRES.STR", + "STR/CAWRRES.STR", + "STR/CIATIDES.STR", + "STR/CIATOUT.STR", + "STR/CIBBINTR.STR", + "STR/CIBBRES.STR", + "STR/CIBTINTR.STR", + "STR/CIDGRES.STR", + "STR/CIFCEINT.STR", + "STR/CIGC1RES.STR", + "STR/CIGC2INT.STR", + "STR/CIGC2RES.STR", + "STR/CIGCINTR.STR", + "STR/CIGDPUNC.STR", + "STR/CIGTCINT.STR", + "STR/CIHVRES.STR", + "STR/CIPAIB.STR", + "STR/CIPAINTR.STR", + "STR/CIPARES.STR", + "STR/CIPFINTR.STR", + "STR/CIPGINTR.STR", + "STR/CIPGRES.STR", + "STR/CIPHINTR.STR", + "STR/CIPHRES.STR", + "STR/CISFINTR.STR", + "STR/COETEMPL.STR", + "STR/COEXIT.STR", + "STR/DAD06.STR", + "STR/DAD07.STR", + "STR/DAD10.STR", + "STR/DAD12.STR", + "STR/DAD13.STR", + "STR/DAD14.STR", + "STR/DAD16.STR", + "STR/DAD17.STR", + "STR/DAD18.STR", + "STR/DAD20.STR", + "STR/DAD21.STR", + "STR/DAD24.STR", + "STR/DAD31.STR", + "STR/DAD35.STR", + "STR/DAD38.STR", + "STR/DAD57.STR", + "STR/DAD58.STR", + "STR/DAD61.STR", + "STR/DAMOLE.STR", + "STR/DEAR1INT.STR", + "STR/DEAR1RES.STR", + "STR/DEAR2INT.STR", + "STR/DEATIN.STR", + "STR/DEATOUT.STR", + "STR/DEBBINTR.STR", + "STR/DECLINTR.STR", + "STR/DECRINTR.STR", + "STR/DECWIN.STR", + "STR/DEFBIA.STR", + "STR/DEFBINTR.STR", + "STR/DEFBRB.STR", + "STR/DEFBRES.STR", + "STR/DEGRES.STR", + "STR/DEHINTRO.STR", + "STR/DEHRES.STR", + "STR/DEJGOTA.STR", + "STR/DEJGOTB.STR", + "STR/DEJGOTC.STR", + "STR/DEJMINTR.STR", + "STR/DELC2.STR", + "STR/DELC3.STR", + "STR/DELCATCH.STR", + "STR/DEODRB.STR", + "STR/DEODRES.STR", + "STR/DERINTRO.STR", + "STR/DERRA.STR", + // "STR/DESCREEN.STR", + "STR/DPBTURRE.STR", + "STR/FABINTRO.STR", + "STR/FABRES.STR", + "STR/FAI1INTR.STR", + "STR/FAI2INTR.STR", + "STR/FAI3INTR.STR", + "STR/FAI4INTR.STR", + "STR/FASBIB.STR", + "STR/FASBINTR.STR", + "STR/FASBRES.STR", + "STR/FORB.STR", + "STR/FORCRES.STR", + "STR/FOTOMRES.STR", + "STR/FOTOWER.STR", + "STR/GRMANIMS.STR", + "STR/INDROP.STR", + "STR/INFFHQ.STR", + "STR/INLOST.STR", + "STR/INPALACE.STR", + "STR/INRESCUE.STR", + "STR/INTIRED.STR", + "STR/INTRAINI.STR", + "STR/JAA1.STR", + "STR/JAA2.STR", + "STR/JAA3.STR", + "STR/JAA4.STR", + "STR/JAA5.STR", + "STR/JAA6.STR", + "STR/JAA7.STR", + "STR/JABOARD.STR", + "STR/JACARRY.STR", + "STR/JAD1.STR", + "STR/JAD2.STR", + "STR/JAD3.STR", + "STR/JAD4.STR", + "STR/JAD5.STR", + "STR/JADARK.STR", + "STR/JADON.STR", + "STR/JADUMMY.STR", + "STR/JAEBOARD.STR", + "STR/JAEDARK.STR", + "STR/JAEGC.STR", + "STR/JAEGNORM.STR", + "STR/JAEGOLD.STR", + "STR/JAELIGHT.STR", + "STR/JAENORMA.STR", + // "STR/JAEXTERN.STR", + "STR/JAFLDAX.STR", + "STR/JAFLUT.STR", + "STR/JAGUN.STR", + "STR/JAICE.STR", + "STR/JAINDAX.STR", + "STR/JAKANGA.STR", + "STR/JALADDER.STR", + "STR/JALIGHT.STR", + "STR/JAMECH.STR", + "STR/JAPEGASU.STR", + "STR/JAPGLIDE.STR", + "STR/JAPGUN.STR", + "STR/JAPHCAR.STR", + "STR/JAPIDAX.STR", + "STR/JAPILOT.STR", + "STR/JAPOLE.STR", + "STR/JAPWCAR.STR", + "STR/JARACER.STR", + "STR/JASWIM.STR", + "STR/JATENTAC.STR", + "STR/JATUBE.STR", + "STR/JATURRET.STR", + "STR/KRWB1.STR", + "STR/KRWB2.STR", + "STR/KRWB3.STR", + "STR/MIBINTRO.STR", + "STR/MIBRES.STR", + "STR/MIERES.STR", + "STR/MIGEXIT.STR", + "STR/MITINTRO.STR", + "STR/MITRES.STR", + "STR/MU2ANIMS.STR", + "STR/MU3ANIMS.STR", + "STR/MU4ANIMS.STR", + "STR/MUANIMS.STR", + "STR/NEDBARRI.STR", + "STR/NEEINTRO.STR", + "STR/NEHINTRO.STR", + "STR/NEHRES.STR", + "STR/NSB1BREA.STR", + "STR/NSB2BREA.STR", + "STR/PARAINTR.STR", + "STR/PARARA.STR", + "STR/PARARES.STR", + "STR/PARPINTR.STR", + "STR/PEFLY.STR", + "STR/POAINTRO.STR", + "STR/PRDSERES.STR", + "STR/PRDSLOSE.STR", + "STR/PRDSRES.STR", + "STR/PRHA.STR", + "STR/PRHB.STR", + "STR/PRHC.STR", + "STR/PRHFINAL.STR", + // "STR/PRMINIMA.STR", + "STR/PRTRES.STR", + "STR/RATA1INT.STR", + "STR/RATA2INT.STR", + // "STR/SCBOOK.STR", + "STR/SEEINTRO.STR", + "STR/SEGENTRA.STR", + "STR/SEHKENTR.STR", + "STR/SEHKRES.STR", + "STR/SEKENTRA.STR", + "STR/SEKEXIT.STR", + "STR/SEKMINTR.STR", + "STR/SEMEXIT.STR", + "STR/SEMHINTR.STR", + "STR/SEPEXIT.STR", + "STR/SESGRUNT.STR", + "STR/SEWATERS.STR", + "STR/TECINTRO.STR", + "STR/TECRES.STR", + "STR/TEDINTRO.STR", + "STR/TEDRES.STR", + "STR/TEEANIMS.STR", + "STR/TEELAANI.STR", + "STR/TEELODS.STR", + "STR/TEJGLGLI.STR", + "STR/TEOINTRO.STR", + "STR/TEORES.STR", + "STR/TETINTRO.STR", + "STR/TETRA.STR", + "STR/TETRB.STR", + "STR/TEWDESER.STR", + "STR/TODINTRO.STR", + "STR/TODRB.STR", + "STR/TODRES.STR", + "STR/VODRES.STR", + "STR/VOI1INTR.STR", + "STR/VOI1RES.STR", + "STR/VOI2INTR.STR", + "STR/VOI2RES.STR", + "STR/WACINTRO.STR", + "STR/WADRES.STR", + "STR/WAGINTRO.STR", + "STR/WAGRES.STR", + "STR/WALRINTR.STR", + "STR/WALRRES.STR", + "STR/WAPGINTR.STR", + "STR/WAPGRES.STR" + // "STR/WOMAP.STR" + ], // streaming "art" that should be added to GAME.FR3. "str_art_file_names": ["STR/JAEXTERN.STR"], @@ -343,6 +580,12 @@ "VAGWAD.INT" ], + // tpages that should always be possible to access. + "common_tpages": [ + 17, // PRMINIMA progress-minimap + 3349 // PRMINIMA progress-minimap2 + ], + "animated_textures": [ // dark jak "jakc-arm", diff --git a/decompiler/config/jak3/ntsc_v1/label_types.jsonc b/decompiler/config/jak3/ntsc_v1/label_types.jsonc index 98dacdfe8c..fd645f0cb0 100644 --- a/decompiler/config/jak3/ntsc_v1/label_types.jsonc +++ b/decompiler/config/jak3/ntsc_v1/label_types.jsonc @@ -1046,7 +1046,7 @@ "desertf-obs": [["L99", "(inline-array vector)", 2]], "desert-dust-storm": [["L89", "vector"]], "artifact-race": [ - ["L162", "(inline-array talker-speech-class)", 16], + ["L162", "(inline-array talker-speech-class)", 32], ["L160", "vector"], ["L159", "vector"], ["L158", "vector"], diff --git a/decompiler/config/jak3/ntsc_v1/stack_structures.jsonc b/decompiler/config/jak3/ntsc_v1/stack_structures.jsonc index 154795ade5..6d8ddeb6f5 100644 --- a/decompiler/config/jak3/ntsc_v1/stack_structures.jsonc +++ b/decompiler/config/jak3/ntsc_v1/stack_structures.jsonc @@ -429,7 +429,7 @@ "(method 22 rigid-body-control)": [[16, ["inline-array", "vector", 2]]], "(method 23 rigid-body-control)": [[16, ["inline-array", "vector", 2]]], "(method 24 rigid-body-control)": [[16, ["inline-array", "vector", 2]]], - "(method 28 rigid-body-control)": [[16, "rigid-body-impact"]], + "(method 28 rigid-body-control)": [[16, "rigid-body-stack"]], "(method 50 rigid-body-object)": [[16, "rigid-body-impact"]], "(method 51 rigid-body-object)": [[16, "rigid-body-impact"]], "ptest": [[16, "vector"]], @@ -1067,7 +1067,7 @@ [208, ["array", "uint32", 1]] ], "(method 35 was-squad-control)": [ - [16, ["inline-array", "matrix", 2]], + [16, ["inline-array", "matrix", 4]], [240, "cquery-with-5vec"] ], "(method 39 vehicle-wheel)": [[16, "rigid-body-move-work"]], @@ -2513,5 +2513,12 @@ [80, "matrix"], [144, "matrix"], [208, "matrix"] + ], + "(method 12 bigmap)": [[32, "matrix"]], + "(method 22 bigmap)": [ + [16, "vector4w"], + [32, "vector"], + [48, "vector"], + [64, "vector"] ] } diff --git a/decompiler/config/jak3/ntsc_v1/type_casts.jsonc b/decompiler/config/jak3/ntsc_v1/type_casts.jsonc index 61bf2d69af..bba5220544 100644 --- a/decompiler/config/jak3/ntsc_v1/type_casts.jsonc +++ b/decompiler/config/jak3/ntsc_v1/type_casts.jsonc @@ -10857,7 +10857,6 @@ ["_stack_", 76, "float"], ["_stack_", 100, "float"] ], - "real-wang-texture-anim-func": [[[3, 31], "v1", "mood-context"]], "(method 24 sky-work)": [ [256, "s4", "(pointer int32)"], [261, "s4", "(pointer int32)"] @@ -11266,5 +11265,80 @@ [[191, 249], "gp", "shadow-dcache"], [96, "v1", "shadow-dcache"] ], - "real-fog-texture-anim-func": [[[6, 160], "s2", "(pointer uint32)"]] + "real-fog-texture-anim-func": [[[6, 160], "s2", "(pointer uint32)"]], + "(method 22 bigmap)": [ + [22, "s3", "process-drawable"], + [[46, 49], "v1", "entity-actor"], + [58, "a0", "process-drawable"], + [65, "a0", "entity-actor"], + [42, "v1", "entity-actor"], + [55, "s3", "process-drawable"], + [[201, 243], "a1", "(inline-array vector4w)"] + ], + "(method 20 bigmap)": [ + [[3, 95], "s4", "(pointer uint32)"], + [99, "a2", "(pointer uint32)"], + [54, "a2", "(pointer uint32)"] + ], + "(method 12 bigmap)": [ + [85, "v1", "(pointer uint32)"], + [100, "v1", "(pointer uint32)"], + [[142, 145], "s0", "(pointer uint128)"], + ["_stack_", 96, "(inline-array vector4w)"] + ], + "(method 21 bigmap)": [[[10, 38], "v1", "(inline-array vector4w)"]], + "(method 19 blit-displays-work)": [ + [764, "v1", "float"], + [759, "v1", "float"], + [[935, 954], "a1", "(inline-array vector4w)"], + [[857, 875], "a1", "(inline-array vector4w)"], + [[844, 847], "a0", "dma-gif-packet"], + [[921, 924], "v1", "dma-gif-packet"] + ], + "(method 9 blit-displays-work)": [[[2, 36], "v1", "(inline-array vector4w)"]], + "(method 10 blit-displays-work)": [ + [[2, 141], "v1", "(inline-array vector4w)"] + ], + "(method 11 blit-displays-work)": [ + [[2, 30], "v1", "(inline-array vector4w)"] + ], + "(method 12 blit-displays-work)": [ + [[4, 41], "v1", "(inline-array vector4w)"], + [[60, 112], "v1", "(inline-array vector4w)"] + ], + "(method 13 blit-displays-work)": [ + [[41, 44], "v1", "(inline-array vector4w)"], + [[53, 71], "a0", "(inline-array vector4w)"] + ], + "(method 18 blit-displays-work)": [ + [[28, 33], "v1", "dma-gif-packet"], + [[174, 177], "v1", "dma-gif-packet"], + [[186, 202], "a0", "(inline-array vector4w)"] + ], + "draw-raw-image": [[[104, 154], "v1", "(inline-array vector4w)"]], + "draw-color-bars": [ + [[11, 16], "v1", "dma-gif-packet"], + [[28, 54], "v1", "(inline-array vector4w)"] + ], + "(method 20 blit-displays-work)": [ + [[57, 89], "a3", "(inline-array vector4w)"], + [[102, 134], "t1", "(inline-array vector4w)"], + [[176, 209], "t1", "(inline-array vector4w)"], + [[310, 338], "t2", "(inline-array vector4w)"], + [[385, 422], "v1", "(inline-array vector4w)"] + ], + "(method 14 blit-displays-work)": [ + [[88, 91], "v1", "dma-gif-packet"], + [[100, 120], "a0", "(inline-array vector4w)"] + ], + "(method 16 blit-displays-work)": [ + [[35, 79], "s2", "(inline-array vector4w)"], + [[134, 178], "s2", "(inline-array vector4w)"] + ], + "(method 15 blit-displays-work)": [ + [[60, 63], "v1", "dma-gif-packet"], + [[81, 99], "a0", "(inline-array vector4w)"], + [[165, 190], "a0", "(inline-array vector4w)"] + ], + "(event idle progress)": [[[10, 80], "v1", "mc-status-code"]] } diff --git a/decompiler/config/jak3/ntsc_v1/var_names.jsonc b/decompiler/config/jak3/ntsc_v1/var_names.jsonc index 8c6dd5250e..39f24b388d 100644 --- a/decompiler/config/jak3/ntsc_v1/var_names.jsonc +++ b/decompiler/config/jak3/ntsc_v1/var_names.jsonc @@ -2135,5 +2135,14 @@ "vars": { "v0-0": ["type", "assault-target-type"] } + }, + "(method 22 bigmap)": { + "vars": { + "a2-1": ["a2-1", "uint"], + "a3-0": ["a3-0", "uint"] + } + }, + "set-font-color": { + "args": ["idx", "clr0", "clr1", "clr2", "clr3"] } } diff --git a/decompiler/data/StrFileReader.cpp b/decompiler/data/StrFileReader.cpp index 016e809a34..526f92bda3 100644 --- a/decompiler/data/StrFileReader.cpp +++ b/decompiler/data/StrFileReader.cpp @@ -166,7 +166,7 @@ FullName extract_name(const std::string& file_info_name) { name.name = name.name.substr(0, name.name.length() - 6); int chunk_id = 0; int place = 0; - for (int i = 2; i-- > 0;) { + for (int i = 3; i-- > 0;) { char c = name.name.back(); if (c >= '0' && c <= '9') { int val = (c - '0'); @@ -258,9 +258,8 @@ std::string StrFileReader::get_full_name(const std::string& short_name) const { return result; } -std::string StrFileReader::get_texture_name() const { - ASSERT(m_chunks.size() == 1); - const auto& chunk = m_chunks[0]; +std::string StrFileReader::get_chunk_texture_name(int idx) const { + const auto& chunk = m_chunks[idx]; auto find_string = get_texture_page_file_info_string(); int offset; if (find_string_in_data(chunk.data(), int(chunk.size()), find_string, &offset)) { diff --git a/decompiler/data/StrFileReader.h b/decompiler/data/StrFileReader.h index a3120828b8..e1eb5535a6 100644 --- a/decompiler/data/StrFileReader.h +++ b/decompiler/data/StrFileReader.h @@ -22,7 +22,7 @@ class StrFileReader { std::string get_chunk_art_name(int idx) const; std::string get_full_name(const std::string& short_name) const; - std::string get_texture_name() const; + std::string get_chunk_texture_name(int idx) const; private: void init_jak1(const fs::path& file_path); @@ -46,8 +46,9 @@ class StrFileReader { std::string get_texture_page_file_info_string() const { switch (m_version) { case GameVersion::Jak2: - case GameVersion::Jak3: return "/src/jak2/final/texture-page8/"; + case GameVersion::Jak3: + return "/src/jak3/final/texture-page8/"; default: ASSERT_MSG(false, "NYI get_file_info_string version"); break; diff --git a/decompiler/data/game_text.cpp b/decompiler/data/game_text.cpp index bf1f0ec7d4..294b335a78 100644 --- a/decompiler/data/game_text.cpp +++ b/decompiler/data/game_text.cpp @@ -454,7 +454,7 @@ std::string write_spool_subtitles( bool has_spools = false; for (auto& [spool_name, subs] : data) { result += " \"" + spool_name + "\": {\n"; - result += " \"scene\": true,\n"; + // result += " \"scene\": true,\n"; result += " \"lines\": [\n"; bool has_subs = false; for (auto& sub : subs) { @@ -463,20 +463,20 @@ std::string write_spool_subtitles( continue; } result += " {\n"; - result += " \"end\": " + float_to_string(sub.end_frame) + ",\n"; + result += " \"frame_end\": " + float_to_string(sub.end_frame) + ",\n"; + result += " \"frame_start\": " + float_to_string(sub.start_frame) + ",\n"; if (dump_text) { result += " \"merge\": false,\n"; } else { result += " \"merge\": true,\n"; } result += " \"offscreen\": false,\n"; - result += " \"speaker\": \"none\",\n"; - result += " \"start\": " + float_to_string(sub.start_frame) + ",\n"; if (dump_text) { - result += " \"text\": \"" + msg.text + "\"\n"; + result += " \"text\": \"" + msg.text + "\",\n"; } else { - result += " \"text\": \"\"\n"; + // result += " \"text\": \"\",\n"; } + result += " \"speaker\": \"none\"\n"; result += " },\n"; has_subs = true; } diff --git a/decompiler/data/streamed_audio.cpp b/decompiler/data/streamed_audio.cpp index 81294cb560..f285164a2b 100644 --- a/decompiler/data/streamed_audio.cpp +++ b/decompiler/data/streamed_audio.cpp @@ -164,13 +164,16 @@ AudioDir read_audio_dir(const decompiler::Config& config, const fs::path& path) u64 data; struct { u64 name : 42; - bool stereo : 1; - bool international : 1; - u8 param : 4; + u64 stereo : 1; + u64 international : 1; + u64 param : 4; u64 offset : 16; }; }; }; + + static_assert(sizeof(DirEntryJak3) == sizeof(u64)); + dir = reader.read(); ASSERT(dir.id[0] == 0x41574756); ASSERT(dir.id[1] == 0x52494444); diff --git a/decompiler/extractor/extractor_util.h b/decompiler/extractor/extractor_util.h index 87cbdc83c2..9f96edd437 100644 --- a/decompiler/extractor/extractor_util.h +++ b/decompiler/extractor/extractor_util.h @@ -12,6 +12,7 @@ enum class ExtractorErrorCode { SUCCESS = 0, INVALID_CLI_INPUT = 3990, + INVALID_CLI_INPUT_MISSING_FOLDER = 3991, VALIDATION_CANT_LOCATE_ELF = 4000, VALIDATION_SERIAL_MISSING_FROM_DB = 4001, VALIDATION_ELF_MISSING_FROM_DB = 4002, diff --git a/decompiler/extractor/main.cpp b/decompiler/extractor/main.cpp index 1635e16caa..47d585d601 100644 --- a/decompiler/extractor/main.cpp +++ b/decompiler/extractor/main.cpp @@ -226,7 +226,7 @@ int main(int argc, char** argv) { if (!project_path_override.empty()) { if (!fs::exists(project_path_override)) { lg::error("Error: project path override '{}' does not exist", project_path_override.string()); - return static_cast(ExtractorErrorCode::INVALID_CLI_INPUT); + return static_cast(ExtractorErrorCode::INVALID_CLI_INPUT_MISSING_FOLDER); } auto ok = file_util::setup_project_path(project_path_override); if (!ok) { @@ -256,7 +256,7 @@ int main(int argc, char** argv) { // - INPUT VALIDATION if (!fs::exists(input_file_path)) { lg::error("Error: input game file path '{}' does not exist", input_file_path.string()); - return static_cast(ExtractorErrorCode::INVALID_CLI_INPUT); + return static_cast(ExtractorErrorCode::INVALID_CLI_INPUT_MISSING_FOLDER); } if (data_subfolders.count(game_name) == 0) { lg::error("Error: input game name '{}' is not valid", game_name); @@ -326,7 +326,7 @@ int main(int argc, char** argv) { } else if (fs::is_directory(input_file_path)) { if (!flag_folder) { // if we didn't request a folder explicitly, but we got one, assume something went wrong. - lg::error("got a folder, but didn't get folder flag"); + lg::error("got a folder, but didn't provide the folder flag"); return static_cast(ExtractorErrorCode::INVALID_CLI_INPUT); } iso_data_path = input_file_path; diff --git a/decompiler/level_extractor/BspHeader.cpp b/decompiler/level_extractor/BspHeader.cpp index b502af8f97..f69c4eef99 100644 --- a/decompiler/level_extractor/BspHeader.cpp +++ b/decompiler/level_extractor/BspHeader.cpp @@ -1017,7 +1017,8 @@ void PrototypeBucketTie::read_from_file(TypedRef ref, for (int i = 0; i < 4; i++) { u32 start = index_start[i]; u32 end = start + frag_count[i]; - ASSERT(num_color_qwcs <= end); + // precd tie has a bug where geo 3's + // ASSERT(num_color_qwcs <= end); num_color_qwcs = std::max(end, num_color_qwcs); } @@ -1987,6 +1988,13 @@ void HFragment::read_from_file(TypedRef ref, const decompiler::DecompilerTypeSys size = read_plain_data_field(ref, "size", dts); } +void AdgifShaderArray::read_from_file(TypedRef ref, const decompiler::DecompilerTypeSystem& dts) { + auto length = read_plain_data_field(ref, "length", dts); + adgifs.resize(length); + memcpy_plain_data((u8*)adgifs.data(), get_field_ref(ref, "data", dts), + sizeof(AdGifData) * length); +} + void BspHeader::read_from_file(const decompiler::LinkedObjectFile& file, const decompiler::DecompilerTypeSystem& dts, GameVersion version, @@ -2001,6 +2009,19 @@ void BspHeader::read_from_file(const decompiler::LinkedObjectFile& file, bsphere.read_from_file(get_field_ref(ref, "bsphere", dts)); name = read_symbol_field(ref, "name", dts); + if (version == GameVersion::Jak1) { + adgifs.read_from_file(get_and_check_ref_to_basic(ref, "adgifs", "adgif-shader-array", dts), + dts); + } + + texture_page_count = read_plain_data_field(ref, "texture-page-count", dts); + if (texture_page_count > 0) { + auto tex_id_ptr = deref_label(get_field_ref(ref, "texture-ids", dts)); + for (int i = 0; i < texture_page_count; i++) { + texture_ids.push_back(deref_u32(tex_id_ptr, i)); + } + } + texture_remap_table.clear(); s32 tex_remap_len = read_plain_data_field(ref, "texture-remap-table-len", dts); if (tex_remap_len > 0) { diff --git a/decompiler/level_extractor/BspHeader.h b/decompiler/level_extractor/BspHeader.h index 128912a826..e0b47969ff 100644 --- a/decompiler/level_extractor/BspHeader.h +++ b/decompiler/level_extractor/BspHeader.h @@ -840,6 +840,12 @@ struct DrawableTreeArray { std::vector> trees; }; +struct AdgifShaderArray { + std::vector adgifs; + + void read_from_file(TypedRef ref, const decompiler::DecompilerTypeSystem& dts); +}; + // The "file info" struct FileInfo { std::string file_type; @@ -884,7 +890,9 @@ struct BspHeader { u16 texture_flags[kNumTextureFlags]; // jak 2 only // // (texture-ids (pointer texture-id) :offset-assert 60) + std::vector texture_ids; // (texture-page-count int32 :offset-assert 64) + s32 texture_page_count; // // (unk-zero-0 basic :offset-assert 68) // @@ -907,6 +915,7 @@ struct BspHeader { // (unk-data-4 float :offset-assert 160) // (unk-data-5 float :offset-assert 164) // (adgifs adgif-shader-array :offset-assert 168) + AdgifShaderArray adgifs; // (actor-birth-order (pointer uint32) :offset-assert 172) // (split-box-indices (pointer uint16) :offset-assert 176) // (unk-data-8 uint32 55 :offset-assert 180) diff --git a/decompiler/level_extractor/extract_collide_frags.h b/decompiler/level_extractor/extract_collide_frags.h index 97c56498a0..c926f40b7a 100644 --- a/decompiler/level_extractor/extract_collide_frags.h +++ b/decompiler/level_extractor/extract_collide_frags.h @@ -19,4 +19,5 @@ void extract_collide_frags(const level_tools::CollideHash& chash, const decompiler::DecompilerTypeSystem& dts, tfrag3::Level& out); +void set_vertices_for_tri(tfrag3::CollisionMesh::Vertex* out, const math::Vector4f* in); } // namespace decompiler diff --git a/decompiler/level_extractor/extract_level.cpp b/decompiler/level_extractor/extract_level.cpp index e77ef5d624..9f502a7c6a 100644 --- a/decompiler/level_extractor/extract_level.cpp +++ b/decompiler/level_extractor/extract_level.cpp @@ -257,7 +257,8 @@ void extract_common(const ObjectFileDB& db, const TextureDB& tex_db, const std::string& dgo_name, const fs::path& output_folder, - const Config& config) { + const Config& config, + const std::vector& all_dgo_names) { if (db.obj_files_by_dgo.count(dgo_name) == 0) { lg::warn("Skipping common extract for {} because the DGO was not part of the input", dgo_name); return; @@ -278,21 +279,55 @@ void extract_common(const ObjectFileDB& db, add_all_textures_from_level(tfrag_level, "ARTSPOOL", tex_db); extract_art_groups_from_level(db, tex_db, {}, "ARTSPOOL", tfrag_level, art_group_data); + // copy in any art groups that were requested to be common + if (config.common_art_groups.size() > 0) { + std::unordered_set art_groups_made_common; + for (const std::string& lvl_dgo_name : all_dgo_names) { + // exit early if we've found everything + if (config.common_art_groups.size() == art_groups_made_common.size()) { + lg::info("Found all requested art groups to be made common!"); + break; + } + + lg::info("Looking for common art groups in {}", lvl_dgo_name); + auto tex_remap = extract_tex_remap(db, lvl_dgo_name); + if (db.obj_files_by_dgo.count(lvl_dgo_name)) { + const auto& files = db.obj_files_by_dgo.at(lvl_dgo_name); + for (const auto& file : files) { + if (!art_groups_made_common.contains(file.name) && config.common_art_groups.contains(file.name)) { + lg::info("Art group {} was requested to be made common, we found it in {}!", file.name, + lvl_dgo_name); + const auto& ag_file = db.lookup_record(file); + extract_merc(ag_file, tex_db, db.dts, tex_remap, tfrag_level, false, db.version()); + extract_joint_group(ag_file, db.dts, db.version(), art_group_data); + // track found art groups so we don't borther re-processing in a later level + art_groups_made_common.insert(file.name); + } + } + } + } + } + std::set textures_we_have; + std::set textures_we_have_id; // put _all_ index textures in common. for (const auto& [id, tex] : tex_db.index_textures_by_combo_id) { tfrag_level.index_textures.push_back(tex); } + // remember which textures we already added. + // textures with the same name or the same ID always have the same data. for (const auto& t : tfrag_level.textures) { textures_we_have.insert(t.debug_name); + textures_we_have_id.insert(t.combo_id); } + // for common textures, add if the ID isn't there - common textures are looked up by ID. for (const auto& [id, normal_texture] : tex_db.textures) { - if (config.common_tpages.count(normal_texture.page) && - !textures_we_have.count(normal_texture.name)) { + if (config.common_tpages.count(normal_texture.page) && !textures_we_have_id.count(id)) { textures_we_have.insert(normal_texture.name); + textures_we_have_id.insert(id); tfrag_level.textures.push_back( make_texture(id, normal_texture, tex_db.tpage_names.at(normal_texture.page), true)); } @@ -378,7 +413,7 @@ void extract_all_levels(const ObjectFileDB& db, const std::string& common_name, const Config& config, const fs::path& output_path) { - extract_common(db, tex_db, common_name, output_path, config); + extract_common(db, tex_db, common_name, output_path, config, dgo_names); auto entities_dir = file_util::get_jak_project_dir() / "decompiler_out" / game_version_names[config.game_version] / "entities"; file_util::create_dir_if_needed(entities_dir); diff --git a/decompiler/level_extractor/extract_level.h b/decompiler/level_extractor/extract_level.h index 48800629a6..ac4712f940 100644 --- a/decompiler/level_extractor/extract_level.h +++ b/decompiler/level_extractor/extract_level.h @@ -26,4 +26,7 @@ tfrag3::Texture make_texture(u32 id, bool pool_load); std::vector extract_tex_remap(const ObjectFileDB& db, const std::string& dgo_name); +std::optional get_bsp_file(const std::vector& records, + const std::string& dgo_name); +bool is_valid_bsp(const LinkedObjectFile& file); } // namespace decompiler diff --git a/decompiler/level_extractor/extract_merc.cpp b/decompiler/level_extractor/extract_merc.cpp index 2a97ef1782..f5f5e1fa5d 100644 --- a/decompiler/level_extractor/extract_merc.cpp +++ b/decompiler/level_extractor/extract_merc.cpp @@ -853,12 +853,19 @@ ConvertedMercEffect convert_merc_effect(const MercEffect& input_effect, u32 tidx = (env >> 8) & 0b1111'1111'1111; tex_combo = (((u32)tpage) << 16) | tidx; } break; - case GameVersion::Jak2: - case GameVersion::Jak3: { + case GameVersion::Jak2: { u32 tpage = 0x1f; u32 tidx = 2; tex_combo = (((u32)tpage) << 16) | tidx; } break; + case GameVersion::Jak3: { + // (define *generic-envmap-texture* (get-texture pal-environment-front environment-generic)) + // (defconstant environment-generic 2) tpage + // (def-tex pal-environment-front environment-generic 1) texture + u32 tpage = 2; + u32 tidx = 1; + tex_combo = (((u32)tpage) << 16) | tidx; + } break; default: ASSERT_NOT_REACHED(); } diff --git a/decompiler/level_extractor/extract_tfrag.cpp b/decompiler/level_extractor/extract_tfrag.cpp index 0949db9fcc..4002bf57a3 100644 --- a/decompiler/level_extractor/extract_tfrag.cpp +++ b/decompiler/level_extractor/extract_tfrag.cpp @@ -2032,6 +2032,20 @@ s32 find_or_add_texture_to_level(u32 combo_tex_id, if (ok_to_miss) { // we're missing a texture, just use the first one. tex_it = tdb.textures.begin(); + // some tfrags in jak 3 are missing textures, so we use some suitable + // replacements instead of the default eye texture + static std::map per_level_tex_hacks = { + {"wasintro", "des-rock-01"}, + {"intpfall", "common-black"}, + {"powergd", "common-black"}, + }; + auto it = std::find_if(tdb.textures.begin(), tdb.textures.end(), + [&](const std::pair val) { + return val.second.name == per_level_tex_hacks[level_name]; + }); + if (it != tdb.textures.end()) { + tex_it = it; + } } else { ASSERT_MSG( false, diff --git a/decompiler/level_extractor/extract_tie.cpp b/decompiler/level_extractor/extract_tie.cpp index 1d0dc08b5b..53ce30a09a 100644 --- a/decompiler/level_extractor/extract_tie.cpp +++ b/decompiler/level_extractor/extract_tie.cpp @@ -2339,7 +2339,7 @@ TieCategoryInfo get_jak1_tie_category(u32 flags) { return result; } -u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb) { +s32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb) { if (combo_tex == 0) { // untextured combo_tex = (((u32)TextureDB::kPlaceholderWhiteTexturePage) << 16) | @@ -2348,7 +2348,7 @@ u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb) // try looking it up in the existing textures that we have in the C++ renderer data. // (this is shared with tfrag) - u32 idx_in_lev_data = UINT32_MAX; + s32 idx_in_lev_data = INT32_MAX; for (u32 i = 0; i < lev.textures.size(); i++) { if (lev.textures[i].combo_id == combo_tex) { idx_in_lev_data = i; @@ -2356,7 +2356,7 @@ u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb) } } - if (idx_in_lev_data == UINT32_MAX) { + if (idx_in_lev_data == INT32_MAX) { // didn't find it, have to add a new one texture. auto tex_it = tdb.textures.find(combo_tex); if (tex_it == tdb.textures.end()) { @@ -2378,14 +2378,20 @@ u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb) new_tex.debug_tpage_name = tdb.tpage_names.at(tex_it->second.page); new_tex.data = tex_it->second.rgba_bytes; } + const auto& level_tex = lev.textures.at(idx_in_lev_data); + const auto& it = tdb.animated_tex_output_to_anim_slot.find(level_tex.debug_name); + if (it != tdb.animated_tex_output_to_anim_slot.end()) { + // lg::warn("TIE animated texture: {}", level_tex.debug_name); + return -int(it->second) - 1; + } return idx_in_lev_data; } void handle_wind_draw_for_strip( tfrag3::TieTree& tree, - std::unordered_map>& wind_draws_by_tex, + std::unordered_map>& wind_draws_by_tex, const std::vector>>& packed_vert_indices, - u32 idx_in_lev_data, + s32 idx_in_lev_data, DrawMode mode, const TieStrip& strip, const TieInstanceInfo& inst, @@ -2452,7 +2458,7 @@ void handle_wind_draw_for_strip( } void handle_draw_for_strip(tfrag3::TieTree& tree, - std::unordered_map>& static_draws_by_tex, + std::unordered_map>& static_draws_by_tex, std::vector& category_draws, const std::vector>>& packed_vert_indices, DrawMode mode, @@ -2542,8 +2548,8 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree, GameVersion version) { // our current approach for static draws is just to flatten to giant mesh, except for wind stuff. // this map sorts these two types of draws by texture. - std::unordered_map> static_draws_by_tex; - std::unordered_map> wind_draws_by_tex; + std::unordered_map> static_draws_by_tex; + std::unordered_map> wind_draws_by_tex; std::array, tfrag3::kNumTieCategories> draws_by_category; @@ -2632,7 +2638,7 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree, for (size_t strip_idx = 0; strip_idx < frag.strips.size(); strip_idx++) { auto& strip = frag.strips[strip_idx]; - u32 idx_in_lev_data = get_or_add_texture(strip.adgif.combo_tex, lev, tdb); + s32 idx_in_lev_data = get_or_add_texture(strip.adgif.combo_tex, lev, tdb); // determine the draw mode DrawMode mode = process_draw_mode(strip.adgif, frag.prog_info.misc_x == 0, frag.has_magic_tex0_bit, version, info.category); @@ -2649,7 +2655,7 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree, draws_by_category.at((int)info.category), packed_vert_indices, mode, idx_in_lev_data, strip, inst, ifrag, proto_idx, frag_idx, strip_idx, matrix_idx); - u32 envmap_tex_idx = + s32 envmap_tex_idx = get_or_add_texture(proto.envmap_adgif.value().combo_tex, lev, tdb); // second pass envmap draw mode, in envmap bucket, envmap-specific draw list @@ -2747,6 +2753,10 @@ void extract_tie(const level_tools::DrawableTreeInstanceTie* tree, bool dump_level, GameVersion version) { for (int geo = 0; geo < GEOM_MAX; ++geo) { + // as far as I can tell, this one has bad colors + if (debug_name == "PRECD.DGO-2-tie" && geo == 3) { + continue; + } tfrag3::TieTree this_tree; // sanity check the vis tree (not a perfect check, but this is used in game and should be right) diff --git a/decompiler/level_extractor/merc_replacement.cpp b/decompiler/level_extractor/merc_replacement.cpp index 1cc4205faa..b8f3ccb5d4 100644 --- a/decompiler/level_extractor/merc_replacement.cpp +++ b/decompiler/level_extractor/merc_replacement.cpp @@ -3,18 +3,25 @@ using namespace gltf_util; namespace decompiler { + +bool material_has_envmap(const tinygltf::Material& mat) { + return mat.extensions.contains("KHR_materials_specular"); +} + void extract(const std::string& name, MercExtractData& out, const tinygltf::Model& model, const std::vector& all_nodes, u32 index_offset, u32 vertex_offset, - u32 tex_offset) { + u32 tex_offset, + bool& has_custom_weights) { ASSERT(out.new_vertices.empty()); std::map draw_by_material; int mesh_count = 0; int prim_count = 0; + bool has_envmaps = false; for (const auto& n : all_nodes) { const auto& node = model.nodes[n.node_idx]; @@ -24,6 +31,8 @@ void extract(const std::string& name, if (node.mesh >= 0) { const auto& mesh = model.meshes[node.mesh]; mesh_count++; + has_custom_weights = node.extras.Has("enable_custom_weights") && + node.extras.Get("enable_custom_weights").Get(); for (const auto& prim : mesh.primitives) { prim_count++; // extract index buffer @@ -39,6 +48,21 @@ void extract(const std::string& name, out.normals.insert(out.normals.end(), verts.normals.begin(), verts.normals.end()); ASSERT(out.new_colors.size() == out.new_vertices.size()); + if (prim.attributes.count("JOINTS_0") && prim.attributes.count("WEIGHTS_0")) { + auto joints_and_weights = gltf_util::extract_and_flatten_joints_and_weights(model, prim); + ASSERT(joints_and_weights.size() == verts.vtx.size()); + out.joints_and_weights.insert(out.joints_and_weights.end(), joints_and_weights.begin(), + joints_and_weights.end()); + } else { + // add fake data for vertices without this data + gltf_util::JointsAndWeights dummy; + dummy.joints[0] = 3; + dummy.weights[0] = 1.f; + for (size_t i = 0; i < out.new_vertices.size(); i++) { + out.joints_and_weights.push_back(dummy); + } + } + // TODO: just putting it all in one material auto& draw = draw_by_material[prim.material]; draw.mode = gltf_util::make_default_draw_mode(); // todo rm @@ -54,41 +78,108 @@ void extract(const std::string& name, } tfrag3::MercEffect e; + tfrag3::MercEffect envmap_eff; out.new_model.name = name; - out.new_model.max_bones = 120; + out.new_model.max_bones = 100; // idk out.new_model.max_draws = 200; - for (const auto& [mat_idx, d_] : draw_by_material) { - e.all_draws.push_back(d_); - auto& draw = e.all_draws.back(); - draw.mode = make_default_draw_mode(); + + auto process_normal_draw = [&](tfrag3::MercEffect& eff, int mat_idx, const tfrag3::MercDraw& d_) { + const auto& mat = model.materials[mat_idx]; + eff.all_draws.push_back(d_); + auto& draw = eff.all_draws.back(); + draw.mode = gltf_util::make_default_draw_mode(); if (mat_idx == -1) { lg::warn("Draw had a material index of -1, using default texture."); draw.tree_tex_id = 0; - continue; + return; } - const auto& mat = model.materials[mat_idx]; int tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index; if (tex_idx == -1) { lg::warn("Material {} has no texture, using default texture.", mat.name); draw.tree_tex_id = 0; - continue; + return; } const auto& tex = model.textures[tex_idx]; ASSERT(tex.sampler >= 0); ASSERT(tex.source >= 0); - draw.mode = draw_mode_from_sampler(model.samplers.at(tex.sampler)); + gltf_util::setup_draw_mode_from_sampler(model.samplers.at(tex.sampler), &draw.mode); + gltf_util::setup_alpha_from_material(mat, &draw.mode); const auto& img = model.images[tex.source]; draw.tree_tex_id = tex_offset + texture_pool_add_texture(&out.tex_pool, img); + }; + + auto process_envmap_draw = [&](tfrag3::MercEffect& eff, int mat_idx, const tfrag3::MercDraw& d_) { + const auto& mat = model.materials[mat_idx]; + eff.all_draws.push_back(d_); + auto& draw = eff.all_draws.back(); + draw.mode = gltf_util::make_default_draw_mode(); + + if (mat_idx == -1) { + lg::warn("Envmap draw had a material index of -1, using default texture."); + draw.tree_tex_id = texture_pool_debug_checker(&out.tex_pool); + return; + } + int base_tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index; + if (base_tex_idx == -1) { + lg::warn("Envmap material {} has no texture, using default texture.", mat.name); + draw.tree_tex_id = texture_pool_debug_checker(&out.tex_pool); + return; + } + + int roughness_tex_idx = mat.pbrMetallicRoughness.metallicRoughnessTexture.index; + ASSERT(roughness_tex_idx >= 0); + const auto& base_tex = model.textures[base_tex_idx]; + ASSERT(base_tex.sampler >= 0); + ASSERT(base_tex.source >= 0); + gltf_util::setup_draw_mode_from_sampler(model.samplers.at(base_tex.sampler), &draw.mode); + gltf_util::setup_alpha_from_material(mat, &draw.mode); + const auto& roughness_tex = model.textures.at(roughness_tex_idx); + ASSERT(roughness_tex.sampler >= 0); + ASSERT(roughness_tex.source >= 0); + + draw.tree_tex_id = + tex_offset + gltf_util::texture_pool_add_envmap_control_texture( + &out.tex_pool, model, base_tex.source, roughness_tex.source, + !draw.mode.get_clamp_s_enable(), !draw.mode.get_clamp_t_enable()); + + // now, setup envmap draw: + auto envmap_settings = gltf_util::envmap_settings_from_gltf(mat); + const auto& envmap_tex = model.textures[envmap_settings.texture_idx]; + ASSERT(envmap_tex.sampler >= 0); + ASSERT(envmap_tex.source >= 0); + auto env_mode = gltf_util::make_default_draw_mode(); + gltf_util::setup_draw_mode_from_sampler(model.samplers.at(envmap_tex.sampler), &env_mode); + eff.envmap_texture = tex_offset + gltf_util::texture_pool_add_texture( + &out.tex_pool, model.images[envmap_tex.source]); + env_mode.set_alpha_blend(DrawMode::AlphaBlend::SRC_0_DST_DST); + env_mode.enable_ab(); + eff.envmap_mode = env_mode; + }; + + for (const auto& [mat_idx, d_] : draw_by_material) { + const auto& mat = model.materials[mat_idx]; + if (!material_has_envmap(mat)) { + process_normal_draw(e, mat_idx, d_); + } else { + has_envmaps = true; + envmap_eff.has_envmap = true; + process_envmap_draw(envmap_eff, mat_idx, d_); + } + } + + lg::info("total of {} unique materials ({} normal, {} envmap)", + e.all_draws.size() + envmap_eff.all_draws.size(), e.all_draws.size(), + envmap_eff.all_draws.size()); + // in case a model only has envmap draws, we don't push the normal merc effect + if (!e.all_draws.empty()) { + out.new_model.effects.push_back(e); + } + if (has_envmaps) { + out.new_model.effects.push_back(envmap_eff); } - lg::info("total of {} unique materials", e.all_draws.size()); - e.has_mod_draw = false; - out.new_model.effects.push_back(e); - out.new_model.effects.push_back(e); - out.new_model.effects.push_back(e); - out.new_model.effects.push_back(e); lg::info("Merged {} meshes and {} prims into {} vertices", mesh_count, prim_count, out.new_vertices.size()); @@ -118,7 +209,8 @@ const tfrag3::MercVertex& find_closest(const std::vector& ol void merc_convert_replacement(MercSwapData& out, const MercExtractData& in, - const std::vector& old_verts) { + const std::vector& old_verts, + bool use_custom_weights) { out.new_model = in.new_model; out.new_indices = in.new_indices; out.new_textures = in.tex_pool.textures_by_idx; @@ -126,26 +218,36 @@ void merc_convert_replacement(MercSwapData& out, // convert vertices for (size_t i = 0; i < in.new_vertices.size(); i++) { const auto& y = in.new_vertices[i]; + const auto& copy_from = find_closest(old_verts, y.x, y.y, y.z); auto& x = out.new_vertices.emplace_back(); x.pos[0] = y.x; x.pos[1] = y.y; x.pos[2] = y.z; - x.normal[0] = copy_from.normal[0]; - x.normal[1] = copy_from.normal[1]; - x.normal[2] = copy_from.normal[2]; - x.weights[0] = copy_from.weights[0]; - x.weights[1] = copy_from.weights[1]; - x.weights[2] = copy_from.weights[2]; + x.normal[0] = in.normals.at(i).x(); + x.normal[1] = in.normals.at(i).y(); + x.normal[2] = in.normals.at(i).z(); + if (use_custom_weights) { + x.weights[0] = in.joints_and_weights.at(i).weights[0]; + x.weights[1] = in.joints_and_weights.at(i).weights[1]; + x.weights[2] = in.joints_and_weights.at(i).weights[2]; + x.mats[0] = in.joints_and_weights.at(i).joints[0]; + x.mats[1] = in.joints_and_weights.at(i).joints[1]; + x.mats[2] = in.joints_and_weights.at(i).joints[2]; + } else { + x.weights[0] = copy_from.weights[0]; + x.weights[1] = copy_from.weights[1]; + x.weights[2] = copy_from.weights[2]; + x.mats[0] = copy_from.mats[0]; + x.mats[1] = copy_from.mats[1]; + x.mats[2] = copy_from.mats[2]; + } x.st[0] = y.s; x.st[1] = y.t; x.rgba[0] = in.new_colors[i][0]; x.rgba[1] = in.new_colors[i][1]; x.rgba[2] = in.new_colors[i][2]; x.rgba[3] = in.new_colors[i][3]; - x.mats[0] = copy_from.mats[0]; - x.mats[1] = copy_from.mats[1]; - x.mats[2] = copy_from.mats[2]; } } @@ -164,18 +266,18 @@ void merc_convert_custom(MercSwapData& out, const MercExtractData& in) { x.normal[0] = in.normals.at(i).x(); x.normal[1] = in.normals.at(i).y(); x.normal[2] = in.normals.at(i).z(); - x.weights[0] = 1.0f; - x.weights[1] = 0.0f; - x.weights[2] = 0.0f; + x.weights[0] = in.joints_and_weights.at(i).weights[0]; + x.weights[1] = in.joints_and_weights.at(i).weights[1]; + x.weights[2] = in.joints_and_weights.at(i).weights[2]; x.st[0] = y.s; x.st[1] = y.t; x.rgba[0] = in.new_colors[i][0]; x.rgba[1] = in.new_colors[i][1]; x.rgba[2] = in.new_colors[i][2]; x.rgba[3] = in.new_colors[i][3]; - x.mats[0] = 3; - x.mats[1] = 0; - x.mats[2] = 0; + x.mats[0] = in.joints_and_weights.at(i).joints[0]; + x.mats[1] = in.joints_and_weights.at(i).joints[1]; + x.mats[2] = in.joints_and_weights.at(i).joints[2]; } } @@ -198,12 +300,13 @@ MercSwapData load_replacement_merc_model(const std::string& name, auto all_nodes = flatten_nodes_from_all_scenes(model); MercExtractData extract_data; + auto has_custom_weights = false; extract(name, extract_data, model, all_nodes, current_idx_count, current_vtx_count, - current_tex_count); + current_tex_count, has_custom_weights); if (custom_mdl) { merc_convert_custom(result, extract_data); } else { - merc_convert_replacement(result, extract_data, old_verts); + merc_convert_replacement(result, extract_data, old_verts, has_custom_weights); } return result; diff --git a/decompiler/level_extractor/merc_replacement.h b/decompiler/level_extractor/merc_replacement.h index 13b9e10ec9..c6f33483a3 100644 --- a/decompiler/level_extractor/merc_replacement.h +++ b/decompiler/level_extractor/merc_replacement.h @@ -10,7 +10,7 @@ struct MercExtractData { std::vector new_vertices; std::vector> new_colors; std::vector normals; - + std::vector joints_and_weights; tfrag3::MercModel new_model; }; diff --git a/docker/Ubuntu/Dockerfile b/docker/Ubuntu/Dockerfile index 4d88164918..24cde146b6 100644 --- a/docker/Ubuntu/Dockerfile +++ b/docker/Ubuntu/Dockerfile @@ -2,7 +2,7 @@ FROM ubuntu:20.04 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update -RUN apt-get install -y gcc make cmake build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libpulse-dev libxi-dev python lld clang curl +RUN apt-get install -y gcc make cmake build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libpulse-dev libxi-dev python lld clang curl libssl-dev libstdc++-10-dev RUN sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin @@ -21,4 +21,4 @@ WORKDIR /home/$user/jak-project/build RUN cmake -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ .. WORKDIR /home/$user/jak-project -RUN cmake -B build && cmake --build build -j 8 +RUN cmake -B build && cmake --build build -j 8 diff --git a/game/assets/jak1/app256.png b/game/assets/jak1/app256.png index badbbbaaa5..34a9b88e04 100644 Binary files a/game/assets/jak1/app256.png and b/game/assets/jak1/app256.png differ diff --git a/game/assets/jak1/app64.png b/game/assets/jak1/app64.png index fce26fb097..897e82ad05 100644 Binary files a/game/assets/jak1/app64.png and b/game/assets/jak1/app64.png differ diff --git a/game/assets/jak1/subtitle/subtitle_lines_fi-FI.json b/game/assets/jak1/subtitle/subtitle_lines_fi-FI.json index a0441d0724..595221dbb2 100644 --- a/game/assets/jak1/subtitle/subtitle_lines_fi-FI.json +++ b/game/assets/jak1/subtitle/subtitle_lines_fi-FI.json @@ -815,6 +815,7 @@ "JA NIITÄ VARMASTI LÖYTYY LISÄÄKIN LUONNOSTA ODOTTELEMASSA,", "ETTÄ JOKU ROHKEA SEIKKAILIJA LÖYTÄÄ NE.", "NO AINAKIN SE ROHKEA SEIKKAILIJA LÖYTYY OMASTA TAKAA.", + "NO AINAKIN SE ROHKEA SEIKKAILIJA LÖYTYY OMASTA TAKAA.", "ROHKEA SEIKKAILIJA?", "TE KAKSI ETTE EDES LÖYTÄISI ULOS KYLÄSTÄ ILMAN HARJOITTELUA!", "ENNEN KUIN TEETTE YHTIKÄS MITÄÄN, TEIDÄN ON PARASTA KULKEA TELEPORTIN LÄPI", @@ -1919,7 +1920,8 @@ "ANTAISIN TEILLE ONNITTELUNI,", "MUTTA TEILLÄ ON NIIN PALJON TEHTÄVÄÄ, ETTEN TUHLAA ENEMPÄÄ AIKAANNE.", "MUUTEN, JOS ASIANNE EIVÄT LUTVIUDU,", - "DAXTERILLE ON AINA VAPAANA TYÖ HOITAA KYLÄMME ROTTAONGELMAA.", + "MUUTEN, JOS ASIANNE EIVÄT LUTVIUDU,", + "HE HA HA HA HA HA HA HA HA HAH...", "HE HA HA HA HA HA HA HA HA HAH..." ], "sagevb02": [ diff --git a/game/assets/jak1/subtitle/subtitle_lines_nl-NL.json b/game/assets/jak1/subtitle/subtitle_lines_nl-NL.json index 65f7314b38..4b1969265c 100644 --- a/game/assets/jak1/subtitle/subtitle_lines_nl-NL.json +++ b/game/assets/jak1/subtitle/subtitle_lines_nl-NL.json @@ -6,7 +6,7 @@ "TOT HET 500 GRADEN BEREIKT, DUS PROBEER HAAR KOEL TE HOUDEN.", "VLIEGEN OVER OPEN LAVA ZAL JE ZEKER SNEL OPWARMEN.", "ALS HET 500 GRADEN WORDT, IS HET VOORBIJ.", - "OVER?! ALS IN BRANDEND GESMOLTEN METAAL OVER?!", + "VOORBIJ?! ALS IN BRANDEND GESMOLTEN METAAL VOORBIJ?!", "DE VUURVALLEI WORDT BEHOORLIJK HEET, DUS KIJK UIT VOOR SCHANSEN", "OM JE VAN DE HETE GROND TE HOUDEN.", "IK HEB OOK EEN AANTAL BLAUWE KOELBALLONNEN UITGEBRACHT DIE JE KUNT GEBRUIKEN OM", @@ -1164,7 +1164,7 @@ "OVER DAAR!" ], "BIL-TA04": [ - "AW, DANG." + "AW, PRUTS." ], "BIL-TA05": [ "RAT HEEFT EEN SNACK." @@ -1191,7 +1191,7 @@ "OVER DAAR." ], "BIL-TA4A": [ - "DANG!" + "VERDOMME!" ], "BIL-TA4B": [ "VERDOMME!" @@ -1748,7 +1748,7 @@ "(SNIKKEN)" ], "WAR-LO1B": [ - "(SOBS)" + "(JANKT)" ], "WAR-LO1C": [ "(BLAAST NEUS EN SPUTTERT)", diff --git a/game/assets/jak1/text/game_custom_text_ja-JP.json b/game/assets/jak1/text/game_custom_text_ja-JP.json index 6660ebb149..90401bef33 100644 --- a/game/assets/jak1/text/game_custom_text_ja-JP.json +++ b/game/assets/jak1/text/game_custom_text_ja-JP.json @@ -16,20 +16,20 @@ "1024": "ミュージック ゲイン", "1025": "アクター カリング", "1026": "バックグラウンド カリング", - "1027": "??マッピングを???に?行", + "1027": "かんきょうマッピングをきょうせいてきにじっこう", "1030": "DISCORDリッチプレゼンス", "1031": "スクリーンモード", "1032": "ウィンドウ", "1033": "ボーダレス", "1034": "フルスクリーン", - "1035": "?像?", + "1035": "かいぞうど", "1036": "~D X ~D", - "1037": "PS2 アスペクト?", - "1038": "PS2アスペクト?が??になると、4?3と16?9しかのアスペクト?が??できません.?行しますか?", - "1039": "アスペクト? (PS2)", - "1040": "??あり", - "1041": "??なし", - "1042": "テキスト??", + "1037": "PS2 アスペクト ひ", + "1038": "PS2アスペクトひがゆうこうになると、4X3と16X9しかのアスペクトひがせんたくできません.つづきますか?", + "1039": "アスペクト ひ (PS2)", + "1040": "じまくあり", + "1041": "じまくなし", + "1042": "テキストのげんご", "1043": "ディスプレイ", "1044": "ディスプレイ ~D", "1050": "MSAA", @@ -38,46 +38,46 @@ "1053": "4X", "1054": "8X", "1055": "16X", - "1060": "フレームレート (???)", + "1060": "フレームレート (じっけんてき)", "1061": "60", "1062": "100", "1063": "150", "1070": "LEVEL OF DETAIL (はいけい)", "1071": "LEVEL OF DETAIL (ぜんけい)", - "1072": "??", - "1073": "?", - "1074": "中", - "1075": "?", - "1076": "??", + "1072": "さいこう", + "1073": "たかい", + "1074": "ふつう", + "1075": "ひくい", + "1076": "さいてい", "1077": "PS2", - "1078": "??", - "1079": "ヒント??", + "1078": "じまく", + "1079": "ヒントじまく", "1080": "チート", "1081": "シークレット", - "1082": "?を??する", - "1083": "スタイルを??する", + "1082": "きょくをせんたくする", + "1083": "スタイルをせんたくする", "1084": "チューンドプリカーソルロボット", "1085": "スタッフロール", "1086": "?????", "1087": "ハイブリッドラーカー クロウ", "1088": "サカナとりゲームのテーマ", "1089": "チャレンジーのテーマ", - "1090": "??の青のエコ", - "1091": "??の赤のエコ", - "1092": "??の緑のエコ", - "1093": "??の黄のエコ", - "1094": "?わりのダクスター", - "1095": "??", - "1096": "???トラック", + "1090": "むげんの青のエコ", + "1091": "むげんの赤のエコ", + "1092": "むげんの緑のエコ", + "1093": "むげんの黄のエコ", + "1094": "かわりのダクスター", + "1095": "むてき", + "1096": "ぜんおんがくトラック", "1097": "リアルタイムオブデイ", "1098": "100%クリア", "1099": "ゲームクリア", "1100": "黄の賢者", "1101": "赤の賢者", "1102": "青の賢者", - "1103": "城のハブ", + "1103": "城エリア", "1104": "プリカーソルロボットの中?", - "1105": "プリカーソルロボットの?わり", + "1105": "プリカーソルロボットのおわり", "1106": "スタイル 1", "1107": "スタイル 2", "1110": "ENGLISH (UK)", @@ -94,20 +94,20 @@ "111b": "POLSKI", "111c": "LIETUVIŲ KALBA", "1500": "スピードラン モード", - "138": "????をぬいたり, さしたり, ??を?ったりは しないでください", - "161": "このアイコンが あらわれている?、????をぬいたり, さしたり, ??を?ったりは しないでください", + "138": "しゅうへんききをぬいたり, さしたり, でんげんを きったりは しないでください", + "161": "このアイコンが あらわれているあいだ、しゅうへんききをぬいたり, さしたり, でんげんを きったりは しないでください", "100c": "オートセーブ オフ", "100d": "オートセーブを?っても よろしいでしょうか?", - "100e": "オートセーブを??にする", - "100f": "その?", + "100e": "オートセーブをむこうにする", + "100f": "そのほか", "103a": "スクリーンに合わせる", - "103b": "????", + "103b": "すいちょくどうき", "103c": "4X3 (PS2)", "103d": "16X9 (PS2)", "103e": "~DX~D", - "103f": " で ??の?り?え", - "107a": "??の??", - "107b": "??にスピーカーを??", + "103f": " をおすとじまくをトグルする", + "107a": "じまくのことば", + "107b": "じまくではなしてをひょうじする", "107c": "いつも", "107d": "いつもしなく", "107e": "オフ スクリーン", @@ -117,14 +117,14 @@ "109c": "ビッグハンドジャック", "109d": "ビッグヘッドキャラクター", "109e": "テクスチャなしモード", - "109f": "??世界", + "109f": "ミラー・モード", "10a0": "ビッグヘッド ジャック", "10c0": "ミュージックプレイヤー", - "10c1": "プレイヤーを??", + "10c1": "シーンプレイヤー", "10c2": "スタッフロール", "10c3": "スクラップブック", "10d0": "デフォルト", - "10d1": "???", + "10d1": "みしよう", "10d2": "セイジィ", "10d3": "セイジィの家", "10d4": "小鳥のオバチャマ", @@ -133,11 +133,11 @@ "10d7": "メイヨル", "10d8": "ほりものし", "10d9": "たんけん家のブロオラ", - "10da": "DOCK", - "10db": "FORBIDDEN TEMPLE EXIT", + "10da": "ドック", + "10db": "キンダン寺の出口", "10dc": "ラーカーのマシン", "10dd": "TOP OF THE TOWER", - "10de": "BLUE VENT SWITCH", + "10de": "青エコのふきだしぐちスイッチ", "10df": "みしよう", "10e0": "SENTINELS", "10e1": "LURKER CANNON", @@ -145,19 +145,19 @@ "10e3": "みしよう1", "10e4": "LURKER BOAT", "10e5": "みしよう2", - "10e6": "ZOOMER", + "10e6": "ズーマー", "10e7": "フラフラ鳥", "10e8": "みしよう", - "10e9": "WARRIOR", - "10ea": "GEOLOGIST", - "10eb": "GAMBLER", + "10e9": "せんしヴォリア", + "10ea": "がくしゃロジィ", + "10eb": "ギャンブラーのタルパン", "10ec": "LEVITATOR MACHINE", "10ed": "みしよう1", "10ee": "LAUNCHER TRAPS", "10ef": "みしよう2", "10f0": "DEAD MAN'S GORGE", - "10f1": "MIDDLE OF THE PASS", - "10f2": "END OF THE PASS", + "10f1": "谷のちゅうかん", + "10f2": "谷のおわり", "10f3": "ヤミノ洞くつへ", "10f4": "ガイセツ山へ", "10f5": "宝石ほりたち", @@ -195,33 +195,33 @@ "151d": "LAVA TUBE IL", "151e": "GOL AND MAIA'S CITADEL IL", "151f": "NEW CATEGORY EXTENSION RUN", - "1520": "?しいゲーム+", - "1521": "ハブ 1 100%", - "1522": "ハブ 2 100%", - "1523": "ハブ 3 100%", + "1520": "つよくてニューゲーム", + "1521": "エリア 1 100%", + "1522": "エリア 2 100%", + "1523": "エリア 3 100%", "1524": "すべてのシーン", - "1600": "INPUT OPTIONS", + "1600": "にゅうりょくせってい", "1601": "コントローラをせんたくする", "1602": "ANALOG DEADZONE", "1603": "IGNORE IF WINDOW UNFOCUSED", "1604": "コントローラのLEDでたい力をひょうじする", "1605": "コントローラのLEDでエコをひょうじする", "1606": "TRACK CAMERA", - "1607": "HORIZONTAL SENSITIVITY", - "1608": "VERTICAL SENSITIVITY", + "1607": "よこかんど", + "1608": "たてかんど", "1609": "PLAYER MOVEMENT", "160a": "コントローラのバインド", "160b": "キーボードのバインド", "160c": "マウスのバインド", "160d": "コントローラオプション", - "160e": "ENABLE KEYBOARD", - "160f": "ENABLE MOUSE", + "160e": "キーボードゆうこう", + "160f": "マウスゆうこう", "1610": "マウスオプション", "1611": "REASSIGN BINDS", "1612": "CONTROLLER ~D", "1613": "AUTO HIDE CURSOR", "1614": "みけってい", - "1615": "?られていない", + "1615": "ふめい", "1616": "アスペクトひのほかのせんたくしはありません", "1617": "コントローラのLEDでズーマーのおんどをひょうじする" } diff --git a/game/assets/jak1/text/game_custom_text_sv-SE.json b/game/assets/jak1/text/game_custom_text_sv-SE.json index 7d0e647dbb..c92204387c 100644 --- a/game/assets/jak1/text/game_custom_text_sv-SE.json +++ b/game/assets/jak1/text/game_custom_text_sv-SE.json @@ -202,7 +202,7 @@ "1524": "ALLA SCENER", "1600": "INMATNINGSINSTÄLLNINGAR", "1601": "VÄLJ HANDKONTROLL", - "1602": "ANALOG DEADZONE", + "1602": "ANALOG NEUTRAL ZON", "1603": "IGNORERA OM FÖNSTRET INTE HAR FOKUS", "1604": "LED REFLEKTERAR HP", "1605": "LED REFLEKTERAR ECO", diff --git a/game/assets/jak2/app256.png b/game/assets/jak2/app256.png index 0302c89b5b..e8d6e115e9 100644 Binary files a/game/assets/jak2/app256.png and b/game/assets/jak2/app256.png differ diff --git a/game/assets/jak2/app64.png b/game/assets/jak2/app64.png index 444722b102..d99491631c 100644 Binary files a/game/assets/jak2/app64.png and b/game/assets/jak2/app64.png differ diff --git a/game/assets/jak2/subtitle/subtitle_lines_ca-ES.json b/game/assets/jak2/subtitle/subtitle_lines_ca-ES.json index dd4972fa6d..5572654b23 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_ca-ES.json +++ b/game/assets/jak2/subtitle/subtitle_lines_ca-ES.json @@ -713,7 +713,8 @@ ], "bb06int": [ "Jak, necessitem que treus un altre grup de Bomb Bots.", - "Aquestes armes mòbils continuen apareixent a la ciutat, les hem de treure el més aviat possible." + "These mobile weapons keep showing up in the city,", + "we gotta take them out as soon as possible." ], "bb06win": [ "Un altre munt de ferralla de bombes per al KG", @@ -724,8 +725,10 @@ "Has perdut un agent! No és gens bo, Jak! Missió fallida!" ], "bb07int": [ - "Esquinçat aquí, necessito que surtis i traslladis més dels nostres agents a nous llocs de la ciutat.", - "Els espies de KG estan vigilant tots els nostres moviments, així que vigileu els problemes. Bona sort." + "Torn here, I need you to go out and move more of our Agents", + "to new locations in the city.", + "KG spies are watching our every move,", + "so look out for trouble. Good luck." ], "bb07win": [ "Bona feina de llançadora! Estàs mantenint la gent viva allà fora." @@ -737,7 +740,8 @@ "bb08int": [ "Jak, alguns dels nostres agents s'han vist compromesos de nou.", "Trobeu-los i porteu-los a amagatalls especials de la ciutat.", - "Les patrulles de guàrdia estan en alerta màxima, així que serà difícil. Mantingueu el cap avall!" + "The guard patrols are on high alert,", + "so this is going to be a tough one. Keep your head down!" ], "bb08win": [ "Va ser una bona conducció, Jak.", @@ -4911,10 +4915,10 @@ "Activació de defenses de seguretat." ], "kg121": [ - "Si us plau, aviseu, descripció del tema." + "Please advise, suspect's description." ], "kg121a": [ - "Si us plau, aviseu, descripció del tema." + "Please advise, suspect's description." ], "kg122": [ "Tinc civismes a la vista." @@ -5689,11 +5693,11 @@ "lluitant per l'Underground." ], "kg233b": [ - "Estic preocupat perquè aquest nou noi lluita per l'Underground.", + "I'm worried about this new guy", "lluitant per l'Underground." ], "kg234": [ - "Sí, diuen que es pot convertir en una mena de... monstre." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ "Sí, diuen que es pot convertir en una mena de monstre." @@ -6939,7 +6943,7 @@ ], "prop049": [ "Estic decebut amb la manca d'aquesta ciutat", - "compromís i sacrifici. Treballar més dur! Menja menys!", + "commitment and sacrifice. Work harder! Eat less!", "Beu només quan et digui! Dormir és opcional.", "Estem en guerra amb una amenaça externa,", "no em feu declarar-vos la guerra també!" @@ -6947,13 +6951,14 @@ "prop050": [ "Salutacions, gent d'aquesta meravellosa utopia. La d'enguany", "la cursa del campionat començarà en breu. Tots els ciutadans", - "no estan sota arrest domiciliari estan convidats a baixar", - "l'Estadi i mira el teu fill preferit Erol", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", "mostrar una vegada més com la Guàrdia Krimzon és l'elit", - "guerrers d'aquesta ciutat. Porta tota la família! El primer", - "mil nens tindran una obligatòria", - "Paquet de contractació de Krimzon Guard i be", - "\"demanat\" unir-se a la Guàrdia de per vida, quina delícia!" + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ "Aquest és el teu baró, encara tinc el control!", @@ -6984,22 +6989,24 @@ "seria si els Metal Heads estiguessin al capdavant!" ], "prop054": [ - "Hem tingut alguns incidents amb els nostres treballadors de classe baixa", - "força últimament. Si el vostre Lurker està actuant, truqueu a Krimzon", - "Control d'animals. El teu Lurker està en un arbre? Encallat en un", - "reixa de clavegueram? Escuma a la boca? Anomenada", - "els oficials amics de la K.A.C. i tractaran", - "amb el teu esclau pelut. amb tot l'amor i cura", - "es mereix... després traieu-lo per a un reacondicionament.", - "Recordeu que els lurkers poden ser perillosos!" + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", + "Remember, Lurkers can be dangerous!" ], "prop055": [ "Si us plau, doneu generosament al fons ecològic Baron.", - "La teva donació s'utilitzarà per a una varietat", - "de necessitats humanitàries: bombes, pistoles, blindatges, genètica", - "investigació sobre alteracions, tot en nom de preservar-ho", - "meravellosa ciutat nostra. Donar sovint, donar lliurement...", - "o t'ho prendran!" + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", + "wonderful city of ours. Give often, give freely...", + "or it will be taken from you!" ], "prop056": [ "Pot estar tan sol a dalt i mirant cap avall", @@ -7549,15 +7556,17 @@ "Fes un petó al teu cul brillant adéu!" ], "sigt112": [ - "Nascut per matar un nadó!" + "Born to kill, baby!" ], "sigt113": [ "Dos al pit, un al cap." ], "spot004": [ - "Veniu a animar-me mentre destrueixo la competició una vegada més a la pista.", - "La final de curses d'enguany serà per morir-se, us garanteixo més emocions i més vessars.", - "Aquesta vegada vull sang!...Porteu els nens." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ "Hola nois! Aquesta és la Tess. Abans que en Krew marxés, el vaig veure amagar-se", @@ -7566,23 +7575,32 @@ "Potser vols venir a comprovar-ho." ], "tor001": [ - "L'operació va ser un èxit. Tots els membres de Underground estan segurs.", - "Torna a l'amagatall, tinc una nova missió per a tu mentre esperem que passi aquesta alerta." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "Això hauria de treure una mica de calor als carrers. Bona feina, jo mateix no ho hauria pogut fer millor." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "Això és tot, Jak, estàs aixecat! Intenta no activar cap alarma, els guàrdies de la guarnició seran durs.", - "Arriba al bloc de cel·les de la presó i troba els presoners. Un cop allà, encendrem la Warp Gate per dins per tornar-vos a sortir. Bona sort." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "D'acord, els meus codis d'accés antics haurien d'ajudar a Vin a apagar el segell magnètic de la porta de la fortalesa." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Jak, aquest és Torn, la ciutat està sota atac de Metal Head. Hi ha una gran força que es mou cap a la muralla de la ciutat des de l'oceà.", - "Necessitem gent que s'encarrega de les pistoles de la torre per aturar aquest assalt. Trobeu-me a la paret marítima del Port, afanyeu-vos!", - "Necessitem tots els homes que puguem aconseguir!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ "Jak, és un bloqueig de guàrdia, surt d'allà!" @@ -7807,8 +7825,8 @@ "Massa d'ells!! Jak!!! AHHHH!!!" ], "ys001": [ - "Excel·lent feina, nois! Torna a l'amagatall,", - "Tinc una altra tasca per a tu." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Bonic tiroteig, fill meu!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_da-DK.json b/game/assets/jak2/subtitle/subtitle_lines_da-DK.json index 812ea60c33..7730a8eec5 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_da-DK.json +++ b/game/assets/jak2/subtitle/subtitle_lines_da-DK.json @@ -713,7 +713,8 @@ ], "bb06int": [ "Jak, vi har brug for dig til at fjerne endnu en gruppe Bombe-botter.", - "Disse mobile våben bliver ved med at dukke op i byen, vi må fjerne dem hurtigst muligt." + "These mobile weapons keep showing up in the city,", + "we gotta take them out as soon as possible." ], "bb06win": [ "Endnu en bunke Bombe-bot skrot for KG'ernes", @@ -724,8 +725,10 @@ "Du mistede en agent! IKKE godt overhovedet, Jak! Missionen fejlet!" ], "bb07int": [ - "Torn her, Jeg skal bruge jer til at tage ud og flytte flere af vores Agenter til nye steder i byen.", - "KG-spioner holder øje med alle vores bevægelser, så hold øje efter problemer. Held og lykke." + "Torn here, I need you to go out and move more of our Agents", + "to new locations in the city.", + "KG spies are watching our every move,", + "so look out for trouble. Good luck." ], "bb07win": [ "Fint flytte-arbejde! I holder folk i live derude." @@ -737,7 +740,8 @@ "bb08int": [ "Jak, nogle af vores agenter er blevet kompromitteret igen.", "Find hver enkelt og tag dem til specielle skjulesteder i byen.", - "Vagtpatruljerne er i høj beredskab, så den her bliver svær. Hold hovedet nede!" + "The guard patrols are on high alert,", + "so this is going to be a tough one. Keep your head down!" ], "bb08win": [ "Det var god kørsel, Jak.", @@ -4911,10 +4915,10 @@ "Aktivering af sikkerhedsforsvar." ], "kg121": [ - "Giv venligst besked, emnebeskrivelse." + "Please advise, suspect's description." ], "kg121a": [ - "Giv venligst besked, emnebeskrivelse." + "Please advise, suspect's description." ], "kg122": [ "Jeg har civvies i sigte." @@ -5689,11 +5693,11 @@ "kæmper for undergrunden." ], "kg233b": [ - "Jeg er bekymret for denne nye fyr, der kæmper for undergrunden.", + "I'm worried about this new guy", "kæmper for undergrunden." ], "kg234": [ - "Ja, de siger, at han kan ændre sig til en slags... monster." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ "Ja, de siger, at han kan ændre sig til en slags monster." @@ -6939,7 +6943,7 @@ ], "prop049": [ "Jeg er skuffet over denne bys mangel på", - "engagement og opofrelse. Arbejd hårdere! Spis mindre!", + "commitment and sacrifice. Work harder! Eat less!", "Drik kun når jeg fortæller dig! Søvn er valgfrit.", "Vi er i krig med en trussel udefra,", "lad mig heller ikke erklære krig mod dig!" @@ -6947,13 +6951,14 @@ "prop050": [ "Hilsen folk i denne vidunderlige utopi. Årets", "mesterskabsløbet begynder snart. Alle borgere", - "ikke i husarrest inviteres til at komme ned til", - "Stadion og se din yndlingssøn Erol", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", "endnu en gang vise, hvordan Krimzon-garden er eliten", - "krigere i denne by. Tag hele familien med! Den første", - "tusinde børn vil få en obligatorisk", - "Krimzon Guard rekrutteringspakke og være", - "\"bad\" om at slutte sig til vagten for livet, sikke en godbid!" + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ "Dette er din baron, jeg har stadig kontrol!", @@ -6984,22 +6989,24 @@ "det ville være, hvis Metal Heads havde ansvaret!" ], "prop054": [ - "Vi har haft et par hændelser med vores lavere klasses arbejdskraft", - "kraft på det seneste. Hvis din Lurker optræder, så ring til Krimzon", - "Dyrekontrol. Er din Lurker i et træ? Sidder fast i en", - "kloakrist? Skummer om munden? Opkald", - "de venlige officerer i K.A.C. og de vil handle", - "med din lodne slave. med al den kærlighed og omsorg det", - "fortjener... så slæb den væk til renovering.", - "Husk, Lurkers kan være farlige!" + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", + "Remember, Lurkers can be dangerous!" ], "prop055": [ "Giv venligst generøst til Baron økofond.", - "Din overdådige donation vil blive brugt til en række forskellige", - "af humanitære behov: bomber, våben, rustninger, genetiske", - "ændringsforskning, alt sammen for at bevare dette", - "vores vidunderlige by. Giv ofte, giv frit...", - "eller det bliver taget fra dig!" + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", + "wonderful city of ours. Give often, give freely...", + "or it will be taken from you!" ], "prop056": [ "Det kan være så ensomt på toppen og kigge ned fra", @@ -7549,15 +7556,17 @@ "Kys din skinnende røv farvel!" ], "sigt112": [ - "Født til at dræbe baby!" + "Born to kill, baby!" ], "sigt113": [ "To til brystet, en til hovedet." ], "spot004": [ - "Kom ud og hep på mig, mens jeg ødelægger konkurrencen igen på banen.", - "Dette års løbsfinale bliver til at dø for, jeg garanterer mere spænding og mere spild.", - "Denne gang vil jeg have blod!...Tag børnene med." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ "Hej gutter! Det her er Tess. Før Krew gik, så jeg ham gemme sig", @@ -7566,23 +7575,32 @@ "Du vil måske komme og tjekke det ud." ], "tor001": [ - "Operationen var en succes. Alle underjordiske medlemmer er i sikkerhed.", - "Kom tilbage til gemmestedet, jeg har en ny mission til dig, mens vi venter på, at denne alarm blæser over." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "Det burde tage lidt varme fra gaderne. Godt arbejde, jeg kunne ikke have gjort det bedre selv." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "Det var det, Jak, du er oppe! Prøv ikke at udløse nogen alarmer, garnisonens vagter vil være hårde.", - "Gå til fængselscelleblokken og find fangerne. Når vi er der, tænder vi Warp Gate inde for at få jer alle ud igen. Held og lykke." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "Ok, mine gamle adgangskoder skulle hjælpe Vin med at slukke for den magnetiske forsegling til fæstningsdøren." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Jak, det er Torn, byen er under Metal Head-angreb. Der er en stor styrke, der bevæger sig mod bymuren fra havet.", - "Vi har brug for folk, der bemander tårnets geværbøjler for at stoppe det overfald. Mød mig ved havets havvæg i havnen, skynd dig!", - "Vi har brug for hver mand, vi kan få!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ "Jak, det er en vagtspærring, kom ud derfra!" @@ -7807,8 +7825,8 @@ "For mange af dem!! Jak!!! ARHHH!!!" ], "ys001": [ - "Fremragende arbejde, drenge! Kom tilbage til skjulestedet,", - "Jeg har endnu en opgave til jer." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Godt skudt, min dreng!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_de-DE.json b/game/assets/jak2/subtitle/subtitle_lines_de-DE.json index 7618e3a1eb..46936e0285 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_de-DE.json +++ b/game/assets/jak2/subtitle/subtitle_lines_de-DE.json @@ -19,7 +19,7 @@ "Gut gemacht, siehst du? Du hast es immer noch drauf!" ], "DSbop006": [ - "I never found hide nor hair of Keira or Samos.", + "Ich habe weder von Keira noch von Samos auch nur ein Haar gefunden.", "Ich weiß nicht, wo sie hingegangen sind." ], "DSbop007": [ @@ -223,7 +223,7 @@ "Pass auf!" ], "agnt058": [ - "Watch it!" + "Pass auf!" ], "agnt059": [ "WHOA!" @@ -626,7 +626,7 @@ "Hm-agh..." ], "asha057": [ - "Hah...agh..." + "Hah...ah..." ], "asht002": [ "Du hattest recht, Jak. Was mein Vater tut, ist falsch.", @@ -711,10 +711,6 @@ "bb05win": [ "Gute Arbeit! Das dürfte das Kriegsbudget des Barons entlasten." ], - "bb06int": [ - "Jak, du musst eine weitere Gruppe Bomb Bots ausschalten.", - "Diese mobilen Waffen tauchen immer wieder in der Stadt auf, wir müssen sie so schnell wie möglich ausschalten." - ], "bb06win": [ "Noch ein Haufen Bombenbot-Schrott für die KG", "Müllverdichter. Mission erfüllt, die Underground", @@ -723,10 +719,6 @@ "bb07fail": [ "Du hast einen Agenten verloren! Gar nicht gut, Jak! Mission gescheitert!" ], - "bb07int": [ - "Ich bin hin- und hergerissen und möchte, dass Sie rausgehen und weitere unserer Agenten an neue Standorte in der Stadt verlegen.", - "KG-Spione beobachten jede unserer Bewegungen, also mach dich auf Ärger gefasst. Viel Glück." - ], "bb07win": [ "Gute Shuttle-Arbeit! Du hältst da draußen Leute am Leben." ], @@ -734,11 +726,6 @@ "Einer unserer besten Agenten wurde verhaftet. Der Schatten wird NICHT", "erfreut! Du hast versagt." ], - "bb08int": [ - "Jak, einige unserer Agenten wurden erneut kompromittiert.", - "Finden Sie sie alle und bringen Sie sie zu besonderen Verstecken in der Stadt.", - "Die Wachpatrouillen sind in höchster Alarmbereitschaft, das wird also hart. Kopf unten halten!" - ], "bb08win": [ "Das war eine gute Fahrt, Jak.", "Die U-Bahn kann jetzt etwas aufatmen." @@ -1039,7 +1026,7 @@ "Sie können nichts tun!" ], "bf006": [ - "HAHAHAHAHAHA!" + "HAHAHAHAHAHAHA!" ], "bf007": [ "HAHAHAHA!" @@ -1207,7 +1194,7 @@ "Ahh!" ], "bf062": [ - "Ungh!" + "Igitt!" ], "bf063": [ "Raghhh!" @@ -1243,7 +1230,7 @@ "AH!" ], "bf074": [ - "Urgh!" + "Igitt!" ], "bf075": [ "Du kannst es besser machen als das!" @@ -1321,7 +1308,7 @@ "UGHH!" ], "bf100": [ - "Urgh!" + "Igitt!" ], "bf101": [ "Uff!" @@ -1516,7 +1503,7 @@ "Ahh!!" ], "cit098a": [ - "Urgh!" + "Igitt!" ], "cit098b": [ "Pfui!" @@ -1663,7 +1650,7 @@ "Bitte eingeben." ], "cityv025": [ - "Warp Gate online." + "Warp Tor online." ], "cityv026": [ "Achtung: Eco-Vorräte gehen zur Neige." @@ -2365,7 +2352,7 @@ "Ooooh!" ], "ds175": [ - "Whoa-whoa-oaa-ah!" + "Hui-ui-ui-uih!" ], "ds176": [ "Boah!" @@ -3838,7 +3825,7 @@ "Daghh!" ], "hal190": [ - "Oughh..." + "Pfui..." ], "hal191": [ "Krew ist tot, weil sie mich da reingezogen hat!" @@ -3955,7 +3942,7 @@ "Auf geht's!" ], "jak039": [ - "Urgh!" + "Igitt!" ], "jak040": [ "Ich nehme das." @@ -4033,7 +4020,7 @@ "Das ist Vergeltung." ], "jak067": [ - "DIE, Praxis!" + "Stirb, Praxis!" ], "jak068": [ "Du bist erledigt, Kor!" @@ -5688,10 +5675,6 @@ "Ich mache mir Sorgen um diesen neuen Typen", "für den Untergrund kämpfen." ], - "kg233b": [ - "Ich mache mir Sorgen um diesen neuen Kerl, der für die Underground kämpft.", - "für den Untergrund kämpfen." - ], "kg234": [ "Ja, sie sagen, er kann sich in eine Art ... Monster verwandeln." ], @@ -5711,13 +5694,13 @@ "Keine Sorge, sein Kopf hängt schon bald an der Turmmauer." ], "kg236": [ - "Hehehe." + "He-he-he-he." ], "kg236a": [ - "Hehehe." + "He-he-he-he." ], "kg236b": [ - "Hehehe." + "He-he-he-he." ], "kg237a": [ "Hehehe ..." @@ -5726,7 +5709,7 @@ "Hehehe ..." ], "kg238a": [ - "Hahaha..." + "Ha-ha-ha-ha." ], "kg239a": [ "Haha!" @@ -6944,17 +6927,6 @@ "Wir befinden uns im Krieg mit einer äußeren Bedrohung,", "zwing mich nicht, dir auch noch den Krieg zu erklären!" ], - "prop050": [ - "Seid gegrüßt, Bewohner dieser wunderbaren Utopie.", - "Das Meisterschaftsrennen beginnt in Kürze. Alle Bürger", - "nicht unter Hausarrest stehen, sind eingeladen,", - "das Stadion und schau deinem Lieblingssohn Erol zu", - "zeigt einmal mehr, dass die Krimzon-Wache die Elite ist", - "Krieger dieser Stadt. Bringen Sie die ganze Familie mit! Die erste", - "eintausend Kinder erhalten eine obligatorische", - "Rekrutierungspaket für die Krimzon-Wache und", - "„gebeten“, der Garde auf Lebenszeit beizutreten, was für ein Vergnügen!" - ], "prop051": [ "Dies ist Ihr Baron, ich habe immer noch die Kontrolle!", "Und ich versichere Ihnen, es gibt absolut keine Metalheads", @@ -6983,24 +6955,6 @@ "härter als es aussieht, stellen Sie sich vor, wie viel schlimmer", "das wäre es, wenn die Metal Heads das Sagen hätten!" ], - "prop054": [ - "Wir hatten einige Zwischenfälle mit unseren Arbeitern aus der Unterschicht", - "Kraft in letzter Zeit. Wenn Ihr Lurker sich benimmt, rufen Sie Krimzon an", - "Tierkontrolle. Ist Ihr Lurker in einem Baum? In einem", - "Gullydeckel? Schaum vor dem Mund? Rufen Sie", - "die freundlichen Beamten des K.A.C. und sie werden sich darum kümmern", - "mit deinem pelzigen Sklaven. Mit all der Liebe und Sorgfalt, die es", - "verdient ... dann bringen Sie es zur Überholung weg.", - "Denken Sie daran: Lurker können gefährlich sein!" - ], - "prop055": [ - "Bitte spenden Sie großzügig für den Baron-Ökofonds.", - "Ihre großzügige Spende wird für verschiedene Zwecke eingesetzt", - "der humanitären Bedürfnisse: Bomben, Waffen, Rüstungen, genetische", - "Veränderungsforschung, alles im Namen der Erhaltung dieser", - "unsere wunderbare Stadt. Geben Sie oft, geben Sie großzügig ...", - "oder es wird dir weggenommen!" - ], "prop056": [ "Es kann so einsam sein, oben zu stehen und von oben herabzuschauen", "Von hier oben kann ich sehen, dass diese schmutzige Stadt in einer verzweifelten Lage ist", @@ -7554,36 +7508,12 @@ "sigt113": [ "Zwei in die Brust, einer in den Kopf." ], - "spot004": [ - "Kommen Sie raus und feuern Sie mich an, wenn ich die Konkurrenz auf der Strecke wieder einmal zerstöre.", - "Das diesjährige Rennfinale wird ein Traum, ich garantiere noch mehr Nervenkitzel und Stürze.", - "Diesmal will ich Blut! ... Bringen Sie die Kinder mit." - ], "tess001": [ "Hey Leute! Das ist Tess. Bevor Krew ging, sah ich ihn sich verstecken", "etwas in der Spielmaschine hier. Krew kennen,", "es ist wahrscheinlich etwas Wertvolles.", "Vielleicht möchten Sie vorbeikommen und es sich ansehen." ], - "tor001": [ - "Die Operation war erfolgreich. Alle Untergrundmitglieder sind in Sicherheit.", - "Kommen Sie zum Versteck zurück, ich habe eine neue Mission für Sie, während wir darauf warten, dass dieser Alarm vorüber ist." - ], - "tor002": [ - "Das sollte den Druck auf die Straßen etwas verringern. Gute Arbeit, ich hätte es selbst nicht besser machen können." - ], - "tor003": [ - "Das war's, Jak, du bist dran! Versuche, keinen Alarm auszulösen, die Garnisonswachen werden hart sein.", - "Gehen Sie zum Zellenblock des Gefängnisses und suchen Sie die Gefangenen. Dort angekommen, schalten wir das Warp-Tor ein, um Sie alle wieder herauszuholen. Viel Glück." - ], - "tor004": [ - "OK, meine alten Zugangscodes sollten Vin helfen, das Magnetsiegel für die Festungstür auszuschalten." - ], - "tor005": [ - "Jak, hier ist Torn. Die Stadt wird von den Metal Heads angegriffen. Eine große Streitmacht bewegt sich vom Meer aus auf die Stadtmauer zu.", - "Wir brauchen Leute, die die Geschütztürme besetzen, um diesen Angriff zu stoppen. Wir treffen uns an der Meeresmauer im Hafen, beeil dich!", - "Wir brauchen jeden Mann, den wir kriegen können!" - ], "tor007": [ "Jak, das ist eine Straßensperre durch Wachen. Verschwinde da!" ], @@ -7806,10 +7736,6 @@ "Sie brechen durch!!", "Zu viele davon!! Jak!!! AHHHH!!!" ], - "ys001": [ - "Ausgezeichnete Arbeit, Jungs! Kommt zurück zum Hideout,", - "Ich habe eine weitere Aufgabe für Sie." - ], "ys002": [ "Guter Schuss, mein Junge!", "Gute Arbeit, Jak!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_en-GB.json b/game/assets/jak2/subtitle/subtitle_lines_en-GB.json index afcaf059c6..576343dfb7 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_en-GB.json +++ b/game/assets/jak2/subtitle/subtitle_lines_en-GB.json @@ -460,7 +460,7 @@ "Payback's a bitch, and I'm it." ], "asha002": [ - "Watch your ass, I'm only woman on the outside." + "Watch your arse, I'm the only woman on the outside." ], "asha003": [ "Let me knock you down to size...", @@ -644,7 +644,7 @@ "but it might be our only chance." ], "bar001": [ - "Pay no attention to the groundless rumors about", + "Pay no attention to the groundless rumours about", "low eco supplies. As your Baron, I assure you,", "the city has an endless supply of eco stores.", "Those who would say we are running out,", @@ -656,7 +656,7 @@ "Go!" ], "bb01fail": [ - "I think you should practice more." + "I think you should practise more." ], "bb01int": [ "Jak, this is Torn. The Underground needs good drivers", @@ -713,7 +713,8 @@ ], "bb06int": [ "Jak, we need you to take out another group of Bomb Bots.", - "These mobile weapons keep showing up in the city, we gotta take them out as soon as possible." + "These mobile weapons keep showing up in the city,", + "we gotta take them out as soon as possible." ], "bb06win": [ "Another pile of bomb bot scrap metal for the KG", @@ -724,8 +725,10 @@ "You lost an agent! NOT good at all, Jak! Mission failed!" ], "bb07int": [ - "Torn here, I need you to go out and move more of our Agents to new locations in the city.", - "KG spies are watching our every move, so look out for trouble. Good luck." + "Torn here, I need you to go out and move more of our Agents", + "to new locations in the city.", + "KG spies are watching our every move,", + "so look out for trouble. Good luck." ], "bb07win": [ "Nice shuttle work! You're keepin' people alive out there." @@ -737,7 +740,8 @@ "bb08int": [ "Jak, some of our Agents have been compromised again.", "Find each one and take them to special hideouts in the city.", - "The guard patrols are on high alert, so this is going to be a tough one. Keep your head down!" + "The guard patrols are on high alert,", + "so this is going to be a tough one. Keep your head down!" ], "bb08win": [ "That was good driving, Jak.", @@ -966,7 +970,7 @@ "Here's a tough one, beat the clock to here." ], "bb30int": [ - "Recognize this place? Find it fast and a reward is yours." + "Recognise this place? Find it fast and a reward is yours." ], "bb31int": [ "Here's a little known place, find it fast and I'll be impressed." @@ -1177,7 +1181,7 @@ "You're history!" ], "bf052": [ - "I am the city's savior, not you!" + "I am the city's saviour, not you!" ], "bf053": [ "Die!" @@ -1729,16 +1733,16 @@ "Unauthorized movement in sewer system." ], "cityv047": [ - "This is a restricted area. Defenses activated." + "This is a restricted area. Defences activated." ], "cityv048": [ - "You are trespassing. Defenses coming online." + "You are trespassing. Defences coming online." ], "cityv049": [ "I regret use of force. Systems arming." ], "cityv050": [ - "Trespasser neutralized." + "Trespasser neutralised." ], "cityv051": [ "Suspect destroyed." @@ -1938,11 +1942,11 @@ "cityv158": [ "Emergency response needed.", "Runaway bomb bots detected and headed for", - "populated areas. Neutralize all bomb bots", + "populated areas. Neutralise all bomb bots", "before it's too late." ], "cityv159": [ - "You failed to neutralize the runaway bomb bots." + "You failed to neutralise the runaway bomb bots." ], "cityv160": [ "You destroyed the runaway bomb bots.", @@ -1969,7 +1973,7 @@ ], "cityv167": [ "Metal Heads have been detected in the gun course.", - "Neutralize them all immediately." + "Neutralise them all immediately." ], "cityv168": [ "You did not kill them all." @@ -2125,7 +2129,7 @@ "Get the tank to shoot the missile!" ], "ds019": [ - "Break those tubes in the center." + "Break those tubes in the centre." ], "ds020": [ "Please tell me you remember how to roll..." @@ -2525,7 +2529,7 @@ "Lookie what we found!" ], "ds228": [ - "You recognize this monster?" + "You recognise this monster?" ], "ds229": [ "We did it! We saved them all!" @@ -2757,7 +2761,7 @@ "That must be the missile Torn wants us to blow up!" ], "ds354": [ - "Break those tubes in the center, Jak!" + "Break those tubes in the centre, Jak!" ], "ds372": [ "Gotta ride the JET-Board on this one, Jak!" @@ -3056,7 +3060,7 @@ "Had enough?" ], "ero025": [ - "Avoid this, smart-ass!" + "Avoid this, smart-arse!" ], "ero026": [ "Say goodnight, eco freak!" @@ -3303,7 +3307,7 @@ "erol002": [ "This is Erol. Looks like you're running out of friends.", "We've arrested them all and thrown them into your", - "favorite prison. By the way, that blonde girl Tess", + "favourite prison. By the way, that blonde girl Tess", "screamed so delightfully when she was arrested.", "I can't wait for her turn in the chair.", "Hahahahaha...." @@ -3979,7 +3983,7 @@ "Mind if I drive?" ], "jak048": [ - "I like the color of this vehicle." + "I like the colour of this vehicle." ], "jak049": [ "Mine now." @@ -4905,16 +4909,16 @@ "Intruder alert!" ], "kg120": [ - "Activating security defenses." + "Activating security defences." ], "kg120a": [ - "Activating security defenses." + "Activating security defences." ], "kg121": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg121a": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg122": [ "I've got civvies in sight." @@ -4941,10 +4945,10 @@ "Right, we'll check it out." ], "kg126": [ - "Confirmed, Underground suspect neutralized." + "Confirmed, Underground suspect neutralised." ], "kg126a": [ - "Confirmed, Underground suspect neutralized." + "Confirmed, Underground suspect neutralised." ], "kg127": [ "They're all guilty!" @@ -5106,13 +5110,13 @@ "This one was easy!" ], "kg168": [ - "Suspect neutralized." + "Suspect neutralised." ], "kg168a": [ - "Suspect neutralized." + "Suspect neutralised." ], "kg168b": [ - "Suspect neutralized." + "Suspect neutralised." ], "kg169": [ "Didn't even work up a sweat." @@ -5211,13 +5215,13 @@ "I hear the Underground are getting stronger." ], "kg182": [ - "Just rumors, private, keep your mouth shut." + "Just rumours, private, keep your mouth shut." ], "kg182a": [ - "Just rumors, private, keep your mouth shut." + "Just rumours, private, keep your mouth shut." ], "kg182b": [ - "Just rumors, private, keep your mouth shut." + "Just rumours, private, keep your mouth shut." ], "kg183": [ "It's us or them, there's no in-between." @@ -5337,7 +5341,7 @@ "I'm bored, I want to crunch heads." ], "kg196": [ - "I want to kick some ass." + "I want to kick some arse." ], "kg196a": [ "Ugh... I want to kick some butt." @@ -5405,13 +5409,13 @@ "Can I shoot someone now?" ], "kg203": [ - "I like the new armor." + "I like the new armour." ], "kg203a": [ - "I like the new armor." + "I like the new armour." ], "kg203b": [ - "I like the new armor." + "I like the new armour." ], "kg204": [ "Yeah, me too. More comfort in the crotch." @@ -5689,11 +5693,11 @@ "fighting for the Underground." ], "kg233b": [ - "I'm worried about this new guy fighting for the Underground.", + "I'm worried about this new guy", "fighting for the Underground." ], "kg234": [ - "Yeah, they say he can change into some kind of... monster." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ "Yeah, they say he can change into some kind of monster." @@ -6401,7 +6405,7 @@ "up and running. It's not good for business.", "Ride the JET-Board out into the Port", "and destroy every Krimzon Guard crate you find.", - "There's sure to be a defense perimeter,", + "There's sure to be a defence perimeter,", "so watch out, 'ey?" ], "krew002": [ @@ -6914,12 +6918,12 @@ ], "prop046": [ "This is your Baron. I have been informed by the", - "ministry of extreme labor that worker productivity is", + "ministry of extreme labour that worker productivity is", "down this month! That is unacceptable!", "I give you safety and this is how you repay me?", "You must work harder, not smarter!", "Free the mind and the body will do as it's told,", - "forced labor will set you free!", + "forced labour will set you free!", "And to help you in your spiritual motivation...", "quotas are doubled next month!" ], @@ -6939,7 +6943,7 @@ ], "prop049": [ "I am disappointed with this city's lack of", - "committment and sacrifice. Work harder! Eat less!", + "commitment and sacrifice. Work harder! Eat less!", "Drink only when I tell you! Sleep is optional.", "We are at war with an outside threat,", "don't make me declare war on you as well!" @@ -6947,13 +6951,14 @@ "prop050": [ "Greetings, people of this wonderful utopia. This year's", "championship race will begin shortly. All citizens", - "not under house arrest are invited to come down to", - "the Stadium and watch your favorite son Erol", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", "once again show how the Krimzon Guard are the elite", - "warriors of this city. Bring the whole family! The first", - "one thousand children will get a mandatory", - "Krimzon Guard recruitment package and be", - "\"asked\" to join the Guard for life, what a treat!" + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ "This is your Baron, I am still in control!", @@ -6984,20 +6989,22 @@ "it would be if the Metal Heads were in charge!" ], "prop054": [ - "We've had a few incidents with our lower class labor", - "force lately. If your Lurker is acting up, call Krimzon", - "Animal Control. Is your Lurker in a tree? Stuck in a", - "sewer grate? Foaming at the mouth? Call", - "the friendly officers of the K.A.C. and they will deal", - "with your furry slave. with all the love and care it", - "deserves... then haul it away for reconditioning.", + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", "Remember, Lurkers can be dangerous!" ], "prop055": [ "Please give generously to the Baron eco fund.", - "Your munificent donation wil be used for a variety", - "of humanitarian needs: bombs, guns, armor, genetic", - "alteration research, all in the name of preserving this", + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", "wonderful city of ours. Give often, give freely...", "or it will be taken from you!" ], @@ -7022,7 +7029,7 @@ "I vowed never to let this city fall, and I intend to keep", "that promise. What must happen is for the good of all!", "Remember, to die in victory is a glorious", - "badge of honor!" + "badge of honour!" ], "prop058": [ "This is Baron Praxis. As our city faces its worst threat", @@ -7549,15 +7556,17 @@ "Kiss your shiny butt goodbye!" ], "sigt112": [ - "Born to kill baby!" + "Born to kill, baby!" ], "sigt113": [ "Two to the chest, one to the head." ], "spot004": [ - "Come out and cheer for me as I destroy the competition once again on the track.", - "This year's racing final will be to die for, I guarantee more thrills and more spills.", - "This time I want blood!...Bring the kids." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ "Hey, guys! This is Tess. Before Krew left, I saw him hide", @@ -7566,23 +7575,32 @@ "You might wanna come check it out." ], "tor001": [ - "The operation was a success. All Underground members are safe.", - "Come back to the hideout, I have a new mission for you while we wait for this alert to blow over." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "That should take some heat off the streets. Good work, I couldn't have done it better myself." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "That's it, Jak, you're up! Try not to trigger any alarms, the garrison guards will be tough.", - "Get to the prison cell block and find the prisoners. Once there, we'll turn on the Warp Gate inside to get you all back out. Good luck." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "Ok, my old access codes should help Vin turn off the magnetic seal for the Fortress door." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Jak, this is Torn, the city is under Metal Head attack. There's a large force moving toward the city wall from the ocean.", - "We need people manning the tower gunpods to stop that assault. Meet me at the seaside ocean wall in the Port, hurry!", - "We need every man we can get!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ "Jak, it's a guard roadblock, get out of there!" @@ -7807,8 +7825,8 @@ "Too many of them!! Jak!!! AHHHH!!!" ], "ys001": [ - "Excellent work, boys! Come on back to the Hideout,", - "I have another task for you." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Nice shooting, my boy!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_en-US.json b/game/assets/jak2/subtitle/subtitle_lines_en-US.json index afcaf059c6..3849a6c5ca 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_en-US.json +++ b/game/assets/jak2/subtitle/subtitle_lines_en-US.json @@ -713,7 +713,8 @@ ], "bb06int": [ "Jak, we need you to take out another group of Bomb Bots.", - "These mobile weapons keep showing up in the city, we gotta take them out as soon as possible." + "These mobile weapons keep showing up in the city,", + "we gotta take them out as soon as possible." ], "bb06win": [ "Another pile of bomb bot scrap metal for the KG", @@ -724,8 +725,10 @@ "You lost an agent! NOT good at all, Jak! Mission failed!" ], "bb07int": [ - "Torn here, I need you to go out and move more of our Agents to new locations in the city.", - "KG spies are watching our every move, so look out for trouble. Good luck." + "Torn here, I need you to go out and move more of our Agents", + "to new locations in the city.", + "KG spies are watching our every move,", + "so look out for trouble. Good luck." ], "bb07win": [ "Nice shuttle work! You're keepin' people alive out there." @@ -737,7 +740,8 @@ "bb08int": [ "Jak, some of our Agents have been compromised again.", "Find each one and take them to special hideouts in the city.", - "The guard patrols are on high alert, so this is going to be a tough one. Keep your head down!" + "The guard patrols are on high alert,", + "so this is going to be a tough one. Keep your head down!" ], "bb08win": [ "That was good driving, Jak.", @@ -4911,10 +4915,10 @@ "Activating security defenses." ], "kg121": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg121a": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg122": [ "I've got civvies in sight." @@ -5689,11 +5693,11 @@ "fighting for the Underground." ], "kg233b": [ - "I'm worried about this new guy fighting for the Underground.", + "I'm worried about this new guy", "fighting for the Underground." ], "kg234": [ - "Yeah, they say he can change into some kind of... monster." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ "Yeah, they say he can change into some kind of monster." @@ -6939,7 +6943,7 @@ ], "prop049": [ "I am disappointed with this city's lack of", - "committment and sacrifice. Work harder! Eat less!", + "commitment and sacrifice. Work harder! Eat less!", "Drink only when I tell you! Sleep is optional.", "We are at war with an outside threat,", "don't make me declare war on you as well!" @@ -6947,13 +6951,14 @@ "prop050": [ "Greetings, people of this wonderful utopia. This year's", "championship race will begin shortly. All citizens", - "not under house arrest are invited to come down to", - "the Stadium and watch your favorite son Erol", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", "once again show how the Krimzon Guard are the elite", - "warriors of this city. Bring the whole family! The first", - "one thousand children will get a mandatory", - "Krimzon Guard recruitment package and be", - "\"asked\" to join the Guard for life, what a treat!" + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ "This is your Baron, I am still in control!", @@ -6984,20 +6989,22 @@ "it would be if the Metal Heads were in charge!" ], "prop054": [ - "We've had a few incidents with our lower class labor", - "force lately. If your Lurker is acting up, call Krimzon", - "Animal Control. Is your Lurker in a tree? Stuck in a", - "sewer grate? Foaming at the mouth? Call", - "the friendly officers of the K.A.C. and they will deal", - "with your furry slave. with all the love and care it", - "deserves... then haul it away for reconditioning.", + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", "Remember, Lurkers can be dangerous!" ], "prop055": [ "Please give generously to the Baron eco fund.", - "Your munificent donation wil be used for a variety", - "of humanitarian needs: bombs, guns, armor, genetic", - "alteration research, all in the name of preserving this", + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", "wonderful city of ours. Give often, give freely...", "or it will be taken from you!" ], @@ -7549,15 +7556,17 @@ "Kiss your shiny butt goodbye!" ], "sigt112": [ - "Born to kill baby!" + "Born to kill, baby!" ], "sigt113": [ "Two to the chest, one to the head." ], "spot004": [ - "Come out and cheer for me as I destroy the competition once again on the track.", - "This year's racing final will be to die for, I guarantee more thrills and more spills.", - "This time I want blood!...Bring the kids." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ "Hey, guys! This is Tess. Before Krew left, I saw him hide", @@ -7566,23 +7575,32 @@ "You might wanna come check it out." ], "tor001": [ - "The operation was a success. All Underground members are safe.", - "Come back to the hideout, I have a new mission for you while we wait for this alert to blow over." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "That should take some heat off the streets. Good work, I couldn't have done it better myself." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "That's it, Jak, you're up! Try not to trigger any alarms, the garrison guards will be tough.", - "Get to the prison cell block and find the prisoners. Once there, we'll turn on the Warp Gate inside to get you all back out. Good luck." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "Ok, my old access codes should help Vin turn off the magnetic seal for the Fortress door." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Jak, this is Torn, the city is under Metal Head attack. There's a large force moving toward the city wall from the ocean.", - "We need people manning the tower gunpods to stop that assault. Meet me at the seaside ocean wall in the Port, hurry!", - "We need every man we can get!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ "Jak, it's a guard roadblock, get out of there!" @@ -7807,8 +7825,8 @@ "Too many of them!! Jak!!! AHHHH!!!" ], "ys001": [ - "Excellent work, boys! Come on back to the Hideout,", - "I have another task for you." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Nice shooting, my boy!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_es-ES.json b/game/assets/jak2/subtitle/subtitle_lines_es-ES.json index aadf3a31ba..2d545cec37 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_es-ES.json +++ b/game/assets/jak2/subtitle/subtitle_lines_es-ES.json @@ -711,10 +711,6 @@ "bb05win": [ "¡Buen trabajo! Menudo sablazo para el presupuesto bélico del barón." ], - "bb06int": [ - "Jak, necesitamos que acabes con otro grupo de Bomba Bots.", - "Estas armas móviles no dejan de aparecer por la ciudad, hay que acabar con ellos cuanto antes." - ], "bb06win": [ "Otro cargamento de chapa de Bomba Bot para el", "desguace. Misión cumplida, la Resistencia", @@ -723,10 +719,6 @@ "bb07fail": [ "¡Has perdido un agente! ¡Esto está fatal, Jak! ¡Misión fallida!" ], - "bb07int": [ - "Aquí Torn, necesito que transportes a más agentes nuestros a nuevas posiciones en la ciudad.", - "Los espías de la Guardia nos vigilan de cerca, así que ten cuidado. Buena suerte." - ], "bb07win": [ "¡Buen trabajo! Gracias a ti, nuestra gente sigue viva." ], @@ -734,11 +726,6 @@ "Han arrestado a uno de nuestros mejores agentes. ¡A la Sombra no le va", "a gustar! Has fracasado." ], - "bb08int": [ - "Jak, algunos de nuestros agentes vuelven a estar en peligro.", - "Búscalos y llévalos a los escondites especiales de la ciudad.", - "Las patrullas de la guardia están en alerta máxima, así que será difícil. ¡Procura que no te vean!" - ], "bb08win": [ "Así se conduce, Jak.", "La Resistencia puede respirar tranquila ahora." @@ -5688,10 +5675,6 @@ "Me preocupa lo del tipo nuevo", "que lucha para la Resistencia." ], - "kg233b": [ - "Me preocupa lo del tipo nuevo que lucha para la Resistencia.", - "que lucha para la Resistencia." - ], "kg234": [ "Sí, dicen que puede transformarse en un monstruo." ], @@ -6944,17 +6927,6 @@ "Luchamos con una amenaza externa,", "¡no me obliguéis a declararos la guerra!" ], - "prop050": [ - "Saludos, habitantes de esta perfecta utopía. Pronto", - "empezará la carrera de este año. Los ciudadanos", - "libres de arresto domiciliario pueden ir al estadio", - "a ver como su hijo favorito, Erol, demuestra", - "que la Guardia Carmesí son los guerreros de élite", - "de la ciudad. ¡Venid con toda la familia! Los primeros", - "mil niños tendrán un paquete de reclutamiento", - "de la Guardia Carmesí obligatorio y les", - "\"pediremos\" que se queden de por vida, ¡qué suerte!" - ], "prop051": [ "Soy vuestro Barón, ¡aún tengo el mando!", "Os aseguro que no quedan Cabezachapas", @@ -6983,24 +6955,6 @@ "mas duro de lo que parece, pues sería peor", "si se ocuparan los Cabezachapas." ], - "prop054": [ - "Hemos tenido algunos incidentes con la clase baja", - "trabajadora. Si vuestro Lurker se desmanda, llamad al", - "Control de Animales Carmesí. ¿El Lurker está en un arbol?", - "¿Atrapado en una alcantarilla? ¿Echa espuma por la boca?", - "Llamad a los cordiales oficiales del C.A.C. y ellos tratarán", - "vuestro peludo amigo con el amor y cuidado que", - "merece... y se lo llevarán para amaestrarlo.", - "Recordad, ¡los Lurkers pueden ser peligrosos!" - ], - "prop055": [ - "Por favor, donad generosamente al fondo de eco del Barón.", - "Vuestra generosa donación se invertirá en acciones", - "humanitarias: bombas, armas, blindajes e investigación", - "en modificación genética, todo para preservar", - "nuestra maravillosa ciudad. Donad a menudo,", - "libremente, ¡u os lo quitaremos!" - ], "prop056": [ "Se está tan solo en la cumbre, y desde arriba puedo", "que esta sucia ciudad necesita desesperadamente", @@ -7554,36 +7508,12 @@ "sigt113": [ "Dos en el pecho, uno en la cabeza." ], - "spot004": [ - "Venid a aclamarme mientras destrozo de nuevo a mis rivales en el circuito.", - "La final de este año será para morirse, garantizo que habrá más emoción.", - "¡Esta vez quiero sangre! ...Traed a los críos." - ], "tess001": [ "¡Eh, chicos! Aquí Tess. Antes de que Krew se fuese, le vi esconder", "algo en la máquina de juegos. Conociéndole,", "es probable que sea algo valioso.", "Quizá queráis venir a echar un vistazo." ], - "tor001": [ - "La operación ha sido un éxito. Todos los miembros de la Resistencia están a salvo.", - "Venid al escondite, tengo una nueva misión para vosotros mientras esperamos a que la alarma acabe." - ], - "tor002": [ - "Eso aliviará la tensión de las calles. Buen trabajo, yo no lo habría hecho mejor." - ], - "tor003": [ - "Eso es, Jak, ¡tu turno! No dispares las alarmas, los guardias de retén son duros.", - "Ve al bloque de celdas y busca a los prisioneros. Cuando estéis allí, activaremos el Portal de dentro para sacaros a todos. Buena suerte." - ], - "tor004": [ - "Bien, mi viejo código de acceso permitirá a Vin desactivar el cierre magnético de la puerta de la Fortaleza." - ], - "tor005": [ - "Jak, aquí Torn. Los Cabezachapas atacan la ciudad. Un gran contingente se acerca a la muralla desde el mar.", - "Para detenerlos, necesitamos que alguien dispare desde las cápsulas armadas. Reuníos conmigo en la muralla que da al mar, ¡deprisa!", - "¡Necesitamos a todos los hombres posibles!" - ], "tor007": [ "Jak, los guardias han bloqueado el camino, ¡sal de aquí!" ], @@ -7806,10 +7736,6 @@ "¡¡La están rompiendo!!", "¡¡Son demasiados!! ¡¡¡Jak!!! ¡¡¡AHHHH!!!" ], - "ys001": [ - "¡Excelente, muchachos! Volved al Escondite,", - "Tengo otra misión para vosotros." - ], "ys002": [ "¡Buen disparo, chaval!", "¡Buen trabajo, Jak!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_fi-FI.json b/game/assets/jak2/subtitle/subtitle_lines_fi-FI.json index 2a5dc78628..76c33da665 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_fi-FI.json +++ b/game/assets/jak2/subtitle/subtitle_lines_fi-FI.json @@ -9829,4 +9829,4 @@ "youngsamos": "Nuori Samos", "youngsamos-before-rescue": "Samos" } -} +} \ No newline at end of file diff --git a/game/assets/jak2/subtitle/subtitle_lines_fr-FR.json b/game/assets/jak2/subtitle/subtitle_lines_fr-FR.json index af91ced625..42064c0e2d 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_fr-FR.json +++ b/game/assets/jak2/subtitle/subtitle_lines_fr-FR.json @@ -4,6 +4,53 @@ "DSbop001": [ "Tu as l'air vraiment en colère, Jak." ], + "DSbop002": [ + "Tu te souviens comment on saute ?" + ], + "DSbop003": [ + "Saute sur cette caisse pour franchir la barricade." + ], + "DSbop004": [ + "Ooh, c'est haut !", + "Pour l'atteindre, saute une première fois", + "et recommence une fois en l'air." + ], + "DSbop005": [ + "Good job, see? You still got it!" + ], + "DSbop006": [ + "I never found hide nor hair of Keira or Samos.", + "Je ne sais pas où ils sont allés." + ], + "DSbop007": [ + "I don't know where that crazy rift vehicle took us, but...", + "C'est une bien grande ville !" + ], + "DSbop008": [ + "It's a tough place, Jak. You DO remember", + "how to fight, right? Try breaking that crate with a kick." + ], + "DSbop009": [ + "Looking good, partner! Nice spin kick!", + "Works out some of that anger, eh?" + ], + "DSbop010": [ + "Il y a beaucoup de caisses Grenagarde qui", + "nous tendent les bras. Démolis celles-là !" + ], + "DSbop011": [ + "Bien joué ! Elle contient une trousse de secours.", + "Prends-la, t'as intérêt à rester en bonne santé, Jak, hein sinon...", + "qui c'est qui va se battre ?" + ], + "DSbop016": [ + "Si tu sautes avant de plonger, tu retomberas assez", + "violemment pour faire de gros dégâts.", + "C'est drôle de casser des trucs, hein ?" + ], + "DSbop017": [ + "Jak, les gardes ! À toi... à... à toi de jouer." + ], "agnt001": [ "Hé, conduisez prudemment !" ], @@ -68,19 +115,19 @@ "Allez-y foncez !" ], "agnt022": [ - "Dépêchez-vous !" + "Dépêche-toi mec !" ], "agnt023": [ - "Je peux pas monter à l'arrière, trouvez un biplace !" + "Je ne peux pas monter à l'arrière, trouvez un biplace !" ], "agnt024": [ - "Prenez une plus grande voiture !" + "Trouvez une voiture plus grande !" ], "agnt025": [ - "Prenez un plus grand véhicule." + "Trouvez un véhicule plus grand." ], "agnt026": [ - "Trouvez un biplace, ok ?" + "Trouvez en un avec deux sièges, d'accord ?" ], "agnt027": [ "Trouvez un autre véhicule." @@ -664,10 +711,6 @@ "bb05win": [ "Beau travail ! Ça va faire un trou dans le budget de guerre du Baron." ], - "bb06int": [ - "Jak, on a besoin de toi pour éliminer un autre groupe d'explorobots.", - "Ces armes mobiles sont partout en ville, il faut les détruire au plus vite." - ], "bb06win": [ "Encore des explorobots réduits en miettes et bons pour la casse de la Grenagarde.", "Mission accomplie, les Souterrains te sont", @@ -676,10 +719,6 @@ "bb07fail": [ "Tu as perdu un agent ! Ce n'est pas bien, Jak ! Tu as échoué !" ], - "bb07int": [ - "Ici Torn, il faut que tu conduises d'autres agents en d'autres points de la ville.", - "Les espions de la Grenagarde nous surveillent, alors sois prudent. Bonne chance." - ], "bb07win": [ "Beau travail ! Tu as sauvé des vies là-bas." ], @@ -687,11 +726,6 @@ "Un de nos meilleurs agents a été arrêté. Le Sphinx ne", "va pas être content ! Tu as échoué." ], - "bb08int": [ - "Jak, plusieurs de nos agents sont encore en danger.", - "Trouve-les et conduis-les vers des cachettes spéciales.", - "Les patrouilles de la garde sont en alerte maximale, ça va pas être facile. Sois extrêmement prudent." - ], "bb08win": [ "Bon pilotage, Jak.", "Les Souterrains vont pouvoir respirer un peu." @@ -2897,34 +2931,6 @@ "ds503": [ "Je crois qu'on doit regagner la ville, Jak." ], - "DSbop002": [ - "Tu te souviens comment on saute ?" - ], - "DSbop003": [ - "Saute sur cette caisse pour franchir la barricade." - ], - "DSbop004": [ - "Ooh, c'est haut !", - "Pour l'atteindre, saute une première fois", - "et recommence une fois en l'air." - ], - "DSbop010": [ - "Il y a beaucoup de caisses Grenagarde qui", - "me tendent les bras. Démolis celles-là !" - ], - "DSbop011": [ - "Bien joué ! Elle contient une trousse de secours.", - "Prends-la, t'as intérêt à rester en bonne santé, Jak, hein sinon...", - "Qui c'est qui va se battre ?" - ], - "DSbop016": [ - "Si tu sautes avant de plonger, tu retomberas assez", - "violemment pour faire de gros dégâts.", - "C'est drôle de casser des trucs, hein ?" - ], - "DSbop017": [ - "Jak, les gardes ! À toi... à... à toi de jouer." - ], "dsek001": [ "Petit ! Ne t'éloigne pas !" ], @@ -3287,8 +3293,7 @@ "Au fait, la blonde Tess je crois,", "elle pousse de jolis petits cris quand elle a peur.", "J'ai hâte de la faire passer sur la chaise.", - "N'oublie pas, si je te laisse libre, c'est uniquement pour t'affronter au championnat.", - "D'ici là, ne meurs pas de solitude ! Hahahahaha...." + "N'oublie pas, si je te laisse libre, c'est uniquement pour t'affronter au championnat." ], "erol003": [ "Ici Erol. N'oublie pas que si je te laisse gentillement respirer", @@ -4117,9 +4122,6 @@ "jk019": [ "Saute dans le véhicule, Dax !" ], - "jakfall": [ - "AAAAAAAAAH !" - ], "kei001": [ "Tu peux monter sur le Jet Board ou en descendre à tout moment." ], @@ -5711,7 +5713,7 @@ "Héhéhahahaha..." ], "kg238a": [ - "Hahaha..." + "Ha-ha-ha-ha." ], "kg239a": [ "Hah !" @@ -6929,17 +6931,6 @@ "Nous luttons contre une menace extérieure,", "ne me forcez pas à vous déclarer la guerre à vous aussi !" ], - "prop050": [ - "Salutations, ô peuple de cette merveilleuse utopie.", - "Le championnat de cette année va bientôt commencer.", - "Les citoyens qui ne sont pas en résidence surveillée", - "sont invités à venir au stade pour voir Erol", - "l'enfant chéri de la ville vers la démonstration de la", - "puissance de la Grenagarde. Venez en famille !", - "Les 1000 premiers enfants recevront un dossier de", - "recrutement obligatoire et se verront", - "\"proposés\" de rejoindre la Grenagarde à vie, quel honneur !" - ], "prop051": [ "C'est votre Baron qui vous parle, je contrôle toujours la situation !", "Je vous assure, qu'il n'y a aucun Metal Head", @@ -6968,24 +6959,6 @@ "est une chose difficile, ne serait-ce pas bien pire", "si les Metal Heads vous gouvernaient !" ], - "prop054": [ - "Nous avons eu quelques incidents avec notre classe ouvrière", - "inférieure. Si votre lurker se rebelle, appelez le", - "Grenacontrôle des animaux. Il est dans un arbre ? Coincé dans", - "une bouche d'égout ? Il bave abondamment ? Appelez les", - "agent du G.A et ils s'occuperont de", - "votre esclave poilu. Avec toute la délicatesse requise", - "avant de l'embarquer.", - "Rapellez-vous que les lurkers peuvent être dangereux !" - ], - "prop055": [ - "Contribuez généreusement au fond éco du Baron.", - "Vos dons serviront à toute sorte de besoin humanitaire :", - "bombes, fusils, armures, recherches en", - "transformation génétique, dans l'unique but de préserver", - "votre ville magnifique. Donnez souvent, donnez librement...", - "ou nous nous servirons !" - ], "prop056": [ "On se sent un peu seul là-haut, et...", "quand je baisse les yeux, je me rends compte que cette ville poussièreuse", @@ -7539,36 +7512,12 @@ "sigt113": [ "Deux pour la poitrine, un pour la tête." ], - "spot004": [ - "Venez applaudir une fois de plus le grand vainqueur habituel de la course.", - "Il ne faut pas manquer la finale de cette année, je vous promets encore plus de collisions et plus d'émotions.", - "Je veux que ça saigne cette fois ! ...N'oubliez pas d'amener les gosses." - ], "tess001": [ "Hé, les gars ! C'est Tess. J'ai vu Krew cacher un truc", "derrière la machine là. Connaissant l'oiseau,", "c'est sûrement quelque chose de précieux.", "Vous devriez jeter un oeil." ], - "tor001": [ - "L'opération est un véritable succès. Tous les membres des Souterrains sont sains et saufs.", - "Rentrez à la cachette, j'ai une nouvelle mission à vous confier en attendant que ça se calme." - ], - "tor002": [ - "Ça devrait calmer un peu les choses. Beau boulot, j'aurais pas fait mieux moi-même." - ], - "tor003": [ - "C'est ça, Jak, à toi de jouer ! Ne déclenche surtout pas les alarmes, les gardes ne sont pas des enfants de coeur.", - "Rends-toi dans le quartier de détention et trouve les prisonniers. Ensuite, nous activerons le téléporteur pour vous tirer de là. Bonne chance." - ], - "tor004": [ - "Ok, mes anciens codes d'accès devraient aider Vin à désactiver le sceau magnétique de la porte de la forteresse." - ], - "tor005": [ - "Jak, ici Torn, Les Metal Heads nous attaquent par l'océan. Leurs effectifs sont importants et ils se dirigent vers les murs de la ville.", - "On a besoin de renforts pour armer les gunpods et repousser l'attaque. Rejoins-moi au mur de l'océan au Port, fais vite !", - "On a besoin de toute l'aide possible !" - ], "tor007": [ "Jak, c'est un barrage Grenagarde, sors de là !" ], @@ -7791,10 +7740,6 @@ "Ils entrent de force !!", "Ils sont trop nombreux !! Jak !!! AHHHH !!!" ], - "ys001": [ - "Excellent les gars ! Revenez à la cachette,", - "j'ai une autre mission pour vous." - ], "ys002": [ "Joli coup, mon grand !", "Beau travail, Jak !", @@ -7823,8 +7768,8 @@ "kid": "Enfant", "kor": "Kor", "krew": "Krew", - "metalkor": "Metal Kor", - "metalkor-before-consite": "Metal Head Leader", + "metalkor": "Métal Kor", + "metalkor-before-consite": "Le chef des Metal Heads", "metalkor-intro": "???", "mog": "Mog", "onin": "Onin", diff --git a/game/assets/jak2/subtitle/subtitle_lines_hu-HU.json b/game/assets/jak2/subtitle/subtitle_lines_hu-HU.json index 70084b2d6d..bed1778fa5 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_hu-HU.json +++ b/game/assets/jak2/subtitle/subtitle_lines_hu-HU.json @@ -713,7 +713,8 @@ ], "bb06int": [ "Jak, szükségünk van arra, hogy vegyél ki egy másik bombabotot.", - "Ezek a mobil fegyverek folyamatosan felbukkannak a városban, mihamarabb ki kell szednünk őket." + "These mobile weapons keep showing up in the city,", + "we gotta take them out as soon as possible." ], "bb06win": [ "Újabb halom bombabot fémhulladék a KG-nek", @@ -724,8 +725,10 @@ "Elvesztettél egy ügynököt! Egyáltalán nem jó, Jak! Küldetés sikertelen!" ], "bb07int": [ - "Itt szakadt, menj ki és költöztess több ügynökünket új helyekre a városban.", - "KG kémek figyelik minden lépésünket, szóval vigyázz a bajra. Sok szerencsét." + "Torn here, I need you to go out and move more of our Agents", + "to new locations in the city.", + "KG spies are watching our every move,", + "so look out for trouble. Good luck." ], "bb07win": [ "Szép transzfer munka! Életben tartod az embereket odakint." @@ -737,7 +740,8 @@ "bb08int": [ "Jak, néhány ügynökünk ismét kompromittálódott.", "Keresse meg mindegyiket, és vigye el őket a város különleges búvóhelyeire.", - "Az őrs járőrök fokozott készültségben vannak, szóval ez nehéz lesz. Tartsd a fejed Lent!" + "The guard patrols are on high alert,", + "so this is going to be a tough one. Keep your head down!" ], "bb08win": [ "Jó volt vezetni, Jak.", @@ -4911,10 +4915,10 @@ "Biztonsági védelem aktiválása." ], "kg121": [ - "Kérem adjon tanácsot, a tárgy leírását." + "Please advise, suspect's description." ], "kg121a": [ - "Kérem adjon tanácsot, a tárgy leírását." + "Please advise, suspect's description." ], "kg122": [ "Civviesek vannak a szemem előtt." @@ -5689,11 +5693,11 @@ "harcol a földalattiért." ], "kg233b": [ - "Aggódom az új srác miatt, aki az Undergroundért harcol.", + "I'm worried about this new guy", "harcol a földalattiért." ], "kg234": [ - "Igen, azt mondják, hogy valamiféle... szörnyeteggé változhat." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ "Igen, azt mondják, hogy valamiféle szörnyeteggé változhat." @@ -6939,7 +6943,7 @@ ], "prop049": [ "Csalódott vagyok a város hiánya miatt", - "elkötelezettség és áldozatvállalás. Keményebben dolgozik! Kevesebbet eszik!", + "commitment and sacrifice. Work harder! Eat less!", "Csak akkor igyál, ha én mondom! Az alvás nem kötelező.", "Külső fenyegetéssel állunk háborúban,", "ne kényszeríts arra, hogy hadat üzenjek neked is!" @@ -6947,13 +6951,14 @@ "prop050": [ "Üdvözlöm, ennek a csodálatos utópiának az emberei. Ezek az évek", "bajnoki futam hamarosan kezdődik. Minden állampolgár", - "nincs házi őrizetben, felkérik, hogy jöjjön le", - "a Stadionba, és nézze meg kedvenc fiát, Erolt", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", "még egyszer mutasd meg, hogy a krimzoni gárda az elit", - "ennek a városnak a harcosai. Hozd el az egész családot! Az első", - "ezer gyerek kap majd kötelezőt", - "Krimzon gárda toborzási csomag és legyen", - "\"felkért\" egy életre a gárdához, micsoda csemege!" + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ "Ez a te báró, még mindig én irányítom!", @@ -6984,22 +6989,24 @@ "az lenne, ha a fémfejek irányítanák!" ], "prop054": [ - "Volt néhány incidens az alsóbb osztályú munkásainkkal", - "erőt mostanában. Ha a lurkere cselekszik, hívja Krimzont", - "Állatszabályozás. A lurkód egy fában van? Beragadt a", - "csatorna rács? Habzik a száj? Hívás", - "a K.A.C. barátságos tisztjei és elintézik", - "szőrös rabszolgáddal. minden szeretettel és törődéssel", - "megérdemli... aztán vigye el felújításra.", - "Ne feledje, a lurkók veszélyesek lehetnek!" + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", + "Remember, Lurkers can be dangerous!" ], "prop055": [ "Kérem, támogassa nagylelkűen a Baron ökoalapot.", - "Bőséges adományát sokféle célra fordítjuk", - "humanitárius szükségletek: bombák, fegyverek, páncélok, genetikai", - "változáskutatás, mindezt ennek megőrzése érdekében", - "csodálatos városunk. Adj gyakran, adj ingyen...", - "vagy elveszik tőled!" + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", + "wonderful city of ours. Give often, give freely...", + "or it will be taken from you!" ], "prop056": [ "Olyan magányos lehet a tetején és onnan nézve", @@ -7549,15 +7556,17 @@ "Csókold meg a csillogó fenekedet, búcsút!" ], "sigt112": [ - "Arra született, hogy megölje a babát!" + "Born to kill, baby!" ], "sigt113": [ "Kettőt a mellkasra, egyet a fejre." ], "spot004": [ - "Gyertek ki és szurkoljatok nekem, ahogy újra tönkreteszem a versenyt a pályán.", - "Az idei verseny döntője az lesz, hogy meghaljunk, garantálom, hogy még több izgalmat és kiöntést kapunk.", - "Ezúttal vért akarok!...Hozd a gyerekeket." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ "Hé srácok! Ő itt Tess. Mielőtt Krew elment, láttam, hogy elbújik", @@ -7566,23 +7575,32 @@ "Érdemes lenne megnézni." ], "tor001": [ - "A művelet sikeres volt. Minden Underground tag biztonságban van.", - "Gyere vissza a búvóhelyre, új küldetésem van számodra, amíg arra várunk, hogy ez a riasztás lefújjon." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "Ez elvenné a hőt az utcákról. Szép munka, magam sem csinálhattam volna jobban." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "Ennyi, Jak, felkeltél! Lehetőleg ne indítson riasztást, a helyőrség őrsége kemény lesz.", - "Menj el a börtöncella blokkjába, és keresd meg a foglyokat. Amint ott vagyunk, bekapcsoljuk a Warp Gate-t, hogy visszajusson. Sok szerencsét." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "Rendben, a régi hozzáférési kódjaim segíthetnek Vinnek kikapcsolni az erőd ajtajának mágneses tömítését." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Jak, ez Torn, a város Metal Head támadás alatt áll. Hatalmas erő halad a városfal felé az óceán felől.", - "Emberekre van szükségünk, akik a torony lövedékeit irányítják, hogy megállítsák ezt a támadást. Találkozzunk a tengerparti óceánfalnál a kikötőben, siess!", - "Minden emberre szükségünk van!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ "Jak, ez egy őr úttorlasz, menj onnan!" @@ -7807,8 +7825,8 @@ "Túl sok belőlük!! Jak!!! AHHHH!!!" ], "ys001": [ - "Kiváló munka, fiúk! Gyere vissza a rejtekhelyre,", - "Van még egy feladatom a számodra." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Szép lövöldözés, fiam!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_is-IS.json b/game/assets/jak2/subtitle/subtitle_lines_is-IS.json index afcaf059c6..3849a6c5ca 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_is-IS.json +++ b/game/assets/jak2/subtitle/subtitle_lines_is-IS.json @@ -713,7 +713,8 @@ ], "bb06int": [ "Jak, we need you to take out another group of Bomb Bots.", - "These mobile weapons keep showing up in the city, we gotta take them out as soon as possible." + "These mobile weapons keep showing up in the city,", + "we gotta take them out as soon as possible." ], "bb06win": [ "Another pile of bomb bot scrap metal for the KG", @@ -724,8 +725,10 @@ "You lost an agent! NOT good at all, Jak! Mission failed!" ], "bb07int": [ - "Torn here, I need you to go out and move more of our Agents to new locations in the city.", - "KG spies are watching our every move, so look out for trouble. Good luck." + "Torn here, I need you to go out and move more of our Agents", + "to new locations in the city.", + "KG spies are watching our every move,", + "so look out for trouble. Good luck." ], "bb07win": [ "Nice shuttle work! You're keepin' people alive out there." @@ -737,7 +740,8 @@ "bb08int": [ "Jak, some of our Agents have been compromised again.", "Find each one and take them to special hideouts in the city.", - "The guard patrols are on high alert, so this is going to be a tough one. Keep your head down!" + "The guard patrols are on high alert,", + "so this is going to be a tough one. Keep your head down!" ], "bb08win": [ "That was good driving, Jak.", @@ -4911,10 +4915,10 @@ "Activating security defenses." ], "kg121": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg121a": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg122": [ "I've got civvies in sight." @@ -5689,11 +5693,11 @@ "fighting for the Underground." ], "kg233b": [ - "I'm worried about this new guy fighting for the Underground.", + "I'm worried about this new guy", "fighting for the Underground." ], "kg234": [ - "Yeah, they say he can change into some kind of... monster." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ "Yeah, they say he can change into some kind of monster." @@ -6939,7 +6943,7 @@ ], "prop049": [ "I am disappointed with this city's lack of", - "committment and sacrifice. Work harder! Eat less!", + "commitment and sacrifice. Work harder! Eat less!", "Drink only when I tell you! Sleep is optional.", "We are at war with an outside threat,", "don't make me declare war on you as well!" @@ -6947,13 +6951,14 @@ "prop050": [ "Greetings, people of this wonderful utopia. This year's", "championship race will begin shortly. All citizens", - "not under house arrest are invited to come down to", - "the Stadium and watch your favorite son Erol", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", "once again show how the Krimzon Guard are the elite", - "warriors of this city. Bring the whole family! The first", - "one thousand children will get a mandatory", - "Krimzon Guard recruitment package and be", - "\"asked\" to join the Guard for life, what a treat!" + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ "This is your Baron, I am still in control!", @@ -6984,20 +6989,22 @@ "it would be if the Metal Heads were in charge!" ], "prop054": [ - "We've had a few incidents with our lower class labor", - "force lately. If your Lurker is acting up, call Krimzon", - "Animal Control. Is your Lurker in a tree? Stuck in a", - "sewer grate? Foaming at the mouth? Call", - "the friendly officers of the K.A.C. and they will deal", - "with your furry slave. with all the love and care it", - "deserves... then haul it away for reconditioning.", + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", "Remember, Lurkers can be dangerous!" ], "prop055": [ "Please give generously to the Baron eco fund.", - "Your munificent donation wil be used for a variety", - "of humanitarian needs: bombs, guns, armor, genetic", - "alteration research, all in the name of preserving this", + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", "wonderful city of ours. Give often, give freely...", "or it will be taken from you!" ], @@ -7549,15 +7556,17 @@ "Kiss your shiny butt goodbye!" ], "sigt112": [ - "Born to kill baby!" + "Born to kill, baby!" ], "sigt113": [ "Two to the chest, one to the head." ], "spot004": [ - "Come out and cheer for me as I destroy the competition once again on the track.", - "This year's racing final will be to die for, I guarantee more thrills and more spills.", - "This time I want blood!...Bring the kids." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ "Hey, guys! This is Tess. Before Krew left, I saw him hide", @@ -7566,23 +7575,32 @@ "You might wanna come check it out." ], "tor001": [ - "The operation was a success. All Underground members are safe.", - "Come back to the hideout, I have a new mission for you while we wait for this alert to blow over." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "That should take some heat off the streets. Good work, I couldn't have done it better myself." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "That's it, Jak, you're up! Try not to trigger any alarms, the garrison guards will be tough.", - "Get to the prison cell block and find the prisoners. Once there, we'll turn on the Warp Gate inside to get you all back out. Good luck." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "Ok, my old access codes should help Vin turn off the magnetic seal for the Fortress door." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Jak, this is Torn, the city is under Metal Head attack. There's a large force moving toward the city wall from the ocean.", - "We need people manning the tower gunpods to stop that assault. Meet me at the seaside ocean wall in the Port, hurry!", - "We need every man we can get!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ "Jak, it's a guard roadblock, get out of there!" @@ -7807,8 +7825,8 @@ "Too many of them!! Jak!!! AHHHH!!!" ], "ys001": [ - "Excellent work, boys! Come on back to the Hideout,", - "I have another task for you." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Nice shooting, my boy!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_it-IT.json b/game/assets/jak2/subtitle/subtitle_lines_it-IT.json index 81635d9808..18fdb84f5f 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_it-IT.json +++ b/game/assets/jak2/subtitle/subtitle_lines_it-IT.json @@ -12,8 +12,8 @@ ], "DSbop004": [ "Ooh, è alto!", - "Prova a saltare, e mentre sei in aria datti la spinta per saltare di nuovo", - "dovresti raggiungerlo." + "saltare, e mentre sei in aria datti la spinta per saltare di", + "nuovo, dovresti raggiungerlo." ], "DSbop005": [ "Good job, see? You still got it!" @@ -24,7 +24,7 @@ ], "DSbop007": [ "I don't know where that crazy rift vehicle took us, but...", - "It's some kind of big city!" + "È una specie di grande città!" ], "DSbop008": [ "It's a tough place, Jak. You DO remember", @@ -36,12 +36,12 @@ ], "DSbop010": [ "Ci sono molte casse delle Guardie Kremizi", - "che aspettano di essere aperte. Rompi quella cassa!" + "aspettano di essere aperte. Rompi quella cassa!" ], "DSbop011": [ "Bene! La cassa aveva una scorta di energia all'interno.", "Raccoglila, devi mantenerti in forze, Jak, altrimenti chi combatterà?", - "who'll do the fighting?" + "altrimenti chi combatterà?" ], "DSbop016": [ "Se salti e ti tuffi, la forza con cui cadrai al suolo", @@ -52,337 +52,337 @@ "Guardie, Jak! Fai quello che sai fare meglio!" ], "agnt001": [ - "Hey hey, drive carefully!" + "Ehi, ehi, fai attenzione!" ], "agnt002": [ - "Look out!" + "Attento!" ], "agnt003": [ - "Watch it!" + "Occhio!" ], "agnt004": [ - "Whoa whoa whoa whoa!" + "Uaoh uaoh uaoh uaoh!" ], "agnt005": [ - "Whoa!" + "Uaoh!" ], "agnt006": [ - "You're crazy!" + "Tu sei pazzo!" ], "agnt007": [ - "Are you out of your mind!?" + "Sei fuori di testa!?" ], "agnt008": [ - "Watch out!" + "Attenzione!" ], "agnt009": [ - "That one hurt!" + "Ehi, è pericoloso!" ], "agnt010": [ - "Stay sharp, we've got a tough part of town coming up." + "Attento, stiamo arrivando nella zona più pericolosa della città." ], "agnt011": [ - "Now we're in for it!" + "Ci siamo!" ], "agnt012": [ - "You're wasting citizens!" + "Stai terrorizzando tutti!" ], "agnt013": [ - "Don't hit the civvies, man!" + "Non colpire i cittadini, amico!" ], "agnt014": [ - "Man, you are hitting people!" + "Amico, stai terrorizzando la mia gente!" ], "agnt015": [ - "Look where you're going!" + "Guarda dove vai!" ], "agnt016": [ - "Go man!" + "Vai, amico!" ], "agnt017": [ - "Tieni la testa giù!" + "Giù la testa!" ], "agnt018": [ - "They're shooting at us!" + "Ci stanno sparando!" ], "agnt019": [ - "We are dead if you don't drive faster!" + "Se non guidi più veloce siamo morti!" ], "agnt020": [ - "Keep going!" + "Vai, continua!" ], "agnt021": [ - "Do it, man, do it!" + "Vai, amico, vai!" ], "agnt022": [ - "Sbrigati, amico!" + "Svelto, amico!" ], "agnt023": [ - "I ain't riding on the back, pick up a two-seater!" + "Non voglio stare dietro, prendi un due posti!" ], "agnt024": [ - "Get a bigger car!" + "Prendi un auto più grande!" ], "agnt025": [ "Prendi un veicolo più grande." ], "agnt026": [ - "Get one with two seats, will ya?" + "Trovane una a due posti, ok?" ], "agnt027": [ - "Prendi un altro veicolo." + "Trova un altro veicolo." ], "agnt028": [ - "They're onto us." + "Ci sono dietro." ], "agnt029": [ - "We're being followed." + "Siamo seguiti." ], "agnt030": [ - "We're taking a beating!" + "Stiamo finendo in pezzi!" ], "agnt031": [ - "We can't take much more of that!" + "Non possiamo subire altri colpi!" ], "agnt032": [ "Stai cercando di morire!?" ], "agnt033": [ - "Dove ti ha trovato Torn?" + "Ma dove ti ha trovato Torn?" ], "agnt034": [ - "Sei sicuro di essere dalla nostra parte?" + "Sei sicuro di essere dei nostri?" ], "agnt035": [ - "Turn, TURN!" + "Gira, GIRA!" ], "agnt036": [ - "Good move." + "Bel colpo." ], "agnt037": [ "Morte al Barone!" ], "agnt038": [ - "Thank Mar you're here, Krimzon Guards are everywhere!" + "Grazie a Mar sei qui, le Guardie Kremizi sono ovunque!" ], "agnt039": [ - "It's about time, let's get out of here!" + "Finalmente, andiamo via di qui!" ], "agnt040": [ - "Good, good, just in time. GO, GO, GO!" + "Bene, bene, appena in tempo. VIA, VIA, VIA!" ], "agnt041": [ - "Finally, we need to move!" + "Finalmente, dobbiamo muoverci!" ], "agnt042": [ - "Man, I was beginning to think you wouldn't show up." + "Amico, cominciavo a pensare che non saresti venuto." ], "agnt043": [ - "Not a moment too soon, let's fly!" + "Andiamo, non c'è un secondo da perdere!" ], "agnt044": [ - "Portami al mio nuovo rifugio, presto!" + "Portami al sicuro, alla svelta!" ], "agnt045": [ - "Grazie, buona fortuna!" + "Grazie. Buona fortuna!" ], "agnt046": [ - "Good driving, go save the rest of our guys." + "Ottima guida, vai a salvare gli altri ragazzi." ], "agnt047": [ - "OK, I'm out of here!" + "OK, scendo qui!" ], "agnt048": [ - "See you at the next meeting." + "Ci vediamo al prossimo incontro." ], "agnt049": [ - "Thanks, you're a life saver." + "Grazie, mi hai salvato la pelle." ], "agnt050": [ - "This is where I get off." + "Io scendo qui." ], "agnt051": [ - "I'm glad you're on our side." + "Sono contento che tu sia dei nostri." ], "agnt052": [ - "Ugh!" + "Hah!" ], "agnt053": [ - "Ugh!" + "Agh!" ], "agnt054": [ - "Hah!" + "Uagh!" ], "agnt055": [ "Ahhh!" ], "agnt056": [ - "Drive carefully!" + "Fai attenzione!" ], "agnt057": [ - "Look out!" + "Attento!" ], "agnt058": [ - "Watch it!" + "Occhio!" ], "agnt059": [ - "WHOA!" + "OOH!" ], "agnt060": [ - "You're crazy!" + "Tu sei pazzo!" ], "agnt061": [ - "Are you out of your mind?!" + "Sei fuori di testa?!" ], "agnt062": [ - "Watch out!" + "Attenzione!" ], "agnt063": [ - "That one hurt." + "Ehi, è pericoloso!" ], "agnt064": [ - "Stay sharp, we got a tough part of our town coming up." + "Stiamo arrivando nella zona più pericolosa della città!" ], "agnt065": [ - "Now we're in for it." + "Ora ci siamo." ], "agnt066": [ - "You're wasting citizens!" + "Stai terrorizzando tutti!" ], "agnt067": [ - "Don't hit the civvies, man!" + "Non colpire i cittadini, amico!" ], "agnt068": [ - "Man, you're hitting the people!" + "Stai terrorizzando la mia gente!" ], "agnt069": [ - "Look where you're going!" + "Guarda dove vai!" ], "agnt070": [ - "Go man, GO!" + "Vai, amico!" ], "agnt071": [ - "Keep your head down!" + "Giù la testa!" ], "agnt072": [ - "They're shooting at us!" + "Ci stanno sparando!" ], "agnt073": [ - "We're dead if you don't drive faster!" + "Se non guidi più veloce siamo morti!" ], "agnt074": [ - "Keep going!" + "Vai, continua!" ], "agnt075": [ - "Do it, man, do it!" + "Vai, amico, vai!" ], "agnt076": [ - "Hurry up, man!" + "Svelto, amico!" ], "agnt077": [ - "I ain't riding on the back, pick up a two-seater!" + "Non voglio stare dietro, prendi un due posti!" ], "agnt078": [ - "Get a bigger vehicle." + "Prendi un veicolo più grande." ], "agnt079": [ - "They're onto us!" + "Ci sono addosso!" ], "agnt080": [ - "We're being followed!" + "Ci inseguono!" ], "agnt081": [ - "We're taking a beating!" + "Stiamo finendo in pezzi!" ], "agnt082": [ - "We can't take much more of that." + "Non possiamo subire altri colpi." ], "agnt083": [ - "You trying to die?" + "Vuoi morire, amico?" ], "agnt084": [ - "Where'd Torn find you?" + "Ma Torn, dove ti ha trovato?" ], "agnt085": [ - "You sure you're on our side?" + "Sei sicuro di essere dei nostri?" ], "agnt086": [ - "Turn, TURN!" + "Gira, GIRA!" ], "agnt087": [ - "Good move!" + "Bel colpo!" ], "agnt088": [ - "Death to the Baron!" + "Morte al Barone!" ], "agnt089": [ - "Thank Mar you're here, Krimzon Guards are everywhere!" + "Grazie a Mar sei qui, le Guardie Kremizi sono ovunque!" ], "agnt090": [ - "It's about time, let's get out of here!" + "Finalmente, andiamo via di qui!" ], "agnt091": [ - "Good, just in time, GO, GO, GO!" + "Bene, appena in tempo, VIA, VIA, VIA!" ], "agnt092": [ - "Finally, we need to move!" + "Finalmente, dobbiamo muoverci!" ], "agnt093": [ - "Man, I was beginning to think you wouldn't show up." + "Cominciavo a pensare che non saresti venuto." ], "agnt094": [ - "Not a moment too soon, let's fly!" + "Puntuale come un orologio. Andiamo!" ], "agnt095": [ - "Get me to my new safehouse, quickly!" + "Portami al sicuro, alla svelta!" ], "agnt096": [ - "Thanks, good luck!" + "Grazie, buona fortuna!" ], "agnt097": [ - "Good driving, go save the rest of our guys." + "Ottima guida, vai a salvare gli altri ragazzi." ], "agnt098": [ - "OK, I'm out of here!" + "OK, scendo qui!" ], "agnt099": [ - "See ya at the next meeting!" + "Ci vediamo al prossimo incontro!" ], "agnt100": [ - "Thanks, you're a life-saver." + "Grazie, mi hai salvato la pelle." ], "agnt101": [ - "This is where I get off." + "Io scendo qui." ], "agnt102": [ - "I'm glad you're on our side." + "Sono contento che tu sia dei nostri." ], "agnt103": [ - "Look out!" + "Attento!" ], "agnt104": [ - "Hey!" + "Ehi!" ], "agnt105": [ - "Augh!" + "Gah!" ], "agnt106": [ - "Come on man, you trying to kill me!?" + "Ehi, stai cercando di farmi fuori!?" ], "agnt107": [ - "Take it easy!" + "Calmo, amico!" ], "agnt108": [ - "Ughh!" + "Doooh!" ], "agnt109": [ - "Ughh!" + "Ohhh!" ], "agnt110": [ - "Ahhh!" + "Blaaahhh!" ], "agnt111": [ - "Oof!" + "Uff!" ], "agnt112": [ "Ah!" @@ -391,805 +391,792 @@ "Ahh!" ], "agnt114": [ - "Oof!" + "Uuuh!" ], "agnt115": [ - "Okay, buddy, move!" + "Ok, amico, andiamo!" ], "agnt116": [ - "Look out!" + "Attenzione!" ], "agnt117": [ - "Keep your eyes on the road!" + "Tieni d'occhio la strada!" ], "agnt118": [ - "Watch it!" + "Attento!" ], "agnt119": [ - "Thanks for the lift." + "Grazie per il passaggio." ], "agnt120": [ - "See ya at the next meeting." + "Ci vediamo al prossimo incontro." ], "agnt121": [ - "Right, let's go!" + "Bene, andiamo!" ], "agnt122": [ - "Drive, man, drive!" + "Guida, amico, guida!" ], "agnt123": [ - "That was close!" + "C'è mancato poco!" ], "agnt124": [ - "You sure you know what you're doing?" + "Sei sicuro di sapere quello che fai?" ], "agnt125": [ - "Ok, thanks, good luck." + "Ok, grazie. Buona fortuna." ], "agnt126": [ - "Great, let's go." + "Perfetto, andiamo." ], "agnt127": [ - "Drive, man, drive!" + "Guida, amico, guida!" ], "agnt128": [ - "That was close!" + "C'è mancato poco." ], "agnt129": [ - "You sure you know what you're doing?" + "Sei sicuro di sapere quello che fai?" ], "agnt130": [ - "OK, thanks, good luck!" + "Ok, grazie, buona fortuna!" ], "agnt131": [ - "What took you so long?" + "Perché c'hai messo tanto?" ], "agnt132": [ - "Move like you got a purpose, man!" + "Muoviti come se sapessi cosa fai!" ], "agnt133": [ - "GO, GO, the KG are onto us!" + "Vai, le Guardie Kremizi ci raggiungono!" ], "agnt134": [ - "Stay sharp, we're almost there!" + "Continua così, ci siamo quasi!" ], "agnt135": [ - "Good, you did well, I'll tell the Shadow we're safe!" + "Sei stato grande, avvertirò l'Ombra che siamo salvi!" ], "asha001": [ - "Payback's a bitch, and I'm it." + "Sarà una vendetta spietata, come me." ], "asha002": [ - "Watch your ass, I'm only woman on the outside." + "Guardati le chiappe, sono una donna solo all'apparenza." ], "asha003": [ - "Let me knock you down to size...", - "Not that you have any." + "Lasciati rimpicciolire...", + "Non che tu ne abbia bisogno." ], "asha004": [ - "Small guns don't get me going." + "Le pistole piccole non mi eccitano." ], "asha005": [ - "That's a tiny gun..." + "Che pistola piccola..." ], "asha006": [ - "You don't know who you're dealing with." + "Non sai con chi hai a che fare." ], "asha007": [ - "I never said you could touch me there." + "Non ho mai detto che potessi toccarmi lì." ], "asha008": [ - "Take that!" + "Prendi questo!" ], "asha009": [ - "Here's some." + "Eccone un po'." ], "asha010": [ - "Ready for another?" + "Pronto per un altro?" ], "asha011": [ - "How's that feel?" + "Come ti senti?" ], "asha012": [ - "Seems like it hurts." + "Sembra far male." ], "asha013": [ - "Oh, that hurt." + "Uuh, che male." ], "asha014": [ - "Ugh!" + "Gah!" ], "asha015": [ - "Ough!" + "Goah!" ], "asha016": [ - "Ah!" + "Gah!" ], "asha017": [ "Agh!" ], "asha018": [ - "Hit me again and you'll lose something really valuable!" + "Colpiscimi ancora e perderai qualcosa di prezioso!" ], "asha019": [ - "Not smart!" + "Poco furbo!" ], "asha020": [ - "Listen, buddy, whose side are you on?" + "Ascolta, amico, da che parte stai?" ], "asha021": [ - "Don't make me hurt you." + "Non obbligarmi a farti male." ], "asha022": [ - "Do that again and I'll put you down." + "Fallo di nuovo e ti ridurrò a pezzi." ], "asha023": [ - "Learn to control your gun, buddy." + "Controlla la tua pistola, amico." ], "asha024": [ - "Where'd you learn to fight?" + "Dove hai imparato a combattere?" ], "asha025": [ - "Check your targets, mister." + "Controlla i bersagli, amico." ], "asha026": [ - "Don't do that again." + "Non farlo mai più!" ], "asha027": [ - "Maybe I should be behind you." + "Forse dovrei stare dietro di te." ], "asha028": [ - "I won't take that!" + "Non lo prenderò!" ], "asha029": [ - "Another one like that and you'll be singing soprano." + "Fallo di nuovo e canterai come un soprano." ], "asha030": [ - "Have some back." + "Ciò che è dato è reso." ], "asha031": [ - "Don't do that again!" + "Non farlo di nuovo!" ], "asha032": [ - "Nice shooting." + "Bel colpo." ], "asha033": [ - "Good shooting, blue boy." + "Bel colpo, ragazzo." ], "asha034": [ - "Good work." + "Bel lavoro." ], "asha035": [ - "Take 'em all down!" + "Distruggili tutti!" ], "asha036": [ - "Let's get 'em!" + "Distruggiamoli!" ], "asha037": [ - "Here they come!" + "Eccoli arrivare!" ], "asha038": [ - "I need some help!" + "Ho bisogno d'aiuto!" ], "asha039": [ - "Man, there are a lot of 'em!" + "Ehi, sono veramente molti!" ], "asha040": [ - "More coming." + "Altri in arrivo." ], "asha041": [ - "I got him." + "Ci penso io." ], "asha042": [ - "More firepower!" + "Più potenza di fuoco!" ], "asha043": [ - "One more down!" + "Uno in meno!" ], "asha044": [ - "Help me out!" + "Aiutami!" ], "asha045": [ - "They're out-flanking us!" + "Ci stanno circondando!" ], "asha046": [ - "We're surrounded!" + "Siamo circondati!" ], "asha047": [ - "Shoot! Shoot!" + "Spara! Spara!" ], "asha048": [ - "It's not looking good." + "È una brutta situazione." ], "asha049": [ - "Help me!" + "Aiuto!" ], "asha050": [ - "Here's one for my father!" + "Questo è per mio padre!" ], "asha051": [ - "Damn Metal Heads..." + "Dannate Teste di Metallo..." ], "asha052": [ - "Bullseye." + "Centro!" ], "asha053": [ - "There's some more of those things!" + "Ne stanno arrivando altre!" ], "asha054": [ - "Get 'em all!" + "Distruggile tutte!" ], "asha055": [ "Ugh..." ], "asha056": [ - "Hm-agh..." + "Gah-agh..." ], "asha057": [ - "Hah...agh..." + "Ahh...uh-agh..." ], "asht002": [ - "You were right, Jak. What my father's doing is wrong.", - "I need to help fix this. If you get to the Weapons Factory,", - "maybe we can stop him. I'll meet you there." + "Avevi ragione, Jak. Ciò che sta facendo mio padre è sbagliato.", + "Mi serve il tuo aiuto. Se riesci a entrare nella Fabbrica d'Armi,", + "forse possiamo fermarlo. Ci vediamo là." ], "asht006": [ - "I think now's the time to act.", - "The Metal Heads are so focused on attacking the city,", - "they may have left their nest vulnerable.", - "Jak, you've got to get out to the Wasteland", - "and breach the Nest barrier any way you can.", - "Maybe if you get inside and take out the Metal Head leader", - "the army will collapse. It's a long shot,", - "but it might be our only chance." + "È il momento di agire.", + "Le Teste di Metallo sono concentrate sull'attacco alla città", + "e il loro nido potrebbe essere indifeso.", + "Jak, devi uscire subito dal Deserto", + "e sfondare la barriera del nido a qualunque costo.", + "Se entri e fai fuori il capo delle Teste di Metallo,", + "la loro armata collasserà. È difficile,", + "ma potrebbe essere la nostra unica possibilità." ], "bar001": [ - "Pay no attention to the groundless rumors about", - "low eco supplies. As your Baron, I assure you,", - "the city has an endless supply of eco stores.", - "Those who would say we are running out,", - "are only trying to frighten and subvert!", - "I have everything in control, I command you", - "to have no fear." + "Non ascoltate le voci prive di fondamento sulle", + "limitate scorte di Eco. In qualità di vostro Barone, vi assicuro", + "che la città ha disponibile una quantità infinita di Eco.", + "Chi dice che le nostre scorte si stanno esaurendo,", + "cerca solo di spaventarvi e di portarvi alla ribellione!", + "Ho tutto sotto controllo. Vi ordino", + "di non avere paura." ], "bar004": [ - "Go!" + "Vai!" ], "bb01fail": [ - "I think you should practice more." + "Credo che ti serve altra pratica." ], "bb01int": [ - "Jak, this is Torn. The Underground needs good drivers", - "for our vehicle missions. Prove your skills on the", - "Ring Challenge and maybe we'll let you in on the action." + "Jak, qui è Torn. Il Mondo Sotterraneo ha", + "bisogno di piloti per le missioni con i veicoli.", + "Prova la Sfida dell'Anello e forse ti prenderemo con noi." ], "bb01win": [ - "Not bad, I think we can use ya.", - "Here's a little reward for your effort." + "Non male, penso che tu possa tornarci", + "utile. Questo è una piccola ricompensa." ], "bb02fail": [ - "You're still a little timid. Try again." + "Sei ancora un po' impacciato. Prova di nuovo." ], "bb02int": [ - "We'd like to see you prove your driving skills. Take on", - "another Ring Challenge, let's see what you've got." + "Vorremmo vederti in azione. Prova di nuovo", + "la Sfida dell'Anello e vediamo cosa sai fare." ], "bb02win": [ - "Not bad. You could be my getaway driver any time." + "Non male. Potresti essere il mio pilota per le fughe." ], "bb03fail": [ - "I knew this one would prove too much for ya. Keep practicing." + "Sapevo che questo sarebbe stato troppo per te. Continua a provare." ], "bb03int": [ - "The next Ring Challenge will separate the men from the boys.", - "Let's see if you can handle it." + "La prossima Sfida dell'Anello distinguerà gli uomini dai ragazzi.", + "Vediamo se riuscirai a cavartela." ], "bb03win": [ - "Very nice driving. I'm starting to think you could really", - "help us, Jak." + "Ottima guida. Comincio a pensare che potresti davvero", + "esserci utile, Jak." ], "bb04fail": [ - "Too bad, I kinda hoped you could do this. Keep trying." + "Peccato, eppure speravo ci riuscissi. Continua a provare." ], "bb04int": [ - "Torn here. I don't even know why I'm lettin' you try this", - "Ring Challenge, never beat it myself. I guess I'm morbidly", - "curious. Beat this one and you'll be the best driver", - "the Underground's ever had." + "Parla Torn. Non so nemmeno perché ti faccio provare questa", + "Sfida dell'Anello, forse perché sono curioso. Del resto nemmeno io l'ho mai", + "superata. Supera la prova e sarai il miglior pilota del", + "Mondo Sotterraneo." ], "bb04win": [ - "Very nice, Jak! You're the best driver we've ever had." + "Molto bene, Jak! Sei il miglior pilota che abbia mai avuto." ], "bb05fail": [ - "You didn't get all the Bomb Bots, Jak!" + "Non hai eliminato tutti i bot, Jak!" ], "bb05int": [ - "Jak, reports say more bomb bots are roaming the city.", - "They're a dangerous menace, and I need you to locate", - "and destroy each one before they hurt our interests." + "Jak, i rapporti dicono che altri Bot Esplosivi si aggirano", + "per la città. Sono un pericolo. Devi trovarli", + "e distruggerli tutti prima che facciano danni." ], "bb05win": [ - "Good work! That oughta put a dent in the Baron's war budget." - ], - "bb06int": [ - "Jak, we need you to take out another group of Bomb Bots.", - "These mobile weapons keep showing up in the city, we gotta take them out as soon as possible." + "Ottimo lavoro! Questo darà un bel colpo al budget di guerra del Barone." ], "bb06win": [ - "Another pile of bomb bot scrap metal for the KG", - "trash compactors. Mission accomplished, the Underground's", - "most grateful for your service." + "Un altro ammasso di bot esplosivi in attesa di", + "rottamazione. Missione compiuta, il Mondo Sotterraneo ti ringrazia", + "per il tuo aiuto." ], "bb07fail": [ - "You lost an agent! NOT good at all, Jak! Mission failed!" - ], - "bb07int": [ - "Torn here, I need you to go out and move more of our Agents to new locations in the city.", - "KG spies are watching our every move, so look out for trouble. Good luck." + "Hai perso un agente! Accidenti, Jak! Missione fallita!" ], "bb07win": [ - "Nice shuttle work! You're keepin' people alive out there." + "Ottimo lavoro! Stai impedendo che la gente muoia là fuori." ], "bb08fail": [ - "One of our best agents was arrested. The Shadow will NOT be", - "pleased! You failed." - ], - "bb08int": [ - "Jak, some of our Agents have been compromised again.", - "Find each one and take them to special hideouts in the city.", - "The guard patrols are on high alert, so this is going to be a tough one. Keep your head down!" + "Uno dei nostri migliori agenti è stato arrestato. L'Ombra non sarà", + "contento! Missione fallita." ], "bb08win": [ - "That was good driving, Jak.", - "The Underground can breathe a little easier now." + "Un ottimo lavoro, Jak.", + "Ora il Mondo Sotterraneo può tirare il fiato." ], "bb09fail": [ - "You took too long, Jak. We're calling off the meeting." + "Ci hai messo troppo tempo, Jak. L'incontro è stato annullato." ], "bb09int": [ - "Jak, we're having an Underground meeting", - "with some special Agents. Pick up each Agent", - "and bring them to the meeting place quickly." + "Jak, è previsto un incontro del", + "Mondo Sotterraneo con alcuni dei nostri agenti.", + "Trovali e portali nel luogo stabilito." ], "bb09win": [ - "Fast work, Jak! Some day, we might even", - "invite you to these meetings." + "Sei molto veloce, Jak! Un giorno potremmo addirittura", + "invitarti a uno di questi incontri." ], "bb10fail": [ - "Not fast enough, buddy! You've gotta be quick", - "with those deliveries." + "Non sei stato abbastanza veloce, amico!", + "Devi fare in fretta con le consegne." ], "bb10int": [ - "Jak, you've got to prove your driving skills once again.", - "One of our Agents dropped off a package,", - "I need it delivered to the Hideout. Immediately." + "Jak, devi provare ancora una volta la tua abilità di guida.", + "Uno dei nostri Agenti ha perso un pacchetto, devi", + "consegnarlo subito al Nascondiglio." ], "bb10win": [ - "Good work, Jak!" + "Ottimo lavoro, Jak!" ], "bb11fail": [ - "The package contents didn't make it. Go faster next time!" + "Il contenuto del pacco non ce l'ha fatta. Più veloce la prossima volta!" ], "bb11int": [ - "Jak, I need you to take a package of eco", - "over to the power station. Get there quickly or the contents", - "will be useless to Vin." + "Jak, devi portare un pacco di Eco alla", + "centrale elettrica. Fa' alla svelta o il contenuto diventerà", + "inutile per Vin." ], "bb11win": [ - "Nice driving, Jak." + "Ottima guida, Jak." ], "bb12fail": [ - "You didn't push it hard enough, newbie. Try again." + "Non hai spinto abbastanza sull'acceleratore. Riprova." ], "bb12int": [ - "This is Torn, we've got another package delivery", - "for the Stadium. Make it quick!" + "Parla Torn, abbiamo un'altra consegna per lo", + "Stadio. Fa' alla svelta!" ], "bb12win": [ - "Not bad driving. You really oughta race", - "in the city championship." + "Non male, dovresti gareggiare nel", + "campionato cittadino." ], "bb13fail": [ - "You gotta work on your speed, man." + "Devi lavorare sulla velocità, amico." ], "bb13int": [ - "I need you to take a valuable item over to Onin.", - "You won't be able to drive the whole way,", - "but you still have to move fast. Good luck." + "Devi consegnare un oggetto di valore a Onin.", + "Non potrai guidare per tutta la strada, ma dovrai", + "fare lo stesso alla svelta. Buona fortuna." ], "bb13win": [ - "That's the way to get it done, good work." + "È così che si fa, ottimo lavoro!" ], "bb14fail": [ - "Too late, Jak! The agent is calling it off.", - "You need to reach it faster!" + "Troppo tardi, Jak! L'agente dice che è troppo tardi.", + "Devi raggiungerlo più in fretta!" ], "bb14int": [ - "Jak, we have an Agent waiting for a package delivery.", - "Guard spies are watching this guy,", - "so if you don't get to him fast, he'll be arrested.", - "Take the package to him before it's too late." + "Jak, un nostro Agente aspetta una consegna. Le Guardie lo tengono", + "d'occhio, quindi se non lo raggiungi", + "velocemente, sarà arrestato. Portagli il pacco prima che", + "sia troppo tardi, mi raccomando." ], "bb14win": [ - "Nice work, the delivery was a success. I like your style, Jak." + "Ottimo lavoro, la consegna è stata un successo. Mi piace il tuo stile, Jak." ], "bb15fail": [ - "You screwed up, Jak! You didn't get it to the safe zone", - "as we asked." + "Male, Jak! Non l'hai portata nella zona", + "sicura come ti avevamo chiesto." ], "bb15farr": [ - "Get off the bike and get clear, Jak!!" + "Scendi dalla moto e allontanati, Jak!!" ], "bb15int": [ - "Jak, we found a bomb in the Slums", - "that was meant for the Shadow.", - "I need you to pick it up and take it out to the Farm Area", - "where we've marked a safe zone where it can explode.", - "Go quickly." + "Jak, nei Bassifondi abbiamo trovato", + "una bomba piazzata per l'Ombra.", + "Devi prenderla e portarla nella zona della Fattoria", + "dove c'è un'area sicura per farla esplodere.", + "Fa' presto!" ], "bb15win": [ - "That was amazing work, Jak! Thank you, I really mean that." + "Un lavoro eccezionale, Jak! Grazie...grazie davvero." ], "bb16fail": [ - "You didn't take out enough guards!", - "We need to hit them harder!" + "Non hai eliminato abbastanza guardie,", + "bisogna colpire più duro!" ], "bb16int": [ - "Jak, this is Torn.", - "Erol's elite personal guard are moving through the city.", - "We need to hit them and hit them hard! Take out enough", - "guards before I have to call off the mission.", - "Get too few guards and we'll have missed an opportunity to", - "inflict real damage on our enemies." + "Jak, qui è Torn.", + "Le guardie d'élite di Erol pattugliano la città.", + "Dobbiamo colpirle e colpire duro! Elimina", + "un numero sufficiente di guardie prima che io", + "interrompa la missione. Se non lo fai, perderemo", + "l'opportunità di infliggere seri danni al nemico." ], "bb16win": [ - "Great hit 'n' run, Jak! That'll send a message to Erol." + "Ottima toccata e fuga, Jak! Questo è un bel messaggio per Erol." ], "bb17fail": [ - "Looks like that thing's too hard to use. We'll pass for now." + "Pare che questo aggeggio sia ostico. Per ora meglio lasciar perdere." ], "bb17int": [ - "We're evaluating the new JET-Board for use in Underground", - "missions. We heard you're pretty good with that thing,", - "show us what it can do. Score enough points with the", - "judge-bot and we'll consider adding it to our arsenal." + "Stiamo valutando l'utilizzo del JET-Board in missione.", + "Sappiamo che te la cavi con quell'aggeggio, facci", + "vedere cosa sai fare. Totalizza abbastanza punti con", + "il giudice-bot e valuteremo l'idea di far entrare il JET nel nostro arsenale." ], "bb17win": [ - "Wow! You can really tear up the concrete with that baby!", - "Good work." + "Uau! Bruci davvero l'asfalto con quell'affare!", + "Ottimo lavoro." ], "bb18fail": [ - "I'm still not sure the JET-Board's that useful." + "Non sono ancora sicuro che il JET-Board sia così utile." ], "bb18int": [ - "Here's another great place to evaluate the performance", - "of the JET-Board. Try to get enough points here as well." + "Questo è un altro luogo perfetto per testare il", + "JET-Board. Cerca di totalizzare più punti possibile." ], "bb18win": [ - "Sweet moves, Jak. The KG would have a hard time", - "catching us on those babies." + "Controllo perfetto, Jak. I Kremizi dovranno sudare", + "per prenderci su questi aggeggi." ], "bb19fail": [ - "You didn't get them all. Try again." + "Non li hai raccolti tutti. Prova di nuovo." ], "bb19int": [ - "We're evaluating the use of homing beacons in missions.", - "Get all of the beacons as fast as you can.", - "You gotta move quickly on this one." + "Stiamo valutando l'uso in missione di segnalatori a", + "ricerca. Raccogli tutti i segnalatori prima possibile.", + "Questa volta dovrai agire velocemente." ], "bb19win": [ - "Excellent work. You're a great asset", - "to the Underground, Jak." + "Bel lavoro. Sei un elemento", + "fondamentale per il Mondo Sotterraneo." ], "bb20fail": [ - "Too slow, Jak! When the Shadow asks, you need to deliver." + "Troppo lento, Jak! Quando l'Ombra chiede, tu devi scattare!" ], "bb20int": [ - "The Shadow needs you to collect some green eco for his", - "experiments. Get all of it before the eco vanishes." + "L'Ombra vuole che tu raccolga dell'Eco verde per i", + "suoi esperimenti. Raccoglilo tutto prima che svanisca." ], "bb20win": [ - "Not bad. I'll put in a good word with the Shadow." + "Non male, Jak. Metterò una buona parola per te con l'Ombra." ], "bb21fail": [ - "Keep tryin'. You need to develop your skills here." + "Continua a provare, devi migliorare ancora." ], "bb21int": [ - "Sometimes we like to \"borrow\" Krimzon Guard", - "equipment. Take that KG patrol bike out for a spin", - "and hit all the targets within the time limit." + "Ogni tanto ci piace \"prendere in prestito\"", + "l'equipaggiamento delle Guardie Kremizi. Prendi la moto della pattuglia e", + "colpisci tutti i bersagli nel tempo limite." ], "bb21win": [ - "Nice shooting. The Guard would looove you as a recruit.", - "Here's a little reward to stay with us instead." + "Bel colpo. Le guardie pagherebbero per averti come recluta,", + "ma eccoti una piccola ricompensa per farti stare con noi." ], "bb22fail": [ - "You didn't get the booths fast enough, Jak." + "Non hai eliminato i chioschi in tempo, Jak!" ], "bb22int": [ - "Some of the Baron's propaganda is unnerving", - "the civilians. Take out those booths and we'll stop Praxis", - "from spreading his lies." + "La propaganda del Barone sta mettendo ad una prova", + "i cittadini. Elimina quei chioschi e fermeremo le menzogne", + "di Praxis." ], "bb22win": [ - "Good work! That should shut up the Baron a bit." + "Bel lavoro! Questo dovrebbe zittire il Barone per qualche tempo." ], "bb23fail": [ - "You lost, Jak. If you wanna win,", - "you better work on your speed skills." + "Hai perso, Jak. Se vuoi vincere,", + "devi lavorare sulla velocità!" ], "bb23int": [ - "The Underground's top racer wants to challenge you", - "to a race on Ring Course One.", - "Think you can handle a little competition?" + "Il miglior pilota del Mondo Sotterraneo", + "vuole sfidarti sul Percorso ad", + "Anello Uno. Ti andrebbe una sfida?" ], "bb23win": [ - "Congratulations! You beat the challenger!" + "Congratulazioni! Hai sconfitto lo sfidante!" ], "bb24fail": [ - "Our boy took you on this one. Better luck next time." + "Il nostro pilota ti ha battuto. Andrà meglio alla prossima." ], "bb24int": [ - "Up for a little race, Jak?", - "Our top driver wants to face you on Ring Course Two.", - "This baby's a little more difficult.", - "Let's see if you can rise to the challenge." + "Pronto per una piccola gara, Jak?", + "Il nostro pilota migliore vuole sfidarti sul", + "Percorso ad Anello Due. Questa volta sarà più", + "difficile. Vediamo cosa riesci a fare." ], "bb24win": [ - "You beat him, Jak. Nice driving." + "L'hai battuto, Jak. Grande prova." ], "bb25fail": [ - "Looks like you're not the top racer in this town, Jak.", - "You lost!" + "Sembra che tu non sia il miglior pilota della città, Jak.", + "Hai perso!" ], "bb25int": [ - "The Underground's race champion wants at you again,", - "this time on the difficult Ring Course Three.", - "This one's gonna get hairy." + "Il campione del Mondo Sotterraneo vuole ancora te.", + "La sfida è sul difficile Percorso ad Anello Tre,", + "stavolta ci vorrà tutta la tua abilità." ], "bb25win": [ - "Congratulations, you beat our best racer. Well done." + "Congratulazioni, hai battuto il nostro campione. Ben fatto." ], "bb26int": [ - "This is Torn, a good Underground agent knows the city", - "inside and out, by sight. Let's see how you stack up,", - "get to this place in the time limit given", - "and you'll get a reward. GO!" + "Parla Torn. Un buon agente del Mondo Sotterraneo", + "conosce la città come le sue tasche, Jak. Raggiungi questo", + "luogo nel tempo limite e otterrai una", + "una ricompensa. Ora va'!" ], "bb27int": [ - "Here's another chance to prove your knowledge of the city." + "Hai un'altra chance per dimostrare che conosci la città." ], "bb28int": [ - "Find this place before time runs out." + "Trova questo luogo prima che scada il tempo!" ], "bb29int": [ - "Here's a tough one, beat the clock to here." + "Questa volta sarà dura, raggiungi il luogo in tempo." ], "bb30int": [ - "Recognize this place? Find it fast and a reward is yours." + "Riconosci questo posto? Trovalo in fretta per avere una ricompensa." ], "bb31int": [ - "Here's a little known place, find it fast and I'll be impressed." + "Questo è un posto poco conosciuto. Se vuoi stupirmi, trovalo alla svelta." ], "bb32int": [ - "I'd like to see you find this place. Impress me, Jak." + "Voglio vedere se riesci a trovare questo posto. Stupiscimi, Jak!" ], "bb33int": [ - "Get here fast and surprise me." + "Arriva qui alla svelta e sorprendimi." ], "bb34int": [ - "Here's another destination, get here quickly." + "Ecco un'altra destinazione, raggiungila." ], "bb35int": [ - "Find this spot, fast!" + "Trova questo luogo, subito!" ], "bb36int": [ - "Reach this area and be rewarded." + "Raggiungi quest'area e avrai una ricompensa." ], "bb37int": [ - "Think you can find this place?" + "Credi di poter trovare questo posto?" ], "bb38fail": [ - "Not so good, Jak! Maybe you should calibrate that board." + "Non va bene, Jak! Forse dovresti ricalibrare quella tavola." ], "bb38int": [ - "We're still evaluating the JET-Board.", - "Let's see if you can collect all of the energy boosts", - "in the time limit allotted." + "Stiamo ancora valutando l'uso del", + "JET-Board. Vediamo se raccogli tutti i nuclei", + "di energia nel tempo limite." ], "bb38win": [ - "Nice moves, fly-boy." + "Ottima guida, ragazzo." ], "bb39fail": [ - "Soo close, but in this business that means dead." + "Quasi, ma in questo lavoro, \"quasi\" significa essere morti." ], "bb39int": [ - "Take that JET-Board through its paces on a Ring Course.", - "Beat the time and I'll get your face tattooed like mine." + "Prova il JET-Board sul Percorso ad Anello. Migliora il", + "tempo record e ti farò tatuare la faccia come la mia." ], "bb39win": [ - "Good speed through the course, Jak!", - "That one looked too easy." + "Hai tenuto una buona media, Jak!", + "Forse era un circuito troppo semplice." ], "bb40fail": [ - "Looks like you've met your match, Jak!", - "You were too slow on that course." + "Pare non sia andata bene, Jak. Sei stato", + "troppo lento su questo tracciato." ], "bb40int": [ - "I'd like to see you take the JET-Board through another", - "Ring Course. We'll make this one a little more interesting,", - "let's see if you can complete it in time." + "Vorrei che provassi il JET-Board su un altro", + "Percorso ad Anello. Rendiamo la cosa più interessante, vediamo se", + "riesci a completare il giro nel tempo limite." ], "bb40win": [ - "Wow! Even I'd have trouble on that one, good job!" + "Wow! Nemmeno io avrei fatto di meglio, bel lavoro!" ], "bf001": [ - "My shield is impervious to your attacks!" + "Il mio scudo è impermeabile ai tuoi attacchi!" ], "bf002": [ - "You cannot hurt me!" + "Non puoi ferirmi!" ], "bf003": [ - "Fool! Nothing can touch me!" + "Pazzo! Nulla può toccarmi!" ], "bf004": [ - "You're powerless!" + "Sei impotente!" ], "bf005": [ - "There is nothing you can do!" + "Non puoi fare nulla!" ], "bf006": [ - "HAHAHAHAHAHA!" + "AHAHAHAHAHAHAHAHAH!" ], "bf007": [ - "HAHAHAHA!" + "AHAHAHAH!" ], "bf008": [ - "Come get me!" + "Prendimi!" ], "bf009": [ - "Come closer!" + "Avvicinati!" ], "bf010": [ - "Try me now!" + "Prova ora!" ], "bf011": [ - "Let's make this personal!" + "Andiamo sul personale!" ], "bf012": [ - "Surprise!" + "Sorpresa!" ], "bf013": [ - "Don't fall!" + "Non cadere!" ], "bf014": [ - "I will crush you!" + "Ti distruggerò!" ], "bf015": [ - "Take this!" + "Prendi questo!" ], "bf016": [ - "Here I come!" + "Eccomi qua!" ], "bf017": [ - "Why won't you die?!" + "Perché non muori?!" ], "bf018": [ - "Your Dark Eco powers surprise me!" + "I poteri dell'eco oscuro mi sorprendono!" ], "bf019": [ - "Your arrogance will be your downfall!" + "La tua arroganza ti sarà letale!" ], "bf020": [ - "The Stone is mine!" + "La Pietra è mia!" ], "bf021": [ - "Give me the Stone!" + "Dammi la Pietra!" ], "bf022": [ - "Release it!" + "Lasciala!" ], "bf023": [ - "I want the Stone!" + "Voglio la Pietra!" ], "bf024": [ - "Argh, let go!" + "Aaarrrgh...lasciala!" ], "bf025": [ - "It's mine!" + "È mia!" ], "bf026": [ - "Try these on for size!" + "Prova questi." ], "bf027": [ - "Here's a little present!" + "Ecco un piccolo regalo!" ], "bf028": [ - "Want some more?" + "Ne vuoi ancora?" ], "bf029": [ - "I grow tired of this, now you die!" + "Mi sto stancando. Ora morirai!" ], "bf030": [ - "You cannot run away from these!" + "Non riuscirai mai a sfuggirgli!" ], "bf031": [ - "Allow me to share the pain!" + "Lasciami condividere il dolore!" ], "bf032": [ - "Now you're mine!" + "Ora sei mio!" ], "bf033": [ - "Here's some hell!" + "Eccoti all'inferno!" ], "bf034": [ - "Say good night!" + "Augura la buona notte." ], "bf035": [ - "Enjoy your next life!" + "Inizia un'altra vita!" ], "bf036": [ - "It's over!" + "È finita!" ], "bf037": [ - "Burn in hell!" + "Brucia all'inferno!" ], "bf038": [ - "The Stone is mine! Let me show you what it can do!" + "La Pietra è mia! Lascia che ti mostri cosa può fare!" ], "bf039": [ - "Now you see the Stone's power in capable hands!" + "Ora vedrai cosa può fare la Pietra nelle giuste mani!" ], "bf040": [ - "How's that for power?" + "Che ne dici?" ], "bf041": [ - "Now you see!" + "Ora vedrai!" ], "bf042": [ - "I am invincible now!" + "Ora sono invincibile!" ], "bf043": [ - "You cannot run forever!" + "Non puoi correre per sempre!" ], "bf044": [ - "I have all the power I need!" + "Ho tutto il potere che mi serve!" ], "bf045": [ - "You can't avoid this!" + "Non puoi evitarlo!" ], "bf046": [ - "Here's a little something special!" + "Ecco qualcosa di speciale!" ], "bf047": [ - "Come to me!" + "Vieni da me!" ], "bf048": [ - "Come here!" + "Vieni qui!" ], "bf049": [ - "Let's get closer!" + "Avvicinati!" ], "bf050": [ - "Nothing can save you now!" + "Ora nulla può salvarti!" ], "bf051": [ - "You're history!" + "Sei storia!" ], "bf052": [ - "I am the city's savior, not you!" + "Io sono il salvatore della città, non tu!" ], "bf053": [ - "Die!" + "Muori!" ], "bf054": [ - "It's over!" + "È finita!" ], "bf055": [ - "I've got you!" + "Ti ho preso!" ], "bf056": [ - "Now you die!" + "Ora morirai!" ], "bf057": [ "NOOOOOO!" @@ -1198,133 +1185,133 @@ "No!" ], "bf059": [ - "NO!" + "No!" ], "bf060": [ - "Uorghh!" + "Uooorrghh!" ], "bf061": [ - "Ahh!" + "Aah!" ], "bf062": [ - "Ungh!" + "Ouh!" ], "bf063": [ "Raghh!" ], "bf064": [ - "We finish this now!" + "Ora facciamola finita!" ], "bf065": [ - "Eat this!" + "Prendi questo!" ], "bf066": [ "Stop!" ], "bf067": [ - "You idiot, you're no match for me!" + "Idiota, non puoi competere con me!" ], "bf068": [ - "Why don't you die!?" + "Perché non muori!?" ], "bf069": [ - "Give up and I'll make it painless!" + "Arrenditi e non ti farò soffrire!" ], "bf070": [ - "You cannot win!" + "Non puoi vincere!" ], "bf071": [ "Aha!" ], "bf072": [ - "Haha!" + "Aha!" ], "bf073": [ "AH!" ], "bf074": [ - "Urgh!" + "Uoh!" ], "bf075": [ - "You can do better than that!" + "Puoi fare di meglio!" ], "bf076": [ - "You're mine!" + "Sei mio!" ], "bf077": [ - "Why won't you die!?" + "Perché non muori!?" ], "bf078": [ - "I have the ultimate power!" + "Il mio potere è infinito!" ], "bf079": [ - "Die!" + "Muori!" ], "bf080": [ - "Is that your best shot?" + "È il tuo colpo migliore?" ], "bf081": [ - "Now you die!" + "Ora morirai!" ], "bf082": [ - "Get off my tower!" + "Via dalla mia torre!" ], "bf083": [ - "We'll see about that!" + "Vedremo come te la cavi!" ], "bf084": [ - "You really think you have a chance?" + "Pensi davvero di avere una possibilità?" ], "bf085": [ - "Fear me!" + "Trema." ], "bf086": [ - "You're nothing!" + "Non sei nessuno!" ], "bf087": [ - "My shield is now recharged!" + "Il mio scudo è di nuovo carico!" ], "bf088": [ - "Try these on for size!" + "Prova questi!" ], "bf089": [ - "I should have killed you long ago!" + "Dovevo eliminarti molto tempo fa!" ], "bf090": [ - "Never a dull moment, eh?" + "Mai un attimo di distrazione, eh?" ], "bf091": [ - "Stand still!" + "Fermo lì!" ], "bf092": [ - "Go back to wherever you came from!" + "Torna da dove sei venuto!" ], "bf093": [ - "You're both going to die by my hand!" + "Morirete entrambi per mano mia!" ], "bf094": [ - "Come closer!" + "Più vicino!" ], "bf095": [ - "To the end!" + "Fino alla fine!" ], "bf096": [ - "You cannot win!" + "Non puoi vincere!" ], "bf097": [ - "Come here!" + "Vieni qui!" ], "bf098": [ - "ARGHHH!" + "ARGH!" ], "bf099": [ - "URGHH!" + "OOOH!" ], "bf100": [ - "Urgh!" + "Ouuuh!" ], "bf101": [ - "Oof!" + "Uuuh!" ], "bf102": [ "Noooo!" @@ -1333,193 +1320,193 @@ "No!" ], "bf104": [ - "Not again!" + "Di nuovo?" ], "bf105": [ - "It can't be!" + "Non può essere!" ], "bf106": [ - "Not this time!" + "Un'altra volta!" ], "bf107": [ - "Stop!" + "Fermo!" ], "bf108": [ - "Damn!" + "Maledizione!" ], "bf109": [ - "Why, you little...!" + "Tu, piccolo...!" ], "bf110": [ - "Now you've made me angry!" + "Ora hai scatenato la mia ira!" ], "bf111": [ - "Impressive, but let's try that again!" + "Notevole, ma prova di nuovo!" ], "bf112": [ - "The stronger man always wins!" + "È sempre il più forte a vincere." ], "bf113": [ - "Your loss was inevitable, Jak!" + "La tua sconfitta era inevitabile." ], "bf114": [ - "You could never be a baron!" + "Non potrai mai essere un barone!" ], "bf115": [ - "I knew you were weak!" + "Sapevo che eri un debole." ], "bf116": [ - "Hm, I expected more from you!" + "Hm, mi aspettavo di più da te." ], "bf117": [ - "Losing is for the weak!" + "La sconfitta è per i deboli!" ], "bf118": [ - "How pathetic!" + "Patetico!" ], "bf119": [ - "That was too easy!" + "Davvero troppo facile!" ], "bf120": [ - "Sorry, old boy, it's just war!" + "Mi dispiace, ragazzo, è la guerra." ], "bf121": [ - "Too bad you don't have what it takes!" + "Peccato che tu non valga niente!" ], "bf122": [ - "The better man won!" + "Ha vinto il migliore." ], "bf123": [ - "We're similar, Jak... oh, except you're dead!" + "Siamo simili, Jak...oh, a parte per il fatto che tu sei morto." ], "bf124": [ - "Feel the fury of the Precursor Stone!" + "Assapora la furia della Pietra del Precursor!" ], "bf125": [ - "With the Stone's power, I am invincible!" + "Con i poteri della Pietra, sono invincibile!" ], "bf126": [ - "All will fear me now!" + "Tutti ora mi temeranno!" ], "bf127": [ - "Time to die!" + "È tempo di morire." ], "bf128": [ - "My little friends will take care of you!" + "I miei piccoli amici avranno cura di te!" ], "bf129": [ - "You can't run forever, Jak!" + "Non puoi fuggire per sempre, Jak!" ], "bf130": [ - "Now I've got you!" + "Ora sei mio..." ], "bf131": [ - "Surprise!" + "Sorpresa!" ], "bf132": [ - "I have better things to do than waste my time with you!" + "Ho cose migliori da fare che perdere il mio tempo con te." ], "bf133": [ - "You are nothing!" + "Non sei niente." ], "bf134": [ - "Annoying insect, die!" + "Fastidioso insetto, muori!" ], "bf135": [ - "Not bad, but let me show you what real power is!" + "Non male, ma lascia che io ti mostri la vera potenza!" ], "bf136": [ - "Feel this!" + "Prendi questo!" ], "bru001": [ - "Great smelly breath of a goosesnake!", - "Heroes to Lurker people you be!", - "By now just see much happy thanks! Ruhuhuh.", - "You honorary members of Lurker tribe now.", - "We no forget - if ever you need us, we help you!" + "Per l'alito puzzolente di un serpente!", + "Eroi per popolo Lurker voi sarete!", + "Noi molto grati siamo a voi! Uhuhuh.", + "Ora voi membri onorari di tribù Lurker.", + "Noi no dimenticare - se a voi servire, noi aiutare!" ], "bru002": [ - "I hears you two look for a piece of Mar's shiny Seal.", - "Brutter loves shiny bright things too.", - "I have piece I thinks. It in Water Slums,", - "hanging over me hut and you free to have.", - "Gift from Brutter!" + "Ho sentito voi due cercare un pezzo di Sigillo luccicante di Mar.", + "Anche a Brutter piacere cose luccicanti.", + "Io credere di avere pezzo. Essere i Bassifondi Marini,", + "appeso su mia capanna. Voi liberi di prendere.", + "Regalo di Brutter!" ], "bru004": [ - "You two good! No better warrior in all Lurker tribes!", - "You keep Seal. You love shiny things just like Brutter." + "Tu essere bravo! No guerriero migliore in tutte tribù Lurker!", + "Tu tenere Sigillo. A te piacere cose luccicanti, proprio come a Brutter." ], "cit001": [ - "Hey!" + "Ehi!" ], "cit004": [ - "Watch it!" + "Attento!" ], "cit008": [ "No!" ], "cit010": [ - "Argh!" + "Aaah!" ], "cit016": [ - "Stay away!" + "Sta' lontano!" ], "cit033": [ - "Hey!" + "Ehi!" ], "cit034": [ - "Look out!" + "Attenzione!" ], "cit035": [ - "Watch out!" + "Attento!" ], "cit046": [ - "Go away!" + "Va' via!" ], "cit047": [ - "Leave me alone!" + "Lasciami da solo!" ], "cit051": [ - "Are you crazy?" + "Sei pazzo?!" ], "cit053": [ - "Are you insane?!" + "Sei matto?" ], "cit055": [ - "Hey, that's my vehicle!" + "Ehi, quello è il mio veicolo!" ], "cit056": [ - "Gimme back my vehicle!" + "Ridammi il mio veicolo!" ], "cit057": [ - "What are you doing?" + "Cosa stai facendo?" ], "cit058": [ - "Please, don't take it!" + "Per favore, non prenderlo!" ], "cit097": [ - "Ugh!" + "Gaaaaah!" ], "cit097a": [ - "Aahh!" + "Aaah!" ], "cit097b": [ - "Aaghhh!" + "Gaaaaaah!" ], "cit097c": [ - "AAAHHH!!" + "Ahh!" ], "cit097d": [ "AAHHH!" ], "cit098": [ - "Ahh!!" + "Ugh!" ], "cit098a": [ - "Urgh!" + "Ugh!" ], "cit098b": [ - "Ugh!" + "Uha!" ], "cit098c": [ "Ugh!" @@ -1531,7 +1518,7 @@ "No!" ], "cit099a": [ - "Noooo!" + "No!" ], "cit099b": [ "No!" @@ -1540,214 +1527,214 @@ "No!" ], "cit099d": [ - "Nooo!" + "No!" ], "cit100": [ - "Please!" + "Per favore!" ], "cit100a": [ - "Please!" + "Per favore!" ], "cit100b": [ - "Please!" + "Per favore!" ], "cit100c": [ - "Please!" + "Per favore!" ], "cit101": [ - "Stop!" + "Fermo!" ], "cit101a": [ - "Stop!" + "Fermo!" ], "cit101b": [ - "Stop!" + "Fermo!" ], "cit101c": [ - "Stop!" + "Fermo!" ], "cit103": [ - "Sound the alarm!" + "Suonate l'allarme!" ], "cit103a": [ - "Sound the alarm!" + "Suonate l'allarme!" ], "cit104": [ - "Guards!" + "Guardie!" ], "cit104a": [ - "Guards! Help us!" + "Guardie!" ], "cit105": [ - "Help us!" + "Aiuto!" ], "cit120": [ - "Keep away from me!" + "Stai lontano da me!" ], "cit120a": [ - "Keep away from me!" + "Stai lontano da me!" ], "cit137a": [ - "Wait!" + "Aspetta!" ], "cityv001": [ - "Leaving city safe zone." + "Esci dalla zona di sicurezza." ], "cityv002": [ - "Leaving city at your own risk." + "Esci dalla città a tuo rischio." ], "cityv003": [ - "Exiting city." + "Esci dalla città." ], "cityv004": [ - "Opening outer shield." + "Apri scudi esterni." ], "cityv005": [ - "Decontamination complete." + "Fine decontaminazione." ], "cityv006": [ - "Entering Haven City." + "Ingresso Città Rifugio." ], "cityv007": [ "Rientro in città." ], "cityv008": [ - "Welcome back." + "Bentornato." ], "cityv009": [ - "It's good to see you still alive." + "È un piacere rivederti." ], "cityv010": [ - "Security clearance granted." + "Concesso autorizzazione sicurezza." ], "cityv011": [ - "Entrance denied. You do not have proper clearance." + "Accesso negato. Non hai l'autorizzazione." ], "cityv012": [ - "I am unable to comply." + "Richiesta inaccettabile." ], "cityv013": [ - "Please come back with proper clearance." + "Torna con l'adeguata autorizzazione." ], "cityv014": [ - "Access denied." + "Accesso negato." ], "cityv015": [ - "You need Red Clearance for this gate." + "Ti serve un'autorizzazione rossa per questo portale." ], "cityv016": [ - "You need Green Clearance for this gate." + "Ti serve un'autorizzazione verde per questo portale." ], "cityv017": [ - "You need Yellow Clearance for this gate." + "Ti serve un'autorizzazione gialla per questo portale." ], "cityv018": [ - "You need Blue Clearance for this gate." + "Ti serve un'autorizzazione blu per questo portale." ], "cityv019": [ - "You need Purple Clearance for this gate." + "Ti serve un'autorizzazione viola per questo portale." ], "cityv020": [ - "You need special Black Clearance for this door." + "Per questo portale: autorizzazione speciale nera." ], "cityv021": [ - "Access granted." + "Accesso consentito." ], "cityv022": [ - "Door open." + "Porta aperta." ], "cityv023": [ - "Door closed." + "Porta chiusa." ], "cityv024": [ - "Please enter." + "Entra, prego." ], "cityv025": [ - "Warp Gate online." + "Portale Temporale online." ], "cityv026": [ - "Warning: Eco supplies low." + "Attenzione: rifornimenti Eco ridotti." ], "cityv027": [ - "Backup systems failing." + "Errore nel sistema di backup." ], "cityv028": [ - "Warning: Eco storage is below safe minimums." + "Attenzione: rifornimenti d'Eco sotto i minimi di sicurezza." ], "cityv029": [ - "Eco Grid unstable." + "Griglia dell'eco instabile." ], "cityv030": [ - "Metal Heads detected at Mining Site." + "Teste di Metallo al Sito Minerario." ], "cityv031": [ - "Metal Heads detected at Drilling Site." + "Teste di Metallo al Sito di Scavo." ], "cityv032": [ - "Stand by for clearance." + "Attendere autorizzazione." ], "cityv033": [ - "Have a nice day." + "Buona giornata." ], "cityv034": [ - "Welcome." + "Benvenuto." ], "cityv035": [ - "This is a restricted area." + "Zona d'accesso limitato." ], "cityv036": [ - "You are in violation of Speed Ordinance 51d, pull over." + "Stai violando la legge 51-D sulla velocità. Rallenta." ], "cityv037": [ - "I have alerted the authorities." + "Ho avvertito le autorità." ], "cityv038": [ - "This sector is closed." + "Questo settore è chiuso." ], "cityv039": [ "Allarme: evasione in corso." ], "cityv040": [ - "Alert: City under attack." + "Allarme: città sotto attacco." ], "cityv041": [ - "Metal Head attack in progress." + "Attacco Teste di Metallo in corso." ], "cityv042": [ - "All citizens go to safe shelters." + "Tutti i cittadini: nei rifugi." ], "cityv043": [ - "Eco Grid growing unstable." + "Instabilità nella griglia dell'eco." ], "cityv044": [ - "The Eco Grid is down. Repeat: The Eco Grid is down." + "Griglia dell'eco spenta. Ripeto: griglia dell'eco spenta." ], "cityv045": [ - "Red alert: City shield wall compromised." + "Codice rosso: scudo della città danneggiato." ], "cityv046": [ - "Unauthorized movement in sewer system." + "Movimento non autorizzato nella rete fognaria." ], "cityv047": [ - "This is a restricted area. Defenses activated." + "Zona d'accesso limitato. Difese attivate." ], "cityv048": [ - "You are trespassing. Defenses coming online." + "Accesso vietato. Attivazione difese." ], "cityv049": [ - "I regret use of force. Systems arming." + "Mi dispiace utilizzare la forza. Armare il sistema." ], "cityv050": [ - "Trespasser neutralized." + "Intruso neutralizzato." ], "cityv051": [ - "Suspect destroyed." + "Sospetto distrutto." ], "cityv052": [ - "I am authorized to use force." + "Sono autorizzato a usare la forza." ], "cityv053": [ - "General alert: Riot in progress. Krimzon Guards en route." + "Allarme generale: rivolta in corso. Guardie Kremizi in arrivo." ], "cityv054": [ "Arrenditi. Sei in arresto." @@ -1762,326 +1749,326 @@ "Sei in arresto. Arrenditi." ], "cityv058": [ - "This sector is off limits." + "Questo settore è off limit." ], "cityv061": [ - "All systems back online and in the green." + "Sistema di nuovo online, codice verde." ], "cityv062": [ - "The race is about to begin." + "La corsa sta per iniziare." ], "cityv063": [ "Benvenuto nel sistema di trasporti cittadino." ], "cityv064": [ - "You can thrust in your vehicle at any time." + "Puoi aumentare la velocità del tuo veicolo se vuoi." ], "cityv065": [ - "Braking will assist in vehicle control." + "La frenata ti aiuterà a controllare il veicolo." ], "cityv067": [ - "Backing up is easy." + "Arretrare è semplice." ], "cityv068": [ - "You can hover in one of two zones: low and high." + "Puoi fluttuare in due zone: in alto e in basso." ], "cityv069": [ - "Try switching hover zones." + "Prova a cambiare la zona in cui fluttui." ], "cityv070": [ - "Switching hover zones may help avoid traffic or", - "ground obstacles." + "Cambiando la zona in cui stai fluttuando eviti", + "il traffico o gli ostacoli." ], "cityv075": [ - "Alert: Vehicle destruction imminent." + "Allarme: distruzione veicolo imminente." ], "cityv076": [ - "Please drive more carefully next time." + "La prossima volta guida con più attenzione." ], "cityv077": [ - "Thank you for using the vehicle." + "Grazie per aver usato il veicolo." ], "cityv078": [ - "Have a nice day." + "Buona giornata." ], "cityv079": [ - "Warning: Missile cooling systems damaged." + "Attenzione: danni al sistema di raffreddamento missile." ], "cityv080": [ - "Alert: Backup cooling system failure.", - "Emergency overrides initiated." + "Attenzione: errore nel backup del sistema di raffreddamento.", + "Iniziare manovra d'emergenza." ], "cityv081": [ - "Missile systems at critical overload.", - "Failsafe not responding." + "Sovraccarico critico al sistema dei missili.", + "Il sistema di sicurezza non risponde." ], "cityv082": [ - "Danger: Warhead detonation imminent.", - "Evacuate immediately." + "Pericolo: detonazione imminente della testata di guerra.", + "Evacuare subito." ], "cityv087": [ - "Arriving at Throne Room floor." + "Trasferimento al piano della Stanza del Trono." ], "cityv088": [ - "Arriving at ground floor." + "Trasferimento al piano terra." ], "cityv093": [ - "You have been sentenced to termination." + "È stata decisa la tua morte." ], "cityv094": [ - "This area is restricted.", - "Initiating termination with extreme prejudice." + "Quest'area è ad accesso limitato,", + "avvio eliminazione con estrema cautela." ], "cityv095": [ - "This area open to Krimzon Guard personnel only." + "Area accessibile solo al personale delle Guardie Kremizi." ], "cityv096": [ - "The city is on high alert." + "La città è in stato di allerta." ], "cityv097": [ - "The city is under attack.", - "All citizens proceed to safe shelters." + "La città è sotto attacco.", + "Tutti i cittadini si rechino nei rifugi." ], "cityv098": [ - "The city is under attack. Please stay in your homes." + "La città è sotto attacco. Restate nelle vostre case." ], "cityv099": [ - "Metal Head aggressors are infiltrating the system." + "Le Teste di Metallo si stanno infiltrando nel sistema." ], "cityv100": [ - "Congratulations on receiving a Security Pass." + "Congratulazioni, hai ricevuto un Lasciapassare di Sicurezza." ], "cityv107": [ - "Unauthorized use of Fortress door.", - "Activating security tank." + "Uso non autorizzato porte Fortezza,", + "tirato carro difensivo." ], "cityv108": [ - "Gunpod weapons coming online." + "Cannone online." ], "cityv109": [ - "Weapons overheating." + "Armi surriscaldate." ], "cityv110": [ - "Weapons inoperative. Please wait for cooling." + "Armi non operative. Attendere il raffreddamento." ], "cityv111": [ - "Weapons back online." + "Armi di nuovo online." ], "cityv112": [ - "The gunpod has taken severe damage." + "Il cannone ha subito ingenti danni." ], "cityv130": [ - "La mappa della città è mostrata in basso a destra." + "Mappa città riprodotta in basso a destra." ], "cityv132": [ "Segui le icone sulla mappa", "per raggiungere luoghi importanti." ], "cityv134": [ - "Intruder alert." + "Allarme intruso." ], "cityv135": [ - "Stand by." + "Fermo." ], "cityv146": [ - "I'm experiencing a circuit overload.", - "Turn on my bypass switches within the time limit", - "and you will be rewarded." + "Sto rilevando un sovraccarico dei circuiti.", + "Attiva gli interruttori di deviazione nel tempo limite,", + "otterrai una ricompensa." ], "cityv147": [ - "You failed to turn on the bypass grid in time.", - "My C-Zone circuits have overloaded." + "Attivazione della griglia di deviazione riuscita.", + "Ecco una ricompensa." ], "cityv148": [ - "You successfully switched on the bypass", - "for my circuits in time.", - "Here is a reward." + "Attivazione della griglia di deviazione", + "riuscita. Ecco una", + "ricompensa." ], "cityv149": [ - "I need emergency power for my Eco Converters.", - "Switch on all available circuits quickly", - "to stabilize the Eco Grid." + "Richiedo energia ausiliaria per i Convertitori di Eco.", + "Attiva circuiti disponibili", + "per stabilizzare la Griglia." ], "cityv150": [ - "You didn't reach all the switches in time.", - "The Eco Grid is still unstable." + "Interruttori non attivati nel tempo limite.", + "Griglia dell'Eco instabile." ], "cityv151": [ - "You successfully switched on the circuits", - "to stabilize the Eco Grid.", - "You have earned a reward." + "Circuiti attivati,", + "Griglia dell'Eco stabilizzata.", + "Hai guadagnato una ricompensa." ], "cityv152": [ - "I have detected a Dark Eco spill.", - "You must remove this hazard quickly", - "before the city is contaminated." + "Rilevata fonte di Eco Oscuro.", + "Rimuovere il pericolo prima che", + "la città sia contaminata." ], "cityv153": [ - "You did not remove all the Dark Eco quickly enough." + "Rimozione dell'Eco Oscuro fallita." ], "cityv154": [ - "You removed the Dark Eco hazard in time.", - "The city is grateful to you." + "Rimozione dell'Eco Oscuro riuscita,", + "la città ti è riconoscente." ], "cityv155": [ - "Sensors indicate a cluster of Blue Eco in the city.", - "Collect all eco before it dissipates", - "and you will be rewarded." + "I sensori indicano una traccia di Eco Blu in città.", + "Raccogli tutto l'Eco prima che si disperda", + "e riceverai una ricompensa." ], "cityv156": [ - "You did not retrieve all of the eco." + "Raccolta di tutto l'eco fallita." ], "cityv157": [ - "You successfully retrieved the eco.", - "Here is your reward." + "Raccolta di tutto l'eco riuscita.", + "Ecco una ricompensa." ], "cityv158": [ - "Emergency response needed.", - "Runaway bomb bots detected and headed for", - "populated areas. Neutralize all bomb bots", - "before it's too late." + "Richiesta intervento di emergenza.", + "Rilevati bot esplosivi in fuga verso", + "le aree popolate. Neutralizzare tutti i bot", + "prima che sia troppo tardi." ], "cityv159": [ - "You failed to neutralize the runaway bomb bots." + "Neutralizzazione bot esplosivi fallita." ], "cityv160": [ - "You destroyed the runaway bomb bots.", - "The city thanks you." + "Bot esplosivi distrutti. La città", + "ti è riconoscente." ], "cityv161": [ - "Get to this point in the game quickly", - "and you will receive a prize." + "Raggiungi rapidamente questo punto", + "del gioco per ricevere un premio." ], "cityv162": [ - "Try to find this spot." + "Prova a trovare questo luogo." ], "cityv163": [ - "Can you identify this place and get there?" + "Sei in grado di raggiungere questo luogo?" ], "cityv164": [ - "Make it here in the time allotted and a reward is yours." + "Raggiungi il luogo nel tempo limite, avrai una ricompensa." ], "cityv165": [ - "Find this spot for a prize." + "Trova questo luogo e avrai un premio." ], "cityv166": [ - "Get to this spot for a prize." + "Raggiungi questo luogo e avrai un premio." ], "cityv167": [ - "Metal Heads have been detected in the gun course.", - "Neutralize them all immediately." + "Rilevate Teste di Metallo sul Percorso di Tiro.", + "Neutralizzarle tutte subito." ], "cityv168": [ - "You did not kill them all." + "Neutralizzazione fallita." ], "cityv169": [ - "Excellent shooting. Threat eliminated." + "Lavoro eccellente. Minaccia eliminata." ], "cityv170": [ - "Get a high score on the JET-Board and receive a prize." + "Totalizza un record sul JET-Board e otterrai un premio." ], "cityv171": [ - "Try for a high score and receive a prize." + "Stabilisci un record e otterrai un premio." ], "cityv172": [ - "You did not achieve a high enough score." + "Punteggio ottenuto non sufficiente." ], "cityv173": [ - "Congratulations, you achieved a high enough score." + "Congratulazioni, hai ottenuto un punteggio record." ], "cityv174": [ - "Welcome to the Stadium Central Computer.", - "Please select your challenge." + "Benvenuto nel Computer Centrale dello Stadio.", + "Prego, selezionare la prova." ], "cityv175": [ - "Attention, all citizens:", - "The Class 1 Race is about to begin." + "Attenzione, a tutti i cittadini:", + "La Gara di Classe 1 sta per iniziare." ], "cityv176": [ - "Attention, all citizens:", - "The Class 2 Race is about to begin." + "Attenzione, a tutti i cittadini:", + "La Gara di Classe 2 sta per iniziare." ], "cityv177": [ - "Attention, all citizens:", - "The Class 3 Race is about to begin." + "Attenzione, a tutti i cittadini:", + "La Gara di Classe 3 sta per iniziare." ], "cityv178": [ - "Care to try for the course record?" + "Vuoi migliorare il record del circuito?" ], "cityv179": [ - "Congratulations, you achieved the gold record." + "Congratulazioni, hai ottenuto la medaglia d'oro." ], "cityv180": [ - "Congratulations, you achieved the silver record." + "Congratulazioni, hai ottenuto la medaglia d'argento." ], "cityv181": [ - "Congratulations, you achieved the bronze record." + "Congratulazioni, hai ottenuto la medaglia di bronzo." ], "cityv182": [ - "Care to try for a high score record?" + "Vuoi migliorare il record di punti?" ], "cityv183": [ - "Would you like to try for a high score?" + "Vuoi provare a stabilire un punteggio record?" ], "cityv184": [ - "Welcome to the Racing Time Trials." + "Benvenuto alle gare a tempo." ], "cityv185": [ - "Would you like to race for a record time?" + "Vuoi provare a stabilire il tempo record?" ], "cityv186": [ - "Choose your course." + "Scegliere il percorso." ], "cityv187": [ - "Would you like to try for a course record?" + "Vuoi migliorare il record del circuito?" ], "cityv188": [ - "Would you like to use Orbs to buy a secret?" + "Vuoi usare Globi per comprare un segreto?" ], "cityv189": [ - "You do not have enough Orbs for this secret." + "Non hai Globi sufficienti per questo segreto." ], "cityv190": [ - "Secret activated." + "Segreto attivato." ], "cityv191": [ - "All secrets are activated." + "Tutti i segreti attivati." ], "cityv192": [ - "Please exit the Titan Suit." + "Uscire dal Titan Suit." ], "cityv193": [ - "You must exit the Titan Suit." + "Devi uscire dal Titan Suit." ], "cityv194": [ - "Vehicles must remain within city limits." + "I veicoli devono restare nei confini cittadini." ], "cityv195": [ - "Exit denied. Enemy targets still present." + "Uscita negata. Obiettivi nemici ancora presenti." ], "cityv196": [ - "Exit denied. Metal Head eggs still detected." + "Uscita negata. Rilevate altre uova di Teste di Metallo." ], "cityv197": [ - "Scanners show Metal Head eggs still active." + "I sensori indicano altre uova di Teste di Metallo." ], "daxm001": [ - "Shoot the platform, Jak." + "Spara la piattaforma, Jak!" ], "daxm002": [ - "We need something to get through that gate!" + "Ci serve qualcosa per superare quel portale." ], "daxm003": [ - "Shoot the Metal Head when he moves his shield!" + "Sparagli quando sposta lo scudo." ], "daxm004": [ - "Hit him in his stomach!" + "Colpiscilo nello stomaco!" ], "daxm005": [ - "Whoa! That path dropped like uh... a rock!" + "Uaoh! Quel ponte è venuto giù come...come un sasso!" ], "daxm006": [ - "Smack the box, baby!" + "Spacca tutto!" ], "daxm007": [ "That's what I call a rocky road!" @@ -2096,251 +2083,251 @@ "Rock 'n roll!" ], "ds001": [ - "We gotta find the Baron, Jak." + "Dobbiamo trovare il Barone, Jak!" ], "ds005": [ - "Jak, those are Metal Heads!" + "Jak, quelle sono Teste di Metallo!" ], "ds006": [ - "Finally, now we get to see the Shadow!", - "What do ya gotta do around this place to get noticed?" + "Finalmente possiamo vedere l'Ombra!", + "Cosa bisogna fare in questo posto per farsi notare?" ], "ds012": [ - "That must be the Ruby Key to the city." + "Quella dev'essere la Chiave di Rubino della città." ], "ds013": [ - "Statues are becoming an endangered species around here." + "Le statue stanno diventando una specie in via d'estinzione da queste parti." ], "ds014": [ - "So this is Mar's scary tomb, eh?", - "Doesn't look so bad." + "Questa è la Tomba di Mar, eh? Non sembra", + "così spaventosa." ], "ds016": [ - "Let's bring the money back to Krew." + "Riportiamo i soldi a Krew." ], "ds017": [ - "That must be the ammo and missile Torn told us to blow up!" + "Guarda! Le munizioni e i missili che Torn ci ha detto di distruggere!" ], "ds018": [ - "Get the tank to shoot the missile!" + "Vai sul carro per sparare al missile!" ], "ds019": [ - "Break those tubes in the center." + "Distruggi quei tubi al centro!" ], "ds020": [ - "Per favore, dimmi che ti ricordi ancora come fare..." + "Per favore, dimmi che ti ricordi ancora come fare!" ], "ds023": [ - "Let's rock!" + "Andiamo!" ], "ds024": [ - "Here we go!" + "Forza, andiamo!" ], "ds025": [ - "All right!" + "Bene!" ], "ds026": [ - "Yeah!" + "Sì!" ], "ds028": [ - "Oh yeah!" + "Oh sììì!" ], "ds029": [ - "Let's go back to the city." + "Torniamo in città." ], "ds030": [ - "I think we need to go back to the city, Jak." + "Credo che dovremmo tornare in città, Jak." ], "ds031": [ - "Let's go talk to Torn." + "Andiamo a parlare con Torn." ], "ds032": [ - "Let's go back to the Underground Hideout." + "Torniamo al Nascondiglio del Mondo Sotterraneo." ], "ds043": [ - "Se arrivi veloce puoi saltare più lontano." + "Se arrivi veloce, puoi saltare più lontano." ], "ds044": [ - "Use a long jump to get across this gap." + "Fai un salto lungo per superare il crepaccio." ], "ds045": [ - "Nice form!" + "Bella forma!" ], "ds046": [ "Se ti abbassi prima di saltare, arriverai più in alto.", "Devi saltare più in alto per raggiungere quella sporgenza, Jak." ], "ds047": [ - "Ooh, that's a high one.", - "You'll need to jump,", - "then jump again in the air to get up there." + "Ooh, è molto in alto! Devi", + "saltare una volta,", + "quindi saltare di nuovo in aria per raggiungerla." ], "ds048": [ - "Hit 'em again, Jak!" + "Colpiscili di nuovo, Jak!" ], "ds049": [ - "Do a spin kick!" + "Calcio in giravolta!" ], "ds050": [ - "Robotank, run!" + "Carro robot! Corri!" ], "ds051": [ - "Hey, we should stay with Sig." + "Dovremmo stare con Sig." ], "ds052": [ - "Hey, big guy, keep close, huh?" + "Ehi, ragazzone, stai vicino, eh?" ], "ds053": [ - "We're too far away from Sig." + "Siamo troppo lontani da Sig." ], "ds054": [ - "Stick with the plan, Jak, protect Sig!" + "Segui il piano, Jak, proteggi Sig!" ], "ds055": [ - "Uh oh, where's Sig?" + "Oh-oh, dov'è Sig?" ], "ds056": [ - "Wow, what a blast!" + "Wow, che botta!" ], "ds057": [ - "Sig's a good shot." + "Sig non è niente male." ], "ds058": [ - "Go help Sig!" + "Vai ad aiutare Sig!" ], "ds059": [ - "Nice shootin', Sig!" + "Bel colpo, Sig!" ], "ds060": [ - "You're my hero!" + "Sei il mio eroe!" ], "ds061": [ - "Uh oh, Sig's in trouble!" + "Oh-oh, Sig è nei guai!" ], "ds062": [ - "There's another Metal Head going after our boy!", - "Shoot it, shoot it!" + "C'è un'altra Testa di Metallo che insegue il ragazzo!", + "Spara, spara!" ], "ds063": [ - "Keep Sig safe, Jak!" + "Tieni Sig al sicuro, Jak!" ], "ds064": [ - "Whoa, Sig's really getting roughed up!" + "Uau, Sig le sta prendendo!" ], "ds065": [ - "Shoot 'em, shoot 'em!" + "Sparagli, sparagli!" ], "ds066": [ - "Sig dies, we die." + "Se Sig muore, noi siamo morti!" ], "ds067": [ - "Oof, we suck..." + "Ah, siamo troppo scarsi..." ], "ds068": [ - "We have to keep 'em away from Sig." + "Dobbiamo tenerli lontani da Sig." ], "ds069": [ - "We need to find the valve to turn the water back on." + "Dobbiamo trovare la valvola per riattivare l'acqua!" ], "ds094": [ - "Robotank, run!" + "Carro robot, corri!" ], "ds095": [ - "Here comes that tank again!" + "Ecco di nuovo quel carro!" ], "ds096": [ - "Get the tank to shoot the missile!" + "Sali sul carro per lanciare il missile!" ], "ds099": [ - "We need to get to the top of that tower!" + "Dobbiamo raggiungere la cima della torre!" ], "ds100": [ - "Climb the ruined tower, Jak!" + "Sali sulla torre, Jak!" ], "ds111": [ - "We should come back with the Titan Suit to do this path." + "Per superare questo percorso, ci servirebbe la Titan Suit." ], "ds112": [ - "You've got a mechanical fist, Jak. Use it!" + "Hai un pugno mechanico, Jak. Usalo!" ], "ds113": [ - "Break the door!" + "Butta giù la porta!" ], "ds114": [ - "800 pound Tigorilla comin' through!" + "Bruto corazzato da 500 chili in arrivo!" ], "ds115": [ - "Smashing work, Jak! Oh, that was funny." + "Bel lavoro, Jak! Ah, è stato divertente!" ], "ds116": [ - "Shoot the platform, Jak." + "Spara la piattaforma, Jak!" ], "ds117": [ - "We need something to get through that gate." + "Ci serve qualcosa per superare quel portale." ], "ds118": [ - "Shoot the Metal Head when he moves his shield." + "Sparagli quando sposta lo scudo." ], "ds119": [ - "Hit him in his stomach." + "Colpiscilo nello stomaco!" ], "ds120": [ - "Whoa, that path dropped like a... a rock!" + "Uao, quel ponte è venuto giù come...come un sasso!" ], "ds121": [ - "Smack the box, baby!" + "Spacca tutto!" ], "ds128": [ - "Good, we're through." + "Bene, siamo passati." ], "ds129": [ - "Shoot the gun, Jak!" + "Spara al cannone, Jak!" ], "ds143": [ - "We're supposed to keep Krew's guys alive, Jak!" + "Dovremmo aiutare i ragazzi di Krew a sopravvivere, Jak!" ], "ds144": [ - "Save 'em, Jak!" + "Salvali, Jak!" ], "ds145": [ - "Don't like this, Jak..." + "Questo non mi piace, Jak..." ], "ds146": [ - "Behind us, Jak!" + "Dietro di noi, Jak!" ], "ds147": [ - "Metal Heads! Everywhere!" + "Teste di Metallo! Dappertutto!" ], "ds148": [ - "Protect us, Jak! But first me." + "Proteggici, Jak! Ma prima proteggi me." ], "ds150": [ - "Take a vehicle, Jak! It's faster." + "Prendi un veicolo, Jak! È più veloce." ], "ds151": [ - "Use your JET-Board!" + "Usa il tuo JET-Board!" ], "ds152": [ - "We got company, Jak! Lots of guards!" + "Abbiamo compagnia, Jak! Guardie, molte guardie!" ], "ds160": [ - "That's right, we're bad! The Precursor Stone is ours!" + "È vero, siamo cattivi! La Pietra del Precursor è nostra!" ], "ds161": [ - "There's Mar's gun, Jak! Let's go check it out." + "C'è il cannone di Mar, Jak, andiamo a vedere!" ], "ds162": [ "Queste sfere Precursor valgono molto ora.", - "dovremmo trovarne alcune qui in giro,", + "dovremmo trovarne alcune qui in giro", "o riceverne completando alcune missioni.", "Vendendole potremmo comprare molte cose!" ], "ds163": [ - "Jak, now that we have the Palace Security Pass,", - "let's go have some fun in the big man's crib!" + "Jak, ora che abbiamo il lasciapassare per entrare nel", + "Palazzo, andiamo a divertirci nelle stanze del capo!" ], "ds164": [ - "Back up to get out of the mech." + "Arretra per uscire dal mech." ], "ds165": [ "Siamo liberi, Jak! Grazie a me.", @@ -2348,751 +2335,751 @@ "La faremo vedere al Barone Praxis!" ], "ds166": [ - "I'm not getting out of this pod", - "'till you kill all those crazy flyin' Metal Heads!" + "Non uscirò da questa capsula", + "finché non avrai ucciso tutte le Teste di Metallo volanti!" ], "ds167": [ - "I wonder why they wanted us to protect Samos' Hut.", - "Maybe now we'll get to meet the Shadow." + "Mi chiedo perché ci hanno chiesto di proteggere la capanna di Samos.", + "Forse ora incontreremo l'Ombra." ], "ds168": [ - "There's the Rift Ring!" + "Ecco l'Anello Temporale!" ], "ds173": [ - "Ahhh!" + "Uaiaha!" ], "ds174": [ - "Ooooh!" + "Uohuuu!" ], "ds175": [ - "Whoa-whoa-oaa-ah!" + "Uau!" ], "ds176": [ - "Whoa!" + "Uaoh!" ], "ds177": [ - "Hey!" + "Ehi!" ], "ds178": [ - "Hey, watch that!" + "Ehi, quello che è?!" ], "ds179": [ - "Ooh!" + "Uohu!" ], "ds180": [ - "Oh, boy!" + "Wow, ragazzo!" ], "ds181": [ - "Uooaaoh!" + "Uaaaaoh!" ], "ds182": [ - "Wow, that was close!" + "Wow, c'è mancato poco!" ], "ds183": [ - "Oh, boy!" + "Oh, ragazzo!" ], "ds184": [ - "Yes!" + "Sì!" ], "ds185": [ - "Yeah!" + "Sì!" ], "ds186": [ - "Hey, watch it!" + "Ehi, attento!" ], "ds187": [ - "All right!" + "Va bene!" ], "ds188": [ - "Move over!" + "Spostati!" ], "ds189": [ - "Orange Lightning coming through!" + "Sta passando il Fulmine Arancione!" ], "ds190": [ - "Rollin' with the homies!" + "A tutta velocità!" ], "ds191": [ - "You're mine!" + "Sei mio!" ], "ds192": [ - "There they are!" + "Eccolo lì!" ], "ds193": [ - "Hey! Watch where you're drivin'!" + "Ehi! Guarda dove stai andando!" ], "ds194": [ - "How do I drive this thing?" + "Come si guida questo coso?" ], "ds195": [ - "Yeah, that's right! I'm bad!" + "Sì, è vero, sono cattivo!" ], "ds196": [ - "Outta my way!" + "Levati dai piedi!" ], "ds197": [ - "Outta my way!" + "Levati dai piedi!" ], "ds198": [ - "Move it or lose it, buddy!" + "Spostati, amico, o saranno guai!" ], "ds199": [ "Mm... bye-bye!" ], "ds200": [ - "Last lap!" + "Ultimo giro!" ], "ds201": [ - "Come on, come on!" + "Forza, forza!" ], "ds202": [ - "Come on, come on, come on!" + "Forza, forza, forza!" ], "ds203": [ - "Pedal to the metal!" + "Andiamo al massimo!" ], "ds204": [ - "Ooooah, I gotta catch up!" + "Uao, dobbiamo rimontare!" ], "ds205": [ - "Turn and burn, baby!" + "Girati e brucia, bellezza!" ], "ds206": [ - "Oooh, it's gonna be close!" + "Wow, sarà una gara combatutta!" ], "ds207": [ - "Eat my dust, buddy!" + "Mangia la mia polvere, amico!" ], "ds208": [ - "Gotcha!" + "Preso!" ], "ds209": [ - "This is my track, grandma!" + "Questa è la mia pista, nonnina!" ], "ds210": [ - "Learn to drive!" + "Impara a guidare!" ], "ds211": [ - "Turn, turn!" + "Curva, CURVA!" ], "ds212": [ - "Step on it!" + "Passaci sopra!" ], "ds213": [ - "Oooh, I won, I won!" + "Uuuh, ho vinto, ho vinto!" ], "ds214": [ - "Yeee, that's a good lap time." + "Sì, ottimo tempo sul giro!" ], "ds215": [ - "Oh, yeah! I'm rockin'!" + "Sì! Sono troppo forte!" ], "ds216": [ - "Another lap in the record book!" + "Un altro giro nel libro dei record!" ], "ds217": [ - "Take a good look at my tail!" + "Guarda bene nel fondoschiena!" ], "ds218": [ - "Wahoo!" + "Uaaaaoh!" ], "ds219": [ - "Hey, fang boy, hurry up and get in,", - "we'll take you to Brutter!" + "Ehi, dentone, muoviti a entrare, ti", + "porteremo da Brutter!" ], "ds220": [ - "Here's your boy, Brutter! We're off to get another animal!" + "Ecco il tuo amico, Brutter! Andiamo subito a prenderne un altro!" ], "ds221": [ - "Yo, animal lover, get your furry butt in the vehicle!" + "Forza, amante degli animali, porta le tue chiappe pelose sul veicolo!" ], "ds222": [ - "Here's another beast of burden!" + "Ecco un altro carico da trasportare!" ], "ds223": [ - "In the vehicle, buddy, we can save you!" + "Monta sul veicolo, amico, possiamo salvarti!" ], "ds224": [ - "Another Lurker freed." + "Un altro Nascosto liberato." ], "ds225": [ - "Let's move, eco breath! We gotta get you to Brutter." + "Muoversi! Dobbiamo portarti da Brutter." ], "ds226": [ - "Hey, Brutter! Look what the cat turkey dragged in." + "Ehi, Brutter! Guarda cosa ti abbiamo portato." ], "ds227": [ - "Lookie what we found!" + "Guarda cos'abbiamo trovato!" ], "ds228": [ - "You recognize this monster?" + "Riconosci questo mostro?" ], "ds229": [ - "We did it! We saved them all!" + "Ce l'abbiamo fatta! Li abbiamo salvati tutti!" ], "ds230": [ - "Catch the paddywagon, Jak!" + "Prendi il carretto, Jak!" ], "ds231": [ - "Crash the paddywagon!" + "Distruggi il carretto, Jak!" ], "ds232": [ - "A little more damage and we got the sucker!" + "Qualche altro colpo ed è tutto finito!" ], "ds233": [ - "He's smoking, Jak! Hit him again!" + "Sta fumando, Jak! Colpiscilo di nuovo!" ], "ds234": [ - "That caused some damage!" + "Questo ha inflitto qualche danno!" ], "ds235": [ - "One more like that and he's through!" + "Un altro colpo del genere ed è finito!" ], "ds236": [ - "Find the next vehicle!" + "Trova il prossimo veicolo!" ], "ds237": [ - "Yes, we took it out!" + "Sì, lo abbiamo distrutto!" ], "ds238": [ - "Hunt and destroy, baby!" + "Insegui e distruggi!" ], "ds239": [ - "Hit it, hit it!" + "Colpiscilo!" ], "ds240": [ - "Take it out!" + "Distruggilo!" ], "ds241": [ - "Pick up the Lurker, Jak!" + "Jak, recupera il Nascosto!" ], "ds242": [ - "Get the Lurker!" + "Recupera il Nascosto!" ], "ds243": [ - "We need to pick up that Lurker back there." + "Dobbiamo recuperare quel Nascosto!" ], "ds244": [ - "Usually, I don't like to be this close to Lurkers." + "Di solito non mi piace essere così vicino ai Nascosti." ], "ds245": [ - "Ehehe, you seem like a nice, uh... animal." + "Ah, sembri un animale molto carino." ], "ds246": [ - "Easy, buddy. Don't bite me!" + "Calmo, amico, non mordermi!" ], "ds247": [ - "Hey, stop slobbering on me!" + "Ehi, smettila di colpirmi!" ], "ds248": [ - "He's recharging!" + "Sta ricaricando!" ], "ds249": [ - "Ooh, we got him good that time!" + "Uuh, l'abbiamo preso bene questa volta!" ], "ds250": [ - "Yeah, now he's hurtin'!" + "Ehi, gli ha fatto male!" ], "ds251": [ - "Good shot, Jak!" + "Bel colpo, Jak!" ], "ds252": [ - "Incoming!" + "In arrivo!" ], "ds253": [ - "Yeah, we got him!" + "Sì, preso!" ], "ds254": [ - "Jak, hide behind the pillars when he shoots!" + "Jak, nasconditi dietro le colonne quando spara!" ], "ds255": [ - "He's got the Precursor Stone!" + "Ha la Pietra del Precursor!" ], "ds256": [ - "Kick the bomb right at him, Jak!" + "Jak, lancia la bomba contro di lui!" ], "ds257": [ - "That one hit him!" + "Quella l'ha colpito!" ], "ds258": [ - "Look out!" + "Attenzione!" ], "ds259": [ - "Jump the gap!" + "Salta!" ], "ds260": [ - "Yeah, you hit him!" + "Sì, lo hai colpito!" ], "ds261": [ - "As if there wasn't enough of Krew already." + "Come se non ne avessimo già abbastanza di Krew." ], "ds262": [ - "Shoot 'em all, Jak! We'll sort 'em out later..." + "Colpiscili tutti, Jak! Li divideremo dopo!" ], "ds263": [ - "There's the real Krew! Shoot him!" + "Ecco il vero Krew! Sparagli!" ], "ds264": [ - "You got him!" + "L'hai preso!" ], "ds265": [ - "Watch your back, Jak!" + "Attento alle spalle, Jak!" ], "ds266": [ - "They're comin' again!" + "Stanno tornando!" ], "ds267": [ - "Now you've got us mad." + "Ora c'hai fatto arrabbiare!" ], "ds268": [ - "Good shot, Jak! The big man is hurtin' now." + "Bel colpo, Jak! Il gran capo si è fatto male." ], "ds269": [ - "And the challenger is down for the count!" + "E lo sfidante è contato a terra!" ], "ds270": [ - "Keep movin', baby! He's gonna shoot!" + "Continua a muoverti! Sta per sparare!" ], "ds271": [ - "Wooh, here come some Metal Heads!" + "Uaoh, stanno arrivando delle Teste di Metallo!" ], "ds272": [ - "Protect the kid!" + "Proteggi il bambino!" ], "ds273": [ - "Kill all the Metal Heads!" + "Uccidi le Teste di Metallo!" ], "ds274": [ - "More Metal Heads!" + "Altre Teste di Metallo!" ], "ds275": [ - "Shoot Kor's legs out, Jak!" + "Colpisci le gambe di Kor, Jak!" ], "ds276": [ - "He's down, Jak! Hit him in the head!" + "È a terra, Jak! Colpiscilo in testa!" ], "ds277": [ - "Boot to the head, boot to the head!" + "Calcio in testa, calcio in testa!" ], "ds278": [ - "I think we should hide somewhere!" + "Credo che dovremmo nasconderci!" ], "ds279": [ - "Take cover before he blows!" + "Nasconditi prima che scoppi!" ], "ds280": [ - "Yeah, you got him good that time!" + "Sì, l'hai preso bene questa volta!" ], "ds281": [ - "Oh, man, now he's angry!" + "Oh, amico, ora è veramente arrabbiato!" ], "ds282": [ - "Get him, Jak!" + "Prendilo, Jak!" ], "ds283": [ - "He's gonna shoot!" + "Sta per sparare!" ], "ds284": [ - "Nice hit, partner!" + "Bel colpo, amico!" ], "ds285": [ - "That had to hurt him." + "Quello deve far male." ], "ds286": [ - "You messed with the wrong heroes, buddy!" + "Hai infastidito gli eroi sbagliati, amico!" ], "ds287": [ - "Shoot him again, Jak!" + "Sparagli ancora, Jak!" ], "ds288": [ - "Jak, we're taking a beating!" + "Jak, le stiamo prendendo!" ], "ds289": [ - "Stay away from the Dark Eco!" + "Stai lontano dall'Eco Oscuro!" ], "ds302": [ - "We've almost got him, Jak!" + "Li abbiamo quasi presi, Jak!" ], "ds303": [ - "That's it! You did it!" + "Ecco! Ci sei riuscito!" ], "ds305": [ - "Shoot the switch to change the coveyor belt's", - "direction!" + "Spara l'interruttore per cambiare la direzione", + "dei nastri!" ], "ds306": [ - "You gotta shoot the switch, Jak!" + "Devi sparare all'interruttore, Jak!" ], "ds307": [ - "Find the switch to change the conveyor's direction!" + "Trova l'interruttore per cambiare la direzione del nastro!" ], "ds321": [ - "Take out the turrets!" + "Distruggi le torrette!" ], "ds322": [ - "Hit the turrets, Jak!" + "Colpisci le torrette, Jak!" ], "ds323": [ - "Doin' some damage!" + "Facciamo qualche danno!" ], "ds324": [ - "Get in the Titan Suit!" + "Entra nel Titan Suit!" ], "ds325": [ - "Shoot that ship!" + "Spara la nave!" ], "ds326": [ - "Yeah, that ship's feelin' it now!" + "Sì, la nave sta subendo dei danni!" ], "ds327": [ - "Ooh, direct hits." + "Ooh, colpi diretti." ], "ds328": [ - "I think you hurt it that time!" + "Questa volta l'hai presa in pieno!" ], "ds329": [ - "The ship's goin' down! You did it, Jak!" + "La nave è distrutta! Ci sei riuscito, Jak!" ], "ds353": [ - "That must be the missile Torn wants us to blow up!" + "Quello dev'essere il missile che Torn ci ha detto di distruggere!" ], "ds354": [ - "Break those tubes in the center, Jak!" + "Distruggi quelle tubature al centro, Jak!" ], "ds372": [ - "Gotta ride the JET-Board on this one, Jak!" + "Dobbiamo usare il JET-Board, Jak!" ], "ds375": [ - "Look out for the ray!" + "Cerca il raggio!" ], "ds378": [ - "We gotta break all the support cables!" + "Dobbiamo rompere i cavi di supporto!" ], "ds379": [ - "Grind on the support bases to break the cables." + "Scivola sulle basi di supporto per rompere i cavi." ], "ds394": [ - "Spider! Spider! Huff... huff... I hate spiders!" + "Ragni! Ragni! Hhu...huhuh...odio i ragni!" ], "ds395": [ - "Gotta run, gotta run!" + "Corriamo, corriamo!" ], "ds398": [ - "The first beam!" + "Il primo raggio!" ], "ds399": [ - "The second beam! The door's opening!" + "Il secondo raggio! La porta si sta aprendo!" ], "ds404": [ - "There's Sig!" + "Ecco Sig!" ], "ds405": [ - "Get the blocks to go into the slots, Jak!" + "Porta quei blocchi nelle aperture, Jak!" ], "ds406": [ - "Shoot or kick the blocks!" + "Spara ai blocchi o dagli un calcio!" ], "ds407": [ - "You have to get the blocks in the slots faster!" + "Devi mettere quei blocchi nelle aperture più in fretta!" ], "ds408": [ - "Run, Jak!" + "Corri, Jak!" ], "ds409": [ - "Keep moving!" + "Continua a muoverti!" ], "ds410": [ - "We gotta stay ahead of that thing!" + "Dobbiamo restare davanti a questa cosa!" ], "ds439": [ - "Shoot all the Metal Head eggs, Jak!" + "Colpisci le uova delle Teste di Metallo, Jak!" ], "ds440": [ - "We didn't get all those nasty eggs!" + "Non abbiamo distrutto tutte le uova!" ], "ds441": [ - "We missed some Metal Head eggs!" + "Abbiamo mancato delle uova!" ], "ds461": [ - "We gotta jump onto the crate dangling from the crane!" + "Dobbiamo salire sulla cassa appesa alla gru!" ], "ds462": [ - "Use your hoverboard on this path!" + "Usa il tuo hoverboard in questo percorso!" ], "ds463": [ - "You can grind to cross those pipes using your", - "hoverboard!" + "Puoi scivolare lungo questi tubi utilizzando", + "l'hoverboard!" ], "ds464": [ - "Ride the half-pipe to the end!" + "Usa l'half-pipe fino alla fine!" ], "ds466": [ - "You gotta drop a bomb into each well, Jak!" + "Devi lanciare una bomba nei pozzi d'Eco, Jak!" ], "ds467": [ - "Use the ramp to get high enough to drop the bomb in!" + "Usa la rampa per alzarti abbastanza e lanciare la bomba!" ], "ds468": [ - "Gotta jump higher!" + "Devi saltare di più!" ], "ds469": [ - "Only a minute before we're toast, Jak!" + "Solo un minuto prima di essere fritti, Jak!" ], "ds470": [ - "30 seconds left, then we go BOOM!" + "30 secondi...e poi...BUM!" ], "ds471": [ - "Ten seconds left, Jak!" + "Mancano dieci secondi, Jak!" ], "ds472": [ - "That's one well down, five to go!" + "Un pozzo distrutto, ne mancano cinque!" ], "ds473": [ - "Two wells are history, four left!" + "Due pozzi andati, quattro rimasti!" ], "ds474": [ - "Three wells cut, only three to go!" + "Tre pozzi esplosi, ne mancano solo tre!" ], "ds475": [ - "That's the fourth well, two bad boys left!" + "Questo era il quarto, mancano due pozzi!" ], "ds476": [ - "You got the fifth well, only one to go!" + "Hai preso il quinto! Ne manca solo uno!" ], "ds477": [ - "You got 'em all, Jak!" + "Li hai distrutti tutti, Jak!" ], "ds478": [ - "The last well is up where we rescued Vin!" + "L'ultimo pozzo è dove abbiamo liberato Vin!" ], "ds479": [ - "Now he's vulnerable!" + "Ora è vulnerabile!" ], "ds480": [ - "Take him out!" + "Eliminalo!" ], "ds481": [ - "Get him while he's vulnerable!" + "Colpiscilo mentre è vulnerabile!" ], "ds482": [ - "Here he comes..." + "Sta arrivando!" ], "ds483": [ - "How's it feel to have your pants down, Baron?" + "Come ci si sente con i pantaloni calati, Barone?" ], "ds484": [ - "Sparategli, sparategli!" + "Sparagli, sparagli!" ], "ds485": [ - "Look out!" + "Attento!" ], "ds487": [ - "Easy, Jak, we gotta get this guy to safety!" + "Calmo, Jak, dobbiamo portarlo al sicuro!" ], "ds488": [ - "We're takin' a lotta damage, buddy!" + "Stiamo subendo molti danni, amico!" ], "ds489": [ - "We're gettin' our butts kicked!" + "Stiamo subendo troppo, amico!" ], "ds490": [ - "Maybe I should drive..." + "Forse dovrei guidare io..." ], "ds491": [ - "Let's go, wondergoon,", - "we'll take you to a safe place in the city!" + "Andiamo nel Sotterraneo, ti", + "porteremo in un luogo sicuro della città!" ], "ds492": [ - "Okay, ride's over, out you go!" + "Okay, la corsa è finita, ora scendi!" ], "ds493": [ - "All aboard the Underground railroad!", - "Next stop: Your new safehouse!" + "Tutti a bordo del Trasporto Sotterraneo!", + "Prossima fermata: la tua nuova casa!" ], "ds494": [ - "I believe this is your stop!" + "Credo che questa sia la tua fermata!" ], "ds495": [ - "Daxter's Freedom Fighter Taxi Service!", - "Hurry up, buddy, we ain't got all day." + "Servizio di Taxi dei Combattenti per la Libertà di", + "Daxter! Su, amico, non c'è tempo da perdere." ], "ds496": [ - "Home free, baby!", - "Don't forget to tell Torn how well we did!" + "Eccoti a casa!", + "Ricordati di dire a Torn quanto siamo stati bravi!" ], "ds497": [ - "You looking for a lift, fighter boy?" + "Stai cercando un passaggio?" ], "ds498": [ - "Okay, this is where you get off. So... get off." + "Ok, devi scendere qui. Allora...scendi!" ], "ds499": [ - "We did it, Jak!", - "We got all the fighters to the new safehouses!" + "Ci siamo riusciti, Jak!", + "Abbiamo portato tutti i combattenti nei nuovi nascondigli!" ], "ds500": [ - "Statues are becoming an endangered species around here." + "Le statue stanno diventando una specie in via d'estinzione da queste parti." ], "ds501": [ - "I got us a talkbox.", - "The city people use these things to communicate", - "with each other." + "Ho trovato un talkbox.", + "La gente in città usa queste cose per", + "comunicare." ], "ds502": [ - "Let's go see Onin and her crazy monkey bird." + "Andiamo da Onin e dal suo folle pennuto." ], "ds503": [ - "I think we need to go back to the city, Jak." + "Credo che dovremmo tornare in città, Jak." ], "dsek001": [ - "Kid! Stay with him, Jak!" + "Bambino, stai con Jak!" ], "dsek002": [ - "Catch up to them, Jak!" + "Raggiungili, Jak!" ], "dsek003": [ - "Where'd they go?!" + "Ma dove vanno?!" ], "dsek004": [ - "There they go again!" + "Eccoli di nuovo!" ], "dsek005": [ - "Uh oh, here comes trouble!" + "Oh-oh, problemi in vista!" ], "dsek006": [ - "More guards!?" + "Altre guardie!" ], "dsek007": [ - "Kid, please! You're killin' me!" + "Bambino, attento, mi stai uccidendo!" ], "dsek008": [ - "Here, poochie, poochie..." + "Vieni qui, ciuccino..." ], "dsek009": [ - "There goes that crazy crocadog again...!" + "C'è di nuovo quel pazzo di crocadog!" ], "dsek010": [ - "Chase after the Kid!" + "Inseguiamo il bambino!" ], "dsek011": [ - "Keep up with the Kid!" + "Dietro al bambino!" ], "dsek012": [ "Crocadog!" ], "dsek013": [ - "Phew, finally... let's get these two to Kor!" + "Uh, finalmente...portiamo questi due da Kor!" ], "ero001": [ - "Out of my way!" + "Togliti dai piedi!" ], "ero002": [ - "I own this track!" + "Questo tracciato è mio!" ], "ero003": [ - "Give it up, eco freak!" + "Arrenditi, eco mostro!" ], "ero004": [ - "Payback time." + "Ora della vendetta." ], "ero005": [ - "Let's make this interesting!" + "Rendiamo la gara interessante!" ], "ero006": [ - "Eat wall!" + "Al muro!" ], "ero007": [ - "Time to die!" + "È l'ora di morire!" ], "ero008": [ - "Move over!" + "Levati!" ], "ero009": [ - "Catch me now, loser!" + "Prendimi ora, perdente!" ], "ero010": [ - "I'm too fast for you!" + "Sono troppo veloce per te!" ], "ero011": [ - "Now you're racing with the big boys!" + "Ora corri contro i grandi!" ], "ero012": [ - "Here's one for the Baron." + "Eccone uno per il Barone." ], "ero013": [ - "Take this!" + "Prendi questo!" ], "ero014": [ - "You're making this too easy!" + "Rendi tutto troppo facile!" ], "ero015": [ - "Hahaha, bye bye!" + "Ahahah, addio!" ], "ero016": [ - "You want some?" + "Ne vuoi un po'?" ], "ero017": [ - "Now you see why I never lose." + "Ora capisci perché non perdo mai." ], "ero018": [ - "The crowd loves me!" + "Il pubblico mi ama!" ], "ero019": [ "Ahh!" ], "ero020": [ - "Here's some pain!" + "Preparati a soffrire!" ], "ero021": [ - "Try to erase these!" + "Prova a sfuggire a questi!" ], "ero022": [ - "How's your reflexes?" + "Come sono i tuoi riflessi?" ], "ero023": [ - "Too much for you?!" + "È troppo per te?!" ], "ero024": [ - "Had enough?" + "Ti basta?" ], "ero025": [ - "Avoid this, smart-ass!" + "Evita questo, furbacchione!" ], "ero026": [ - "Say goodnight, eco freak!" + "Buonanotte, eco-mostro!" ], "ero027": [ - "You can't beat me!" + "Non puoi battermi!" ], "ero028": [ - "I'd die before I let you win!" + "Morirei pur di non farti vincere!" ], "ero029": [ - "This will be your last lap." + "Questo sarà il tuo ultimo giro." ], "ero030": [ - "Crash and burn!" + "Esplodi e brucia!" ], "ero031": [ - "To the end!" + "Fino alla fine!" ], "ero032": [ - "Last lap to live!" + "Ultimo giro di vita!" ], "ero033": [ - "Now we end this!" + "Ora la facciamo finita!" ], "ero034": [ - "You won't see the finish line!" + "Non vedrai la bandiera scacchi!" ], "ero035": [ - "DIE!" + "MUORI!" ], "ero036": [ - "Die!" + "Muori!" ], "ero037": [ - "Hahahaha!" + "Ahahahah!" ], "ero038": [ "YEAH!" @@ -3110,103 +3097,103 @@ "AHHHHHH!" ], "ero043": [ - "Here we go." + "Andiamo." ], "ero044": [ - "See you later." + "Ci vediamo più tardi." ], "ero045": [ - "Fool! You cannot defeat me." + "Pazzo! Non puoi sconfiggermi." ], "ero046": [ - "You missed a ring." + "Ha mancato un anello." ], "ero047": [ - "This race is mine!" + "Questa gara è mia!" ], "ero048": [ - "You can never be as fast as me!" + "Non sarai mai veloce come me!" ], "ero049": [ - "Keira wants a real man." + "Keira vuole uomini veri." ], "ero050": [ - "Bad luck, old chap." + "Che sfortuna, poverino." ], "ero051": [ - "Nice try." + "Bel tentativo." ], "ero052": [ - "Move over!" + "Spostati!" ], "ero053": [ - "Out of my way!" + "Levati da lì!" ], "ero054": [ - "Coming through!" + "Sto passando!" ], "ero055": [ "Bye bye!" ], "ero056": [ - "Here I come!" + "Eccomi qui!" ], "ero057": [ - "Get used to watching my back!" + "Abituati a guardarmi il fondoschiena!" ], "ero058": [ - "This is my city, eco freak." + "Questa è la mia città, eco-mostro." ], "ero059": [ - "Looking sloppy, Jak." + "Non sembri in forma, Jak." ], "ero060": [ - "Give it up!" + "Arrenditi!" ], "ero061": [ - "Not this time." + "Non questa volta." ], "ero062": [ - "Getting a bit nervous?" + "Stai diventando nervoso." ], "ero063": [ - "Come back here!" + "Torna qui!" ], "ero064": [ - "Move over, slowpoke!" + "Spostati, lumaca!" ], "ero065": [ - "This is where I beat you." + "È qui che io ti batterò." ], "ero066": [ - "Final stretch!" + "L'ultimo sforzo!" ], "ero067": [ - "It's over!" + "È finita!" ], "ero068": [ - "I own this city." + "Questa città è mia!" ], "ero069": [ - "What? Where'd you come from?" + "Cosa? Da dove verresti?" ], "ero070": [ - "You're just lucky." + "Sei solo fortunato." ], "ero071": [ - "You can't handle the speed!" + "Non la reggi questa velocità!" ], "ero072": [ - "Die, freak." + "Muori, mostro." ], "ero073": [ "No!" ], "ero074": [ - "STOP!" + "FERMO!" ], "ero075": [ - "Hahahaha!" + "Ahahahah!" ], "ero076": [ "HAHA!" @@ -3215,537 +3202,537 @@ "Ahhh!" ], "ero078": [ - "Ough!" + "Ohh!" ], "ero079": [ - "Oof!" + "Uuh!" ], "ero080": [ - "Beat it, freak!" + "Prendi questo, mostro!" ], "ero081": [ - "Care to get back in the chair?" + "Preoccupati di finire intero." ], "ero082": [ - "This race was too easy." + "È stata una gara troppo facile." ], "ero083": [ - "It was easier than I thought to beat you." + "Batterti è stato più facile di quanto pensassi." ], "ero084": [ - "Not even close, Keira's betting on the wrong man." + "Non ci sei neanche vicino, Kiera ha scelto la persona sbagliata." ], "ero085": [ - "Loser! You disgust me!" + "Perdente! Mi fai schifo!" ], "ero086": [ - "You see Jak, I win, and I get what I want.", - "Someday I will be Baron, then the city will really pay!" + "Vedi, Jak? Ho vinto e prenderò ciò che voglio.", + "Un giorno io sarò il Barone, e allora la città la pagherà!" ], "ero087": [ - "I should have known you'd be no match." + "Lo sapevo che non avrei avuto problemi con te." ], "ero088": [ - "I win, Keira's going to love me!" + "Ho vinto! Adesso Kiera mi amerà!" ], "ero089": [ - "Maybe you should go back to wherever you came from." + "Forse dovresti tornare al pianeta da cui provieni." ], "ero090": [ - "I'll get a victory kiss from Keira later." + "Più tardi mi prenderò un bel bacio della vittoria da Kiera." ], "ero091": [ - "Again I prove my superiority." + "Ho dimostrato ancora la mia superiorità." ], "ero092": [ - "You see? You are no match for me." + "Vedi? Non hai speranze contro di me." ], "ero093": [ - "Too bad, I win!" + "Che peccato, ho vinto!" ], "ero094": [ - "Hahahaha, pathetic insect, I win!" + "Ahahahah, patetico insetto, ho vinto!" ], "ero095": [ - "You can never defeat me!" + "Non mi sconfiggerai mai!" ], "ero096": [ - "Ahhh!...ahh." + "Ahhh...ahh." ], "ero097": [ - "Ugh!" + "Guh!" ], "ero098": [ - "Ughhh!" + "Uoh!" ], "ero099": [ "Dahh!" ], "ero100": [ - "Yaughh!" + "Eahh!" ], "ero101": [ - "AUGHH!" + "OAHHH!" ], "ero102": [ - "OW!" + "UOH!" ], "ero103": [ - "DAHHH!" + "IOAHHH!" ], "ero104": [ - "DAUGHH!" + "NOOOOH!" ], "erol001": [ - "I'm looking for you, eco freak,", - "and when I find you, you'll wish you died in prison." + "Ti sto cercando, eco-mostro.", + "Visto quello che ho in mente per te, sarebbe stato meglio morire in prigione!" ], "erol002": [ - "This is Erol. Looks like you're running out of friends.", - "We've arrested them all and thrown them into your", - "favorite prison. By the way, that blonde girl Tess", - "screamed so delightfully when she was arrested.", - "I can't wait for her turn in the chair.", - "Hahahahaha...." + "Parla Erol. Sembra che tu sia corto di amici.", + "Li abbiamo arrestati e li abbiamo", + "portati nella tua prigione preferita. E quella biondina Tess", + "urlava in maniera deliziosa quando l'abbiamo", + "arrestata. Già, non vedo l'ora di", + "interrogarla. Ricordati, l'unico motivo per cui cammini ancora è perché voglio sfidarti nella gara del campionato! Fino ad allora, non sentirti troppo solo...ahahahahah!" ], "erol003": [ - "This is Erol. Just remember, the only reason I'm letting you", - "walk is so I can face you in the championship race!" + "Qui parla Erol. Ricorda che l'unica ragione per cui ti lascio", + "caminare è che così ti posso affrontare nel campionato!" ], "hal001": [ - "Quiet! Here comes pretty boy." + "Calmi! Ecco arrivare il ragazzo." ], "hal002": [ - "'Bout time you showed up. Okay, let's do this." + "Era ora che arrivassi. Ok, andiamo." ], "hal003": [ - "Krew said you'll protect us all the way to the statue." + "Krew ha detto che ci proteggerai fino alla statua." ], "hal004": [ - "We go down!" + "Noi scendiamo!" ], "hal006": [ - "This way!" + "Di qua!" ], "hal007": [ - "AHH! It's a Metal Head! Shoot it, shoot it!" + "AHH! È una Testa di Metallo! Sparagli, sparagli!" ], "hal008": [ - "Stay with us!" + "Resta con noi, ragazzo!" ], "hal009": [ - "Man, Krew's gonna be pissed if you mess this up." + "Se ci lasci morire, Krew ti distruggerà." ], "hal010": [ - "Don't leave us to die!" + "Non lasciarci morire!" ], "hal011": [ - "You ditch us and Krew's gonna mess you up!" + "Se ci scarichi, Krew ti farà a pezzi!" ], "hal012": [ - "We need to stay together." + "Dobbiamo restare uniti." ], "hal013": [ - "I thought this guy was supposed to be protecting us!" + "Ma quel ragazzo non doveva proteggerci?" ], "hal014": [ - "That's it! We're calling the mission off,", - "we don't go until you're serious." + "Ora possiamo dire che la missione è finita.", + "Non andremo avanti finché non farai sul serio." ], "hal015": [ - "I'm not getting killed because of this loser,", - "this mission is over." + "Non mi farò ammazzare per colpa di un perdente,", + "la missione è conclusa!" ], "hal019": [ - "Let's go back before we all get killed." + "Torniamo indietro, moriremo tutti." ], "hal020": [ - "Ugh, this place stinks." + "Oh, questo posto puzza!" ], "hal021": [ - "I got a bad feeling about this place." + "Ho una brutta sensazione su questo posto." ], "hal022": [ - "Uh oh, I think I wet myself." + "Oh-oh, me la sono fatta addosso." ], "hal023": [ - "No! Please!" + "No! Per favore!" ], "hal024": [ - "I wanna go home." + "Torniamo a casa." ], "hal025": [ - "Uhh, I'm hearing things." + "Ohh, sento delle voci." ], "hal026": [ - "Let's go back." + "Torniamo indietro!" ], "hal027": [ - "Move your butts, or I'll move 'em for ya!" + "Muovete le chiappe o ve ne farò muovere io!" ], "hal028": [ - "This job beats being a garbage man." + "Questo lavoro è peggio che fare lo spazzino." ], "hal029": [ - "Ain't the smell of sulphur grand?" + "L'odore di zolfo non è grandioso? Eheh...eheh..." ], "hal030": [ - "Cover your ears!" + "Tappati le orecchie!" ], "hal031": [ - "I love this job." + "Adoro questo lavoro." ], "hal032": [ - "Great, now we're trapped in this slime pit!" + "Aah, siamo bloccati in questo pozzo schifoso!" ], "hal033": [ - "Shoot, baby, shoot!" + "Spara, amico, spara!" ], "hal034": [ - "Ahh! The ceiling's crawling!" + "Ah! Attenzione al soffitto!" ], "hal035": [ - "I can't get away!" + "Non posso andare!" ], "hal036": [ - "There's one coming right at me!" + "Qualcuno viene verso di me!" ], "hal037": [ - "It sees me!" + "Ehi, mi vede!" ], "hal038": [ - "Ahh! Stay away!" + "Ahh! Allontanati!" ], "hal039": [ - "It's hitting me!" + "Mi sta colpendo!" ], "hal040": [ - "Gahh, I'm gonna die here!" + "Gahh, morirò qui!" ], "hal041": [ - "I'm getting zapped!" + "Mi stanno colpendo!" ], "hal042": [ - "This'll be the end of me!" + "Questa sarà la mia fine!" ], "hal043": [ - "Help me! I've got eight kids to feed!" + "Aiuto! Ho otto figli da sfamare!" ], "hal044": [ - "Nice work, those were some nasty Metal Heads." + "Bel lavoro, quelle Teste di Metallo erano molto pericolose." ], "hal045": [ - "There you are, why don't you make yourself useful?" + "Eccoti qui, perché non cerchi di renderti utile?" ], "hal046": [ - "Keep moving!" + "Continua a muoverti!" ], "hal047": [ - "On we go, we're not getting any younger." + "Andiamo! Non diventeremo più giovani." ], "hal048": [ - "Ahh! They're crawling down the walls!" + "Ahh! Stanno scendendo dai muri!" ], "hal049": [ - "Way to go, this is where I come in." + "La strada è ancora lunga, siamo entrati da qui." ], "hal050": [ - "You mean cover your ass! Fire in the hole!" + "Volevi dire \"copriti le chiappe\"! Bomba in buca!" ], "hal051": [ - "You better keep your head down, sugar." + "Farai meglio a tenere giù la testa, tesoro." ], "hal052": [ - "Your bad breath, let's move." + "Che alito pesante, andiamo!" ], "hal053": [ - "That straightened your hair, huh?", - "Hehe, next time you'll listen to me. Okay, let's move." + "Ti ha fatto rizzare i capelli, eh?", + "Eheh, la prossima volta mi ascolterai. Ok, andiamo avanti." ], "hal054": [ - "Oof, that had to hurt.", - "I told you to keep back, but no one ever listens to Jinx." + "Ooh, deve fare molto male.", + "Ti avevo detto di stare indietro, ma nessuno ascolta mai Jinx!" ], "hal055": [ - "More of those monsters!" + "Ci sono altri mostri!" ], "hal056": [ - "So what, we got a dream team here. Do your stuff, Jak!" + "E allora? Siamo in compagnia dei migliori. Jak, pensaci tu!" ], "hal057": [ - "Jak! Get your butt up here and do your thing." + "Jak! Porta qui il tuo sedere e pensaci tu!" ], "hal058": [ - "Take 'em out, blue boy." + "Portali fuori, ragazzo!" ], "hal059": [ - "You're pretty handy with that iron, blondie." + "Sei molto abile con quel ferro, biondino." ], "hal060": [ - "Shut up, Mog." + "Sta' zitto, Mog!" ], "hal061": [ - "Here they come again!" + "Eccoli di nuovo!" ], "hal062": [ - "Get up here and earn your keep!" + "Vieni qui e guadagnati la paga!" ], "hal063": [ - "Krew was right about you. You got the magic, man." + "Krew aveva ragione su di te. Sei magico, amico." ], "hal064": [ - "Nice fighting, man, I'm beginning to like you." + "Bel combattimento, amico! Cominci a piacermi." ], "hal065": [ - "Okay... that doesn't look good. Jak, you're up!" + "Okay...la situazione non è bella. Jak, tocca a te!" ], "hal066": [ - "Wow! Beams of death!", - "I'm staying right here 'til you do something about that." + "Uao! Raggio della morte?!", + "Resterò qui fino a quando non avrai fatto qualcosa." ], "hal067": [ - "Uhhh, Jak. I think you're the man for this job." + "Ah, Jak, tu sei la persona giusta per questo lavoro." ], "hal068": [ - "Jump the beams, Jak." + "Salta i raggi, Jak!" ], "hal069": [ - "Nice moves." + "Belle mosse!" ], "hal070": [ - "Yeah... you wish, tubby." + "Sì, ti piacerebbe, nanetto." ], "hal071": [ - "We're staying put 'til you take out those Metal Heads." + "Staremo fermi finché non avrai eliminato le Teste di Metallo." ], "hal072": [ - "Sweet as a ballerina, hehehehe..." + "Dolce come una ballerina! Eheh...eheh..." ], "hal073": [ - "Knock 'em silly, Jak!" + "Falli impazzire, Jak!" ], "hal074": [ - "This one's gonna be loud!" + "Ci sarà un bel rumore." ], "hal075": [ - "This is too easy." + "Troppo facile!" ], "hal080": [ - "We ain't moving, 'til you kill 'em all!" + "Non ci muoviamo fino a quando non li ammazzi tutti!" ], "hal081": [ - "OK, let's get out of here before more come back." + "Ok, usciamo di qui prima che ne arrivino altre." ], "hal082": [ - "You're earning your dough today. Let's finish this!" + "Oggi ti sei meritato la paga. E ora finiamola!" ], "hal083": [ - "I'm impressed, Jak. I'll put in a good word with the boss." + "Sono impressionato, Jak. Metterò una buona parola per te con il capo." ], "hal084": [ - "Yeah, do it, Jinx." + "Avanti, fallo, Jinx!" ], "hal085": [ - "Man, Jinx, what'd you put in those boomsticks?" + "Ehi, Jinx, cos'hai messo in quegli esplosivi?" ], "hal086": [ - "Look at him go." + "Guardate come va." ], "hal087": [ - "I could jump like that." + "Anch'io potrei saltare così." ], "hal088": [ - "Get away from me, you crazy monster!" + "Allontanati da me, brutto mostro!" ], "hal090": [ - "This is where I come in, cover your ears." + "Ecco dove entro in gioco io. Copritevi le orecchie!" ], "hal091": [ - "Fire in the hole!" + "Bomba in buca!" ], "hal092": [ - "And on we go." + "Andiamo avanti." ], "hal093": [ - "Please, allow me." + "Per favore, lascia fare a me!" ], "hal094": [ - "One unclogged sewer, comin' up." + "Fogna sgorgata in arrivo!" ], "hal095": [ - "This is my boomshtick!" + "Questo è il mio trucco esplosivo!" ], "hal096": [ - "Boom, baby!" + "Esplodi, baby!" ], "hal097": [ - "We're clear, let's move." + "Tutto a posto. Muoviamoci!" ], "hal101": [ - "Ahh! That's gonna leave a mark." + "Ahh! Questo lascerà il segno!" ], "hal102": [ - "Die! A little help would be good!" + "Muori! Un piccolo aiuto ci starebbe bene!" ], "hal103": [ - "Watch it, pretty boy, or I'll rearrange your face." + "Fa' attenzione, bello, o ti cambio i connotati." ], "hal104": [ - "You got an itchy trigger finger." + "Controlla il dito sul mirino!" ], "hal107": [ - "Piece of cake." + "Una passeggiata." ], "hal108": [ - "Get over here, Jak!" + "Vieni qui, Jak!" ], "hal109": [ - "Stay close, pretty boy!" + "Resta vicino, bel ragazzo!" ], "hal111": [ - "Keep with us, tough guy!" + "Stai con noi, ragazzo!" ], "hal112": [ - "You're in the way, Jak, move!" + "È un punto pericoloso, Jak, muoviti!" ], "hal113": [ - "I wouldn't stand there if I were you!" + "Non resterei lì se fossi in te!" ], "hal114": [ - "This is gonna be loud." + "Ci sarà un bel rumore." ], "hal115": [ "Oh!" ], "hal116": [ - "Oh!" + "Ooh!" ], "hal117": [ - "Hey!" + "Ehi!" ], "hal118": [ - "It's a trap!" + "Una trappola!" ], "hal119": [ - "Yeah, why did we sign up for this?" + "Ah, io avrei un impegno..." ], "hal120": [ - "I got 30 keys of high explosives strapped to my back...", - "Great..." + "Ho trenta cariche di potenti esplosivi attaccate alla mia schiena...", + "Perfetto..." ], "hal121": [ - "Just shut your whiny traps and keep moving." + "Smettila di piagnucolare e continua a muoverti." ], "hal122": [ - "Uh, do we have to?" + "Uh, dobbiamo proprio?" ], "hal123": [ - "Uhh, did you hear that?" + "Aah, l'hai sentito?" ], "hal124": [ - "We are so dead, man." + "Siamo morti, amico." ], "hal125": [ - "Shut up! I'll go ahead and check it out..." + "Zitto! Andrò avanti a vedere cos'è successo..." ], "hal126": [ - "Man, that thing's ugly." + "Quel coso è bruttissimo." ], "hal127": [ - "Get him, man, before he gets us." + "Prendilo, prima che lui prenda noi." ], "hal128": [ - "They're coming up from behind, too!" + "Stanno arrivando anche da dietro!" ], "hal129": [ - "Jak's my hero." + "Jak è il mio eroe." ], "hal130": [ - "Sounds like I got gas." + "Sembra che io abbia ancora benzina." ], "hal131": [ - "I hate Krew." + "Io odio Krew!" ], "hal132": [ - "I'm sure not going back that way!" + "Krew si arrabbierà se combini dei guai!" ], "hal133": [ - "It's coming for me!" + "Sta venendo da me!" ], "hal134": [ - "I think it wants me!" + "Credo che voglia me!" ], "hal135": [ - "Help me, Jak!" + "Aiutami, Jak!" ], "hal136": [ - "I'm gonna die!" + "Sto per morire!" ], "hal137": [ - "It got me!" + "Mi ha preso!" ], "hal138": [ - "Jak! Save me!" + "Jak! Salvami!" ], "hal139": [ - "Ughh! It got me!" + "Oouuh! Mi ha preso!" ], "hal140": [ - "Oughh! That beam smarts." + "Oughh! Quel raggio è forte." ], "hal141": [ - "I've been shot!" + "Mi ha preso!" ], "hal142": [ - "I'm hit!" + "Mi ha colpito!" ], "hal143": [ - "Ughh!" + "Gahhh!" ], "hal144": [ - "Ughh! Help me!" + "Gahah! Aiuto!" ], "hal145": [ - "Hey man, watch it!" + "Ehi, ragazzo, attento!" ], "hal146": [ - "Ohh, hit me again and I'll pound you!" + "Ohh, prendimi ancora e te le suono!" ], "hal147": [ - "Nobody's my friend..." + "Nessuno è mio amico..." ], "hal148": [ - "Oof!" + "Oh!" ], "hal149": [ "Uh!" ], "hal150": [ - "Ahh!" + "Oh!" ], "hal151": [ - "He's got me!" + "Mi ha preso!" ], "hal152": [ - "Gahh!! Not again!" + "Un'altra volta no!" ], "hal153": [ - "I'm dying!" + "Sto per morire!" ], "hal154": [ - "Any more like that, then I'm history." + "Un'altra così e sono storia." ], "hal155": [ - "I'm getting shot!" + "Mi sta sparando!" ], "hal156": [ - "Sure! Why don't you kill me too?" + "Certo! Perché non uccidi anche me?" ], "hal157": [ - "Check your targets, wimp boy!" + "Occhio a chi spari, pivello!" ], "hal158": [ - "Shoot the shine-heads, not me!" + "Spara alle bestiacce di ferro, non a me!" ], "hal159": [ "Ahh!" @@ -3763,510 +3750,510 @@ "Ah!" ], "hal165": [ - "Look out!" + "Attenti!" ], "hal166": [ - "We're not doing this with a rookie, I'm calling this off!" + "Non lavoriamo con i pivelli. Per me abbiamo finito!" ], "hal167": [ - "That's it, we're done! Come back when you're serious." + "Bene, abbiamo finito! Torna quando vorrai fare sul serio." ], "hal168": [ - "I'm cornered!" + "Mi hanno incastrato!" ], "hal169": [ - "It's gonna shoot me!" + "Sta per spararmi!" ], "hal170": [ - "Jak! Do something!" + "Jak! Fa' qualcosa!" ], "hal171": [ - "Ahh! It got me!" + "Aaah! Mi ha preso!" ], "hal172": [ - "No no no! Help!" + "No no no no! Aiuto!" ], "hal173": [ - "They're getting too close, Jak!" + "Si stanno avvicinando troppo, Jak!" ], "hal174": [ - "It's gonna get me!" + "Sta per prendermi!" ], "hal175": [ - "I'm getting killed here!" + "Stanno per uccidermi quaggiù!" ], "hal176": [ - "Jak! I'm about to be metal meat!" + "Jak! Sto per diventare cibo per le bestie!" ], "hal177": [ - "Aghh! That beam burns!" + "Aah! Quel raggio brucia!" ], "hal178": [ - "It's shooting me!" + "Mi sta sparando!" ], "hal179": [ - "Watch out for the beam!" + "Attenti ai raggi!" ], "hal180": [ - "I'm shot!" + "Mi spara addosso!" ], "hal181": [ - "I'm trapped!" + "Sono in trappola!" ], "hal182": [ - "Get back... I'm gonna detonate this one remotely." + "State indietro! Sto per farlo saltare con il comando a distanza!" ], "hal183": [ - "He-hah!" + "Eh? Heh, sì!" ], "hal184": [ - "Alright!" + "Così!" ], "hal185": [ - "Let's go!" + "Andiamo!" ], "hal186": [ - "Move it!" + "Muoversi!" ], "hal187": [ - "That's a lot of Metal Heads." + "Sono una marea di Teste di Metallo!" ], "hal188": [ - "Oof!" + "Oh!" ], "hal189": [ - "Daghh!" + "Dah!" ], "hal190": [ - "Oughh..." + "Oooah..." ], "hal191": [ - "Krew's dead for getting me into this!" + "Krew la pagherà per avermi cacciato in questo guaio!" ], "jak001": [ - "Alright!" + "Ottimo!" ], "jak002": [ "Yeah!" ], "jak003": [ - "Wooo!" + "Uoaoh!" ], "jak004": [ - "Here we go!" + "Andiamo!" ], "jak005": [ - "Nice!" + "Bene!" ], "jak006": [ - "Rock 'n roll!" + "Rock 'n' roll!" ], "jak007": [ - "Right on!" + "Perfetto!" ], "jak008": [ - "Cool!" + "Figo!" ], "jak009": [ - "Cool!" + "Figo!" ], "jak010": [ - "Oh, yeah!" + "Oh, sì!" ], "jak011": [ - "Comin' through!" + "Sorpasso!" ], "jak012": [ - "Look out!" + "Occhio!" ], "jak013": [ - "Last lap!" + "Ultimo giro!" ], "jak014": [ - "Watch out!" + "Attenzione!" ], "jak015": [ - "Whoa!" + "Uao!" ], "jak016": [ - "Whoa!" + "Uaoh!" ], "jak017": [ - "Hold on, Dax!" + "Resisti, Dax!" ], "jak018": [ - "Hang on, Dax!" + "Reggiti, Dax!" ], "jak020": [ - "Whoa... boy that was close." + "Uh! Ragazzi, c'è mancato poco." ], "jak021": [ "No!" ], "jak022": [ - "Not this time." + "Non questa volta." ], "jak023": [ - "Huargh!" + "Hueh!" ], "jak024": [ - "Lean, baby, lean!" + "Abbassati, baby!" ], "jak025": [ - "Catch him on the inside!" + "Passalo all'interno!" ], "jak026": [ - "This is MY show!" + "È il mio spettacolo!" ], "jak027": [ - "Haha, we got him!" + "Hah, l'abbiamo preso!" ], "jak028": [ - "Watch out!" + "Attenzione!" ], "jak029": [ - "You're dead, Erol!" + "Sei morto, Erol!" ], "jak030": [ - "See ya!" + "Ci vediamo!" ], "jak031": [ - "Haha!" + "Ahah!" ], "jak032": [ - "Wooo!" + "Uoh!" ], "jak033": [ - "Last lap!" + "Ultimo giro!" ], "jak034": [ - "Later." + "A più tardi." ], "jak035": [ - "We gotta catch up!" + "Dobbiamo rimontare!" ], "jak036": [ - "Eccolo!" + "Eccolo lì!" ], "jak037": [ - "Come on, baby, show me what you got!" + "Forza, baby, fammi vedere chi sei!" ], "jak038": [ - "Here we go!" + "Andiamo!" ], "jak039": [ - "Urgh!" + "Guh!" ], "jak040": [ - "I'll take this." + "Questo lo prendo io." ], "jak041": [ - "I need to borrow this." + "Lo prendo in prestito." ], "jak042": [ - "Move over, buddy!" + "Spostati, amico!" ], "jak044": [ - "Outta the vehicle!" + "Fuori da quel veicolo!" ], "jak045": [ - "Outta my way, buddy!" + "Togliti dai piedi!" ], "jak046": [ - "Thanks for the lift." + "Grazie per il passaggio." ], "jak047": [ - "Mind if I drive?" + "Ti spiace se guido io?" ], "jak048": [ - "I like the color of this vehicle." + "Bello il colore di questo veicolo." ], "jak049": [ - "Mine now." + "Ora è mio." ], "jak050": [ - "'Scuse me, but I need this." + "Scusa, ma serve a me." ], "jak051": [ - "Take a hike, buddy!" + "Fai l'autostop, amico!" ], "jak052": [ - "Try walking." + "Prova a camminare." ], "jak053": [ - "Sorry, but I'm in a hurry!" + "Scusa, ma sono di fretta!" ], "jak054": [ - "Gotta go!" + "Devo andare!" ], "jak055": [ - "Get another vehicle!" + "Prendi un altro mezzo!" ], "jak056": [ - "Road hog!" + "Pirata!" ], "jak057": [ - "Brake yourself!" + "Va' al diavolo!" ], "jak059": [ - "Haha, you want some?" + "Eheh, ne vuoi ancora?" ], "jak060": [ - "Get some!" + "Prendi questo!" ], "jak061": [ - "Yeah, feel it!" + "Sì, come ti senti?" ], "jak062": [ - "Die!" + "Muori!" ], "jak063": [ - "Badass comin' through!" + "Il cattivone sta arrivando!" ], "jak064": [ - "Be afraid. Be very afraid." + "Se fossi in te, comincerei a tremare, amico." ], "jak065": [ - "Oooh, that's gotta hurt." + "Uuuh, fa male, vero?" ], "jak066": [ - "This is payback." + "Questa è la mia vendetta." ], "jak067": [ - "DIE, Praxis!" + "MUORI, Praxis!" ], "jak068": [ - "You're finished, Kor!" + "Sei finito, Kor!" ], "jak069": [ - "This is my town, Kor!" + "Questa è la mia città, Kor!" ], "jak070": [ - "Surprise... you can't kill me in my dark form." + "Sorpresa, non puoi uccidermi nella mia forma oscura." ], "jak071": [ - "Now you pay!" + "Ora la pagherai!" ], "jak072": [ - "Go back to the past, Kor! 'Cause you're history." + "Torna al passato, Kor! Perché sei storia." ], "jak073": [ - "I win." + "Ho vinto." ], "jak074": [ - "You should have killed me when you had the chance, Praxis." + "Dovevi uccidermi quando ne avevi la possibilità, Praxis." ], "jak075": [ - "Daxter, just shut up and watch my back." + "Daxter, taci e guardami le spalle." ], "jak076": [ - "Whatever, Daxter." + "Come vuoi, Daxter." ], "jak077": [ - "Will you stop yappin'?" + "Vuoi tacere un attimo?" ], "jak078": [ - "When you got smaller, so did your brain." + "Ti si è rimpicciolito tutto, anche il cervello." ], "jak079": [ - "You're on MY shoulder. YOU'RE the sidekick." + "TU sei sulla mia spalla. TU sei l'aiutante." ], "jak080": [ - "As long as you're on MY shoulder, keep your mouth shut." + "Finché stai sulla mia spalla, tieni chiusa la bocca." ], "jd001": [ - "Hey, kid! Wait! Come back!", - "We gotta protect him!" + "Bambino! Aspetta! Torna indietro!", + "Dobbiamo proteggerlo!" ], "jk001": [ - "Wait, KID!" + "Aspetta! Bambino!" ], "jk002": [ - "There he goes!" + "Iniziamo!" ], "jk003": [ - "Leave him alone!" + "Lasciatelo in pace!" ], "jk004": [ - "KID!" + "BAMBINO!" ], "jk005": [ - "Pick on someone your own size!" + "Prenditela con uno come te!" ], "jk006": [ - "Kid, look out!" + "Bambino, attento!" ], "jk007": [ - "How do YOU like it when somebody fights back?" + "È più divertente quando qualcuno si difende?" ], "jk008": [ - "Leave the kid alone!" + "Lasciate stare il bambino!" ], "jk009": [ - "He's just a kid!" + "È solo un bambino!" ], "jk010": [ - "Keep away from him!" + "State lontani da lui!" ], "jk011": [ - "Now you've pissed me off!" + "Ora mi avete fatto arrabbiare!" ], "jk012": [ - "Eat this!" + "Prendi questo!" ], "jk013": [ - "Back off!" + "Indietro!" ], "jk014": [ - "We gotta get in the vehicle with the Kid!" + "Entriamo nel veicolo col bambino!" ], "jk015": [ - "Hold on!" + "Fermo!" ], "jk016": [ - "Keep your head down, Kid!" + "Giù la testa, piccolo!" ], "jk017": [ - "Stick with me, Kid, and you'll be safe." + "Stai con me e sarai al sicuro." ], "jk018": [ - "Stay with me, Kid!" + "Stai con me, bambino!" ], "jk019": [ - "Get in the vehicle, Dax!" + "Nel veicolo, Dax!" ], "kei001": [ - "You can get on and off the JET-Board at any time." + "Puoi salire e scendere dal JET-Board in qualunque momento." ], "kei002": [ - "You can jump on your JET-Board!" + "Sul tuo JET-Board puoi fare dei salti!" ], "kei003": [ - "Jump up on that ledge." + "Salta su quel muretto!" ], "kei004": [ - "Try jumping up on that crate." + "Prova a saltare su quella cassa!" ], "kei005": [ - "Jump over that obstacle." + "Salta oltre quell'ostacolo." ], "kei006": [ - "You can get a higher jump by ducking before you jump!" + "Puoi saltare ancora più in alto se prima ti accovacci!" ], "kei007": [ - "Try doing a duck jump over that obstacle." + "Prova a darti lo slancio per saltare quell'ostacolo." ], "kei008": [ - "Jump and jump again a little after you've landed", - "for an even bigger launch!" + "Salta, e appena atterrato, salta di nuovo.", + "Otterrai una spinta addirittura maggiore!" ], "kei009": [ - "Try getting up on that higher ledge with a boost jump!" + "Prova a raggiungere quel muretto più in alto con un gran salto!" ], "kei010": [ - "You can spin in the air!" + "Mentre sei in aria, puoi ruotare!" ], "kei011": [ - "Land a perfect 360 for a speed boost!" + "Se ruoti di 360 gradi, avrai una spinta in avanti!" ], "kei012": [ - "Nice spin!" + "Ottima giravolta!" ], "kei013": [ - "You can land on a rail and grind across it." + "Puoi atterrare su un corrimano e fare un grind." ], "kei014": [ - "Try grinding on that rail." + "Fai un grind su quella ringhiera." ], "kei016": [ - "You can do flips while you jump!" + "Mentre salti, puoi fare dei flip!" ], "kei017": [ - "You can also do tricks for fun." + "Divertiti a fare delle evoluzioni." ], "kei018": [ - "Try to put a number of moves together to get points." + "Prova a concatenare più mosse, una dopo l'altra, per fare punti." ], "kei019": [ - "Get enough points to win the challenge!" + "Se fai abbastanza punti, vinci la sfida!" ], "kei020": [ - "Not enough points! Work on your moves." + "Non hai abbastanza punti! Migliora le tue mosse." ], "kei021": [ - "Good job!" + "Ottimo lavoro!" ], "kei022": [ - "Close, but not quite there." + "Quasi, ma non è abbastanza." ], "kei023": [ - "Try again." + "Riprova." ], "kei024": [ - "A little more work and you just might win!" + "Ancora un piccolo sforzo e puoi vincere!" ], "kei025": [ - "No good! Not enough points." + "Non va bene! Non hai abbastanza punti." ], "kei026": [ - "The Underground said you needed some help,", - "you won't be able to catch those Metal Heads in the", - "Forest on foot so I've left my JET-Board at the airlock", - "near the city exit. Since you're helping the Underground,", - "I'll even let you keep it!" + "Il Mondo Sotterraneo ha chiesto aiuto,", + "non prenderai mai quelle Teste di", + "Metallo nella Foresta a piedi. Il mio JET-Board è al portello", + "all'uscita della città. Potrei lasciartelo tenere, visto che aiuti", + "il Mondo Sotterraneo!" ], "kei027": [ - "Jak, this is Keira. Don't forget - I still need two artifacts", - "to make the Rift Rider work! I need the Time Map and the", - "Heart of Mar Energy Gem, or we're not going anywhere!" + "Jak, parla Kiera. Non dimenticare che per far funzionare il Rift Rider,", + "mi servono questi due artefatti: la Mappa del Tempo e la", + "gemma energetica Cuore di Mar, o non andremo da nessuna parte!" ], "kei028": [ - "I still need those two artifacts or this pile of junk", - "won't move one city block, much less through the Rift", - "and back to our own time!", - "You've got to find the Heart of Mar and the Time Map", - "or we're stuck!" + "Mi servono quei due artefatti o questo cumulo di", + "rottami non si sposterà di un metro, figurati", + "riportarci alla nostra epoca!", + "Devi trovare il Cuore di Mar e la Mappa del Tempo", + "o resteremo tutti qui!" ], "kei029": [ - "This is Keira. Thanks for getting the artifacts, guys.", - "It's strange... the Time Map had a bunch of old coordinates", - "in it. Come see me at the Stadium." + "Parla Kiera. Grazie per aver recuperato gli", + "artefatti. È strano...ma la mappa del tempo mostrava un gruppo di vecchie", + "coordinate. Incontriamoci allo Stadio." ], "kg001": [ - "Call for backup!" + "Servono rinforzi!" ], "kg001a": [ - "Call for backup!" + "Servono rinforzi!" ], "kg002": [ - "Freeze!" + "Fermo!" ], "kg002a": [ - "Freeze!" + "Fermo!" ], "kg004": [ "Halt!" ], "kg004a": [ - "Halt!" + "Alt!" ], "kg005": [ - "Get more cruisers in here!" + "Servono altri incrociatori!" ], "kg005a": [ - "Get more cruisers in here!" + "Servono altri incrociatori!" ], "kg006": [ - "Surrender!" + "Arrenditi!" ], "kg006a": [ - "Surrender!" + "Arrenditi!" ], "kg007": [ - "Quì il volo è vietato!" + "Qui il volo è vietato!" ], "kg007a": [ - "Quì il volo è vietato!" + "Qui il volo è vietato!" ], "kg008": [ "Fermo!" @@ -4275,28 +4262,28 @@ "Fermo!" ], "kg009": [ - "Say good night!" + "Sorridi, amico!" ], "kg010": [ "Chiudete l'area." ], "kg011": [ - "Stop the vehicle!" + "Ferma il veicolo!" ], "kg011a": [ - "Stop the vehicle!" + "Ferma il veicolo!" ], "kg012": [ - "You're under arrest!" + "Sei in arresto!" ], "kg012a": [ - "You're under arrest!" + "Sei in arresto!" ], "kg013": [ - "You there!" + "Ehi tu!" ], "kg014": [ - "You want some?!" + "Un po' di piombo?!" ], "kg015": [ "L'accesso è vietato." @@ -4305,67 +4292,67 @@ "Stop!" ], "kg018": [ - "Hey!" + "Ehi!" ], "kg019": [ - "We do this the easy way, or the hard way." + "Puoi scegliere: le buone o le cattive." ], "kg020": [ - "Slow down!" + "Rallenta!" ], "kg020a": [ - "Slow down!" + "Rallenta!" ], "kg021": [ - "Move over!" + "Muoviti!" ], "kg021a": [ - "Move over!" + "Muoviti!" ], "kg022": [ - "Call in more Hellcats!" + "Chiama altri Hellcat!" ], "kg023": [ - "Requesting backup!" + "Richiedo rinforzi!" ], "kg023a": [ - "Requesting backup!" + "Richiedo rinforzi!" ], "kg024": [ - "Suspect on foot!" + "Sospetto a piedi!" ], "kg024a": [ - "Suspect on foot!" + "Sospetto a piedi!" ], "kg025": [ - "Suspect in vehicle!" + "Sospetto in un veicolo!" ], "kg025a": [ - "Suspect in vehicle!" + "Sospetto in un veicolo!" ], "kg026": [ - "Suspect fleeing into sector five!" + "Sospetto in volo nel settore cinque!" ], "kg026a": [ - "Suspect fleeing into sector five!" + "Sospetto in volo nel settore cinque!" ], "kg027": [ - "Suspect moving to sector six!" + "Sospetto nel settore sei!" ], "kg027a": [ - "Suspect moving into sector six!" + "Sospetto nel settore sei!" ], "kg028": [ - "High-speed chase in sector four!" + "Inseguimento nel settore quattro!" ], "kg028a": [ - "High-speed chase in sector four!" + "Inseguimento nel settore quattro!" ], "kg029": [ - "Checking sector three." + "Controllo settore tre." ], "kg029a": [ - "Checking sector three." + "Controllo settore tre." ], "kg030": [ "Pattugliamento settore nove." @@ -4404,16 +4391,16 @@ "Nulla fin ora." ], "kg036": [ - "Roger that, still looking." + "Ricevuto, continuo a cercare." ], "kg036a": [ - "Roger that, still looking." + "Ricevuto, continuo a cercare." ], "kg037": [ - "Roger, we'll shoot on sight." + "Ricevuto, spariamo a vista." ], "kg037a": [ - "Roger, we'll shoot on sight." + "Ricevuto, spariamo a vista." ], "kg038": [ "Comunicare la descrizione dei sospetti." @@ -4425,364 +4412,364 @@ "Fuori dal veicolo!" ], "kg040": [ - "Call in more Hellcats!" + "Chiama altri Hellcat!" ], "kg040a": [ - "Call in more Hellcats!" + "Chiama altri Hellcat!" ], "kg041": [ - "The area is secure." + "L'area è sicura." ], "kg041a": [ - "The area is secure." + "L'area è sicura." ], "kg042": [ - "Nothing to report." + "Nulla da segnalare." ], "kg042a": [ - "Nothing to report." + "Nulla da segnalare." ], "kg043": [ - "Proceeding as planned." + "Procedo come stabilito." ], "kg043a": [ - "Proceeding as planned." + "Procedo come stabilito." ], "kg044": [ - "I lost him." + "L'ho perso." ], "kg044a": [ - "I lost him." + "L'ho perso!" ], "kg045": [ - "Subject is not in sight." + "Sospetto non in vista." ], "kg045a": [ - "Subject not in sight." + "Sospetto non in vista!" ], "kg046": [ - "He's gone." + "È scomparso." ], "kg046a": [ - "He disappeared!" + "È scomparso!" ], "kg047": [ - "Where'd he go?" + "Dov'è andato?" ], "kg047a": [ - "Where'd he go?" + "Dov'è andato?" ], "kg048": [ - "Lost visual contact." + "Ho perso il contatto visivo." ], "kg048a": [ - "Lost visual contact." + "Ho perso il contatto visivo!" ], "kg049": [ - "He just ducked out." + "Si è dileguato." ], "kg049a": [ - "He just ducked out." + "Si è dileguato!" ], "kg050": [ - "He's out of sight." + "Non è più in vista." ], "kg050a": [ - "He's out of sight." + "Non è più in vista!" ], "kg051": [ - "We're losing him!" + "L'abbiamo perso!" ], "kg051a": [ - "We're losing him!" + "L'abbiamo perso!" ], "kg052": [ - "Continuing our sweep." + "Proseguiamo la perlustrazione." ], "kg052a": [ - "Continuing our sweep." + "Proseguiamo la perlustrazione." ], "kg053": [ - "Searching sector four." + "Perlustrazione settore quattro." ], "kg053a": [ - "Searching sector four." + "Perlustrazione settore quattro." ], "kg054": [ - "Searching sector seven." + "Perlustrazione settore sette." ], "kg054a": [ - "Searching sector seven." + "Perlustrazione settore sette." ], "kg055": [ - "Searching sector three." + "Perlustrazione settore tre." ], "kg055a": [ - "Searching sector three." + "Perlustrazione settore tre." ], "kg056": [ - "Keep looking." + "Ricerca in corso." ], "kg056a": [ - "Keep looking." + "Ricerca in corso!" ], "kg057": [ - "He's got to be here somewhere." + "Deve essere qui da qualche parte." ], "kg057a": [ - "He's got to be here somewhere." + "Deve essere qui da qualche parte." ], "kg058": [ - "I can't find him." + "Non riesco a trovarlo." ], "kg058a": [ - "I can't find him." + "Non riesco a trovarlo!" ], "kg059": [ - "No sign of the subject." + "Nessuna traccia del soggetto." ], "kg059a": [ - "No sign of the subject." + "Nessuna traccia del soggetto!" ], "kg060": [ - "I don't see him anywhere." + "Non lo vedo da nessuna parte." ], "kg060a": [ - "I don't see him anywhere." + "Non lo vedo da nessuna parte!" ], "kg061": [ - "Still searching." + "Continua a cercare." ], "kg061a": [ - "Still searching." + "Continua a cercare." ], "kg062": [ - "Searching for the target." + "Ricerca del soggetto in corso." ], "kg062a": [ - "Searching for the target." + "Ricerca del soggetto in corso." ], "kg063": [ - "He must be here." + "Deve essere qui." ], "kg063a": [ - "He must be here." + "Deve essere qui." ], "kg064": [ - "He was just here." + "Era proprio qui." ], "kg064a": [ - "He was just here." + "Era proprio qui!" ], "kg065": [ - "We lost him." + "L'abbiamo perso." ], "kg065a": [ - "We lost him." + "L'abbiamo perso." ], "kg066": [ - "He got away." + "È scomparso." ], "kg066a": [ - "He got away." + "È scomparso!" ], "kg067": [ - "He escaped." + "È fuggito." ], "kg067a": [ - "He escaped." + "È fuggito!" ], "kg068": [ - "He shook us." + "Ci ha seminati." ], "kg068a": [ - "He shook us." + "Ci ha seminati." ], "kg069": [ - "Looks like he's gone." + "Sembra sia sparito." ], "kg069a": [ - "Looks like he's gone." + "Sembra sia sparito." ], "kg070": [ - "I found him!" + "L'ho trovato!" ], "kg070a": [ - "I found him!" + "L'ho trovato!" ], "kg071": [ - "Eccolo." + "Eccolo!" ], "kg071a": [ "Eccolo!" ], "kg072": [ - "Be advised, target in sight." + "Attenzione, soggetto in vista." ], "kg072a": [ - "Be advised, target in sight!" + "Attenzione, soggetto in vista!" ], "kg073": [ - "We have a positive ID." + "Soggetto identificato." ], "kg073a": [ - "We have a positive ID." + "Soggetto identificato!" ], "kg074": [ - "I see him!" + "Lo vedo!" ], "kg074a": [ - "I see him!" + "Lo vedo!" ], "kg075": [ - "He's over there, get him!" + "È da questa parte!" ], "kg075a": [ - "He's over here!" + "È da questa parte!" ], "kg076": [ - "Get him!" + "Prendiamolo!" ], "kg076a": [ - "Get him!" + "Prendiamolo!" ], "kg077": [ - "I've reacquired the target!" + "Obiettivo riacquisito!" ], "kg077a": [ - "I've reacquired the target!" + "Obiettivo riacquisito!" ], "kg078": [ - "I'm closing in." + "Mi sto avvicinando." ], "kg078a": [ - "I'm closing in!" + "Mi sto avvicinando!" ], "kg079": [ - "I'm on him!" + "Ci sono vicino!" ], "kg079a": [ - "I'm on him!" + "Ci sono vicino!" ], "kg080": [ - "I'm in pursuit!" + "Sono all'inseguimento!" ], "kg080a": [ - "I'm in pursuit!" + "Sono all'inseguimento!" ], "kg081": [ - "Pursuing target." + "Inseguo il soggetto." ], "kg081a": [ - "Pursuing target!" + "Inseguo il soggetto!" ], "kg082": [ - "Don't let him get away!" + "Non lasciamolo scappare!" ], "kg082a": [ - "Don't let him get away!" + "Non lasciamolo scappare!" ], "kg083": [ - "Get him!" + "Prendiamolo!" ], "kg083a": [ - "Get him!" + "Prendiamolo!" ], "kg084": [ - "After him!" + "Seguiamolo!" ], "kg084a": [ - "After him!" + "Seguiamolo!" ], "kg085": [ - "I have a visual!" + "Ora lo vedo!" ], "kg085a": [ - "I have a visual!" + "Ora lo vedo!" ], "kg086": [ - "We see him!" + "Lo vedo!" ], "kg086a": [ - "We see him!" + "Lo vedo!" ], "kg087": [ - "Stop right there!" + "Fermo dove sei!" ], "kg087a": [ - "Stop right there!" + "Fermo dove sei!" ], "kg088": [ - "I have a bead on him!" + "Ce l'ho a portata di tiro!" ], "kg088a": [ - "I have a bead on him!" + "Ce l'ho a portata di tiro!" ], "kg089": [ - "I'm hit!" + "Mi ha colpito!" ], "kg089a": [ - "I'm hit!" + "Mi ha colpito!" ], "kg090": [ - "Man down!" + "Uomo a terra!" ], "kg090a": [ - "Man down!" + "Uomo a terra!" ], "kg091": [ - "I need backup!" + "Mi servono rinforzi!" ], "kg091a": [ - "I need backup!" + "Mi servono rinforzi!" ], "kg092": [ - "Stop him!" + "Fermatelo!" ], "kg092a": [ - "Stop him!" + "Fermatelo!" ], "kg093": [ - "Look out!" + "Attenzione!" ], "kg093a": [ - "Look out!" + "Attenzione!" ], "kg094": [ - "There he is, shoot him!" + "Eccolo, sparategli!" ], "kg094a": [ - "There he is, shoot him!" + "Eccolo, sparategli!" ], "kg095": [ - "Take him out!" + "Eliminatelo!" ], "kg095a": [ - "Take him out!" + "Eliminatelo!" ], "kg096": [ - "Prisoner escape in progress, sound the alarm!" + "Fuga in corso, suonare l'allarme!" ], "kg096a": [ - "Prison escape in progress, sound the alarm!" + "Fuga in corso, suonare l'allarme!" ], "kg097": [ "Prigioniero al livello due!" ], "kg097a": [ - "Prisoner on level two!" + "Prigioniero al livello due!" ], "kg098": [ - "Prisoner moving to sub-level B!" + "Prigioniero in direzione del sub-livello B!" ], "kg098a": [ - "Prisoner moving to sub-level B!" + "Prigioniero in direzione del sub-livello B!" ], "kg099": [ - "We think he's in the pipes!" + "Pensiamo sia nei condotti!" ], "kg099a": [ - "We think he's in the pipes!" + "Pensiamo sia nei condotti!" ], "kg100": [ "Iniziamo la perlustrazione." @@ -4791,10 +4778,10 @@ "Iniziamo la perlustrazione." ], "kg101": [ - "We have prisoner in sight, move in!" + "Il prigioniero è in zona, muoviamoci!" ], "kg101a": [ - "We have prisoner in sight, move in!" + "Il prigioniero è in zona. Muoviamoci!" ], "kg102": [ "C'è movimento al livello uno!" @@ -4803,112 +4790,112 @@ "C'è movimento al livello uno!" ], "kg103": [ - "Close in!" + "In avvicinamento." ], "kg103a": [ - "Close in!" + "In avvicinamento!" ], "kg104": [ - "Stiamo entrando!" + "Stiamo entrando." ], "kg104a": [ - "Stiamo entrando!" + "Stiamo entrando." ], "kg105": [ - "Secure the cell block!" + "Sorvegliate le celle!" ], "kg105a": [ - "Secure the cell block!" + "Sorvegliate le celle!" ], "kg106": [ - "Take no prisoners!" + "Non fate prigionieri!" ], "kg106a": [ - "Take no prisoners!" + "Non fate prigionieri!" ], "kg107": [ - "Prisoner sighted, we got him!" + "Prigioniero avvistato, ce l'abbiamo!" ], "kg107a": [ - "Prisoner sighted, we got him!" + "Prigioniero avvistato, ce l'abbiamo!" ], "kg108": [ - "Prisoner is still on the loose!" + "Il prigioniero è fuggito!" ], "kg108a": [ - "Prisoner is still on the loose!" + "Il prigioniero è fuggito!" ], "kg109": [ - "We think he's going for an exit!" + "Crediamo sia diretto all'uscita!" ], "kg109a": [ - "We think he's going for an exit!" + "Crediamo sia diretto all'uscita!" ], "kg110": [ - "Searching rooms." + "Perlustriamo le stanze." ], "kg110a": [ - "Searching rooms." + "Perlustriamo le stanze!" ], "kg111": [ - "Prisoner loose in complex." + "Prigioniero libero nel complesso!" ], "kg111a": [ - "Prisoner loose in complex." + "Prigioniero libero nel complesso!" ], "kg112": [ - "You are authorized to shoot to kill." + "Siamo autorizzati a sparare per uccidere." ], "kg112a": [ - "You are authorized to shoot to kill." + "Siamo autorizzati a sparare per uccidere." ], "kg113": [ - "Go, go, go! Sweep the area!" + "Via, via, via! Perlustrare l'area!" ], "kg113a": [ - "Go go go! Sweep the area!" + "Via, via, via! Perlustrate l'area!" ], "kg114": [ - "Searching the sub-basements." + "Perlustriamo i sotterranei!" ], "kg114a": [ - "Searching the sub-basements." + "Perlustriamo i sotterranei." ], "kg115": [ - "Cell block is clear." + "Zona celle è sicura." ], "kg115a": [ - "Cell block is clear." + "Zona celle sicura." ], "kg116": [ - "Tank room is clear." + "Sala carro sicura." ], "kg116a": [ - "Tank room is clear." + "Sala carro sicura!" ], "kg117": [ - "Activate riot tanks." + "Attivare i carri." ], "kg117a": [ - "Activate riot tanks." + "Attivare i carri!" ], "kg118": [ - "Riot tank has prisoner in sight." + "Il carro ha avvistato il prigioniero." ], "kg118a": [ - "Riot tank has prisoner in sight." + "Il carro ha avvistato il prigioniero!" ], "kg119": [ - "Intruder alert." + "Allarme intruso." ], "kg119a": [ - "Intruder alert!" + "Allarme intruso!" ], "kg120": [ - "Activating security defenses." + "Attivazione sistemi di sicurezza." ], "kg120a": [ - "Activating security defenses." + "Attivazione sistemi di sicurezza." ], "kg121": [ "Fornire la descrizione dei sospetti." @@ -4917,543 +4904,543 @@ "Fornire la descrizione dei sospetti." ], "kg122": [ - "I've got civvies in sight." + "Civili in vista." ], "kg122a": [ - "I've got civvies in sight." + "Ho civili in vista." ], "kg123": [ - "I've got suspects in sight." + "Sospetti in vista." ], "kg123a": [ - "I've got suspects in sight." + "Ho i sospetti in vista." ], "kg124": [ - "I hate the smell of this part of the city." + "Odio l'odore di questa zona della città." ], "kg124a": [ - "I hate the smell in this part of the city." + "Odio l'odore di questa zona della città." ], "kg125": [ - "Right, we'll check it out." + "Ok, controlliamo." ], "kg125a": [ - "Right, we'll check it out." + "Ok, controlliamo." ], "kg126": [ - "Confirmed, Underground suspect neutralized." + "Confermato, sospetto neutralizzato." ], "kg126a": [ - "Confirmed, Underground suspect neutralized." + "Confermato, sospetto neutralizzato." ], "kg127": [ - "They're all guilty!" + "Sono tutti colpevoli!" ], "kg127a": [ - "They're all guilty!" + "Sono tutti colpevoli!" ], "kg128": [ - "This is Unit Alpha, we're en route." + "Qui è Unità Alfa, siamo in marcia." ], "kg128a": [ - "This is Unit Alpha, we're en route." + "Qui è Unità Alfa, siamo in marcia." ], "kg129": [ - "Roger, continuing our sweep." + "Ricevuto, proseguiamo la perlustrazione." ], "kg129a": [ - "Roger, continuing our sweep." + "Ricevuto, proseguiamo la perlustrazione." ], "kg130": [ - "Unit Zulu, moving in." + "Unità Zulu, stiamo entrando." ], "kg130a": [ - "Unit Zulu, moving in." + "Unità Zulu, stiamo entrando!" ], "kg131": [ - "Roger that, we're making our sweep." + "Ricevuto, perlustrazione in corso." ], "kg131a": [ - "Roger that, we're making our sweep." + "Ricevuto, perlustrazione in corso." ], "kg132": [ - "I say shoot 'em all and sort 'em out later." + "Sparate a tutti, li identificheremo dopo." ], "kg132a": [ - "I say shoot 'em all and sort 'em out later." + "Sparate a tutti, li identificheremo dopo." ], "kg133": [ - "You have the right to die!" + "Hai il diritto di morire, amico!" ], "kg134": [ - "Lock and load!" + "Pronto al fuoco!" ], "kg135": [ "Aprite il fuoco!" ], "kg136": [ - "Alert, alert!" + "Allarme, allarme!" ], "kg137": [ - "Don't move!" + "Non muoverti!" ], "kg138": [ - "Do it!" + "Vai!" ], "kg139": [ - "Go, go, go!" + "Via, via, via!" ], "kg140": [ - "Flank 'em!" + "Circondatelo!" ], "kg141": [ - "Move in!" + "Avanziamo!" ], "kg142": [ - "Take 'em out!" + "Eliminatelo!" ], "kg143": [ - "Bust some heads!" + "Spaccate qualche testa!" ], "kg144": [ - "Arrest him!" + "Arrestatelo!" ], "kg145": [ - "Shoot 'em, shoot 'em!" + "Sparategli, sparategli!" ], "kg146": [ - "Die, outlaw!" + "Muori, criminale!" ], "kg147": [ - "You're history!" + "Sei storia, amico!" ], "kg148": [ - "Eat this!" + "Prendi questo!" ], "kg149": [ - "Get some!" + "Prendi!" ], "kg150": [ - "Fire, fire!" + "Fuoco, fuoco!" ], "kg151": [ - "Here's one for the Guard!" + "Eccone uno per la Guardia!" ], "kg152": [ - "Give it up, outlaw!" + "Arrenditi, criminale!" ], "kg153": [ - "Here's some pain!" + "Arriva il giustiziere!" ], "kg154": [ - "Payback time!" + "Rispondete al fuoco!" ], "kg155": [ - "Shoulda given up!" + "Dovresti arrenderti!" ], "kg156": [ - "I need cover fire!" + "Mi serve copertura!" ], "kg157": [ - "Call in reinforcements!" + "Chiamate i rinforzi!" ], "kg158": [ - "I'll shoot!" + "Fermo o sparo!" ], "kg159": [ - "Die!" + "Muori!" ], "kg160": [ - "You're busted!" + "Sei in arresto!" ], "kg161": [ - "Riot in progress!" + "Sommossa in corso!" ], "kg162": [ - "Send in the troops!" + "Mandate le truppe!" ], "kg163": [ - "Give it up!" + "Arrenditi!" ], "kg164": [ - "Make 'em pay!" + "Deve pagarla!" ], "kg165": [ - "Tag 'em and bag 'em!" + "Inseguitelo ed eliminatelo!" ], "kg165a": [ - "Tag 'em and bag 'em!" + "Inseguitelo ed eliminatelo!" ], "kg165b": [ - "Tag 'em and bag 'em!" + "Inseguitelo ed eliminatelo!" ], "kg166": [ - "Another notch for my gun." + "Un'altra tacca per la mia pistola." ], "kg166a": [ - "Another notch for my gun." + "Un'altra tacca per la mia pistola." ], "kg166b": [ - "Another notch for my gun." + "Un'altra tacca per la mia pistola." ], "kg167": [ - "This one was easy!" + "Troppo facile!" ], "kg167a": [ - "This one was easy!" + "Troppo facile!" ], "kg167b": [ - "This one was easy!" + "Troppo facile!" ], "kg168": [ - "Suspect neutralized." + "Sospetto neutralizzato." ], "kg168a": [ - "Suspect neutralized." + "Sospetto neutralizzato." ], "kg168b": [ - "Suspect neutralized." + "Sospetto neutralizzato." ], "kg169": [ - "Didn't even work up a sweat." + "Come bere un bicchier d'acqua." ], "kg169a": [ - "Didn't even work up a sweat." + "Come bere un bicchiere d'acqua." ], "kg169b": [ - "Didn't even work up a sweat." + "Come bere un bicchiere d'acqua." ], "kg170": [ - "Take him in for... questioning, hehehe..." + "Prendetelo per...interrogarlo, ahahahahah..." ], "kg170a": [ - "Take him in for... questioning, hehehe..." + "Prendetelo per...interrogarlo, eheheheheheheheh..." ], "kg170b": [ - "Take him in for... questioning, hehehe..." + "Prendetelo per...interrogarlo, ahahahahahahah..." ], "kg171": [ - "Another one bites the dust." + "Un altro che mangia la polvere." ], "kg171a": [ - "Another one bites the dust." + "Un altro che morde la polvere." ], "kg171b": [ - "Another one bites the dust." + "Un altro che morde la polvere." ], "kg172": [ - "That must have hurt." + "Deve fare male, eh?" ], "kg172a": [ - "That must have hurt." + "Deve fare male, eh?" ], "kg172b": [ - "That must have hurt." + "Deve fare male, eh?" ], "kg173": [ - "There's plenty more where that came from." + "Ce ne sono molti altri da dove viene questo." ], "kg173a": [ - "There's plenty more where that came from." + "Ce ne sono molti altri da dove viene questo." ], "kg173b": [ - "There's plenty more where that came from." + "Ce ne sono molti altri da dove viene questo." ], "kg174": [ - "Citizen scum." + "Feccia!" ], "kg174a": [ - "Citizen scum." + "Feccia!" ], "kg174b": [ - "Citizen scum." + "Feccia." ], "kg175": [ - "Don't fight the law, son." + "Non sfidare la legge, amico." ], "kg175a": [ - "Don't fight the law, son." + "Non sfidare la legge, amico." ], "kg175b": [ - "Don't fight the law, son." + "Non sfidare la legge, amico." ], "kg176": [ "Sei in arresto!" ], "kg177": [ - "Get moving!" + "Muoviamoci!" ], "kg178a": [ - "He vanished!" + "È scomparso!" ], "kg179": [ - "You guys hear about the latest Metal Head attacks?" + "Avete saputo dell'ultimo attacco delle Teste di Metallo?" ], "kg179b": [ - "Oh you guys hear about the latest Metal Head attacks?" + "Avete saputo dell'ultimo attacco delle Teste di Metallo?" ], "kg180": [ - "We lost three squads last week." + "Abbiamo perso tre squadre la settimana scorsa." ], "kg180a": [ - "We lost three squads last week." + "Abbiamo perso tre squadre la settimana scorsa." ], "kg180b": [ - "We lost three squads last week." + "Abbiamo perso tre squadre la settimana scorsa." ], "kg181": [ - "I hear the Underground are getting stronger." + "Il Mondo Sotterraneo si sta rinforzando." ], "kg181a": [ - "I hear the Underground are getting stronger." + "Ho sentito che il Mondo Sotterraneo si sta rinforzando." ], "kg181b": [ - "I hear the Underground are getting stronger." + "Il Mondo Sotterraneo si sta rinforzando." ], "kg182": [ - "Just rumors, private, keep your mouth shut." + "Sono solo voci, soldato, tieni chiusa la bocca." ], "kg182a": [ - "Just rumors, private, keep your mouth shut." + "Sono solo voci, soldato, tieni chiusa la bocca." ], "kg182b": [ - "Just rumors, private, keep your mouth shut." + "Sono solo voci, soldato, tieni chiusa la bocca." ], "kg183": [ - "It's us or them, there's no in-between." + "O noi o loro, non c'è altra scelta." ], "kg183a": [ - "It's us or them, there's no in-between." + "O noi o loro, non c'è altra scelta." ], "kg183b": [ - "It's us or them, there's no in-between." + "O noi o loro, non c'è altra scelta." ], "kg184": [ - "Don't worry, the Baron will save us." + "Non preoccuparti, il Barone ci salverà." ], "kg184a": [ - "Don't worry, the Baron will save us." + "Non preoccuparti, il Barone ci salverà." ], "kg184b": [ - "Don't worry, the Baron will save us." + "Non preoccuparti, il Barone ci salverà." ], "kg185": [ - "I got no faith in nobody." + "Non mi fido di nessuno." ], "kg185a": [ - "I ain't got no faith in nobody." + "Non mi fido di nessuno." ], "kg185b": [ - "I got no faith in nobody." + "Non mi fido di nessuno!" ], "kg186": [ - "Seen that new JX-7 racer? Sweet ride." + "Vedi quel JX-7? È uno splendore." ], "kg186a": [ - "You seen that new JX-7 racer? Sweet ride." + "Vedi quel JX-7? È uno splendore." ], "kg186b": [ - "Seen that new JX-7 racer? It's a sweet ride." + "Vedi quel JX-7? È uno splendore." ], "kg187": [ - "You seen anything?" + "Hai visto tutto?" ], "kg187a": [ - "You seen anything?" + "Hai visto tutto?" ], "kg187b": [ - "You seen anything?" + "Hai visto tutto." ], "kg188": [ - "No." + "Nah." ], "kg188a": [ - "No." + "Nah." ], "kg188b": [ "Nah." ], "kg189": [ - "Keep your eyes peeled." + "Tieni gli occhi aperti." ], "kg189a": [ - "Keep your eyes peeled." + "Tieni gli occhi aperti." ], "kg189b": [ - "Keep your eyes peeled." + "Tieni gli occhi aperti." ], "kg190": [ - "I just got a radio alert, stay frosty." + "Ho ricevuto un allarme radio, stiamo all'erta." ], "kg190a": [ - "I just got a radio alert, stay frosty." + "Ho ricevuto un allarme radio, stiamo all'erta." ], "kg190b": [ - "I just got a radio alert, stay frosty." + "Ho ricevuto un allarme radio, stiamo all'erta." ], "kg191": [ - "Never trust a civilian." + "Mai fidarsi di un civile." ], "kg191a": [ - "Never trust a civilian." + "Mai fidarsi di un civile." ], "kg191b": [ - "Never trust a civilian." + "Mai fidarsi di un civile." ], "kg192": [ - "Never trust anyone." + "Non fidarti di nessuno." ], "kg192a": [ - "Never trust anyone." + "Mai fidarsi di nessuno." ], "kg192b": [ - "Never trust anyone." + "Mai fidarsi di nessuno." ], "kg193": [ - "Long live the KG!" + "Lunga vita ai Kremizi!" ], "kg193a": [ - "Long live the KG!" + "Lunga vita ai Kremizi!" ], "kg193b": [ - "Long live the KG!" + "Lunga vita ai Kremizi!" ], "kg194": [ - "We ain't had a food riot since we brought in them tanks." + "Non abbiamo avuto una sommossa da quando abbiamo i carri." ], "kg194a": [ - "We ain't had a food riot since we brought in them tanks." + "Non abbiamo avuto una sommossa da quando abbiamo i carri." ], "kg194b": [ - "We ain't had a food riot since we brought in them tanks." + "Non abbiamo avuto una sommossa da quando abbiamo i carri." ], "kg195": [ - "I'm bored, I want to crunch heads." + "Sono stanco, voglio spaccare qualche testa." ], "kg195a": [ - "I'm bored, I want to crunch heads." + "Sono stanco, voglio spaccare qualche testa." ], "kg195b": [ - "I'm bored, I want to crunch heads." + "Sono stanco...voglio spaccare qualche testa." ], "kg196": [ - "I want to kick some ass." + "Argh...voglio prendere a calci qualcuno." ], "kg196a": [ - "Ugh... I want to kick some butt." + "Ugh...voglio prendere a calci qualcuno." ], "kg196b": [ - "I want to kick some butt." + "Argh, voglio prendere a calci qualcuno!" ], "kg197": [ - "Did you hear the Underground got our ammo at HQ?" + "Lo sai che il Mondo Sotterraneo ci ha rubato le munizioni?" ], "kg197a": [ - "Did you hear the Underground got to", - "our ammo at HQ?" + "Hai sentito che il Mondo", + "Sotterraneo ha rubato le munizioni?" ], "kg197b": [ - "Did you hear the Underground got to", - "our ammo at HQ?" + "Lo sai che il Mondo Sotterraneo", + "ci ha rubato le munizioni?" ], "kg198": [ - "Payback's a bitch!" + "Facciamogliela vedere!" ], "kg198a": [ - "Payback's a bitch!" + "Facciamogliela vedere." ], "kg198b": [ - "Payback's a bitch!" + "Facciamogliela vedere!" ], "kg199": [ - "Animals!" + "Animali!" ], "kg199a": [ - "Animals!" + "Animali." ], "kg199b": [ - "Animals!" + "Animali!" ], "kg200": [ - "I hear the Shadow's been dead for years." + "Ho sentito che l'Ombra è morto da anni." ], "kg200a": [ - "I hear the Shadow's been dead for years." + "Ho sentito che l'Ombra è morto da anni." ], "kg200b": [ - "I hear the Shadow's been dead for years." + "Ho sentito che l'Ombra è morto da anni." ], "kg201": [ - "Maybe, but the rest of them Underground scum", - "are still scurrying about." + "Forse, ma gli altri del Mondo Sotterraneo", + "sono ancora in giro." ], "kg201a": [ - "Maybe, but the rest of them Underground scum", - "are still scurrying about." + "Forse, ma gli altri del Mondo", + "Sotterraneo sono ancora in giro." ], "kg201b": [ - "Maybe, but the rest of them Underground scum", - "are still scurrying about." + "Forse, ma gli altri del Mondo Sotterraneo sono", + "ancora in giro." ], "kg202": [ - "Can I shoot someone now?" + "Posso sparare a qualcuno ora?" ], "kg202a": [ - "Can I shoot someone now?" + "Posso sparare a qualcuno ora?" ], "kg202b": [ - "Can I shoot someone now?" + "Posso sparare a qualcuno ora?" ], "kg203": [ - "I like the new armor." + "Mi piace la nuova corazza." ], "kg203a": [ - "I like the new armor." + "Mi piace la nuova corazza." ], "kg203b": [ - "I like the new armor." + "Mi piace la nuova corazza." ], "kg204": [ - "Yeah, me too. More comfort in the crotch." + "Sì, anche a me, è più comoda al cavallo." ], "kg204a": [ - "Yeah, me too. More comfort in the crotch." + "Sì, anche a me. È più comoda al cavallo." ], "kg204b": [ - "Yeah, me too. More comfort in the crotch." + "Sì, anche a me. È più comoda al cavallo." ], "kg205": [ - "If something interesting doesn't happen soon,", + "Alla prossima, posso uccidere un civile?", "I'm going to start shooting you." ], "kg205a": [ - "Next time, can I kill a civvy?" + "Alla prossima, posso uccidere un civile?" ], "kg205b": [ - "Next time, can I kill a civvy?" + "Alla prossima, posso uccidere un civile?" ], "kg206a": [ - "If something interesting doesn't happen soon,", - "I'm gonna shoot you." + "Se non succede nulla di", + "interessante, sparo a te." ], "kg206b": [ - "If something interesting doesn't happen soon,", - "I'm gonna start shooting you." + "Se non succede nulla di interessante,", + "sparo a te." ], "kg207": [ - "Did you collect your bribes this week?" + "Raccogliamo bustarelle?" ], "kg207a": [ - "You collect your bribes this week?" + "Raccogliamo bustarelle?" ], "kg207b": [ - "You collect your bribes this week?" + "Raccogliamo bustarelle?" ], "kg208": [ "Shhh..." ], "kg208a": [ - "Shhh..." + "Shh..." ], "kg209": [ "Shh." @@ -5465,241 +5452,237 @@ "Shh." ], "kg210": [ - "I hear someone's been using the old wall airlocks.", - "Pfft, crazy bastard." + "Ho sentito che qualcuno usa i portelli delle vecchie mura.", + "Bastardo." ], "kg210a": [ - "I hear someone's been using the old wall airlocks.", - "Crazy bastard." + "Ho sentito che qualcuno usa i portelli delle vecchie mura.", + "Bastardo." ], "kg210b": [ - "I hear someone's been using the old wall airlocks.", - "Crazy bastard." + "Ho sentito che qualcuno usa i portelli delle vecchie mura.", + "Bastardo!" ], "kg211": [ - "I've been on duty for two days straight." + "Sono in servizio da due giorni." ], "kg211a": [ - "I've been on duty for two days straight." + "Sono in servizio da due giorni." ], "kg211b": [ - "I've been on duty for two days straight." + "Sono in servizio da due giorni." ], "kg212": [ - "Pfft, don't complain. I've got sewer patrol next week." + "Non lamentarti. Settimana pattuglio le fogne." ], "kg212a": [ - "Don't complain, I got sewer patrol next week." + "Non lamentarti, settimana pattuglio le fogne." ], "kg212b": [ - "Don't complain. I got sewer patrol next week." + "Non lamentarti, in settimana pattuglio le fogne." ], "kg213": [ - "Ahh, you poor bastard. Which commander did you piss off?" + "Ah, poveraccio. Quale comandante hai fatto arrabbiare?" ], "kg213a": [ - "Ahh, you poor bastard. Which commander did you piss off?" + "Ah, poveraccio. Quale comandante hai fatto arrabbiare?" ], "kg213b": [ - "Hehe, poor bastard. Which commander did you piss off?" + "Ah, poveraccio. Quale comandante hai fatto arrabbiare?" ], "kg214": [ - "I say death to the Underground." + "Morte al Mondo Sotterraneo!" ], "kg214a": [ - "I say death to the Underground." + "Morte al Mondo Sotterraneo!" ], "kg214b": [ - "I say death to the Underground." + "Morte al Mondo Sotterraneo!" ], "kg215": [ - "I wanna so kill that Shadow guy." + "Voglio uccidere l'Ombra." ], "kg215a": [ - "I want to kill that Shadow guy!" + "Voglio uccidere l'Ombra!" ], "kg215b": [ - "I want to kill that Shadow guy!" + "Voglio uccidere l'Ombra!" ], "kg216": [ - "And don't forget that traitor Torn." + "E ricorda Torn, quel traditore." ], "kg216a": [ - "And don't forget that traitor Torn." + "E ricorda Torn, quel traditore." ], "kg216b": [ - "Don't forget that traitor Torn!" + "E ricorda Torn, quel traditore!" ], "kg217": [ - "Death's too good for him." + "La morte è poco per lui." ], "kg217a": [ - "Death's too good for him." + "La morte è poco per lui." ], "kg217b": [ - "Death's too good for him." + "La morte è poco per lui!" ], "kg218": [ - "Why are we looking for some kid?" + "Perché stiamo cercando dei ragazzini?" ], "kg218a": [ - "Why are we looking for some kid?" + "Perché stiamo cercando dei ragazzini?" ], "kg218b": [ - "Why are we looking for some kid?" + "Perché stiamo cercando dei ragazzini?" ], "kg219": [ - "I don't know, Baron's orders." + "Non lo so, ordini del Barone." ], "kg219a": [ - "I dunno, Baron's orders." + "Non lo so, ordine del Barone." ], "kg219b": [ - "I dunno, Baron's orders." + "Non lo so, ordini del Barone." ], "kg220": [ - "Hey, have they found Mar's Tomb yet?" + "Hanno trovato la Tomba di Mar?" ], "kg220a": [ - "Have they found Mar's Tomb yet?" + "Hanno trovato la Tomba di Mar?" ], "kg220b": [ - "Have they found Mar's Tomb yet?" + "Hanno trovato la Tomba di Mar?" ], "kg221": [ - "They wouldn't tell us if they did." + "No, ma tanto non ce lo direbbero." ], "kg221a": [ - "Nah, they wouldn't tell us if they did." + "No, ma tanto non ce lo direbbero." ], "kg221b": [ - "Nah, they wouldn't tell us if they did." + "No, ma tanto non ce lo direbbero." ], "kg222": [ - "I've got a big bet on the next city races." + "Ho una grossa puntata sulle prossime gare." ], "kg222a": [ - "I got a big bet on the next city races." + "Ho una grossa puntata sulle prossime gare." ], "kg222b": [ - "Got a big bet on the next city races." + "Ho una grossa puntata sulle prossime gare." ], "kg223": [ - "Erol's my boy. He always wins." + "Erol è il mio favorito. Vince sempre." ], "kg223a": [ - "Erol's my boy. He always wins." + "Erol è il mio favorito. Vince sempre." ], "kg223b": [ - "Erol's my boy. He always wins." + "Erol è il mio favorito. Vince sempre." ], "kg224": [ - "You going to the city races this time?" + "Vai alle gare cittadine stavolta?" ], "kg224a": [ - "You going to the city races this time?" + "Vai alle gare cittadine stavolta?" ], "kg224b": [ - "You going to the city races this time?" + "Vai alle gare cittadine stavolta?" ], "kg225": [ - "I'll be there." + "Ci sarò." ], "kg225a": [ - "I'll be there." + "Ci sarò." ], "kg225b": [ - "I'll be there." + "Ci sarò." ], "kg226": [ - "There've been some serious guard casualties this week." + "Questa settimana ci sono stati molti caduti tra le guardie." ], "kg226a": [ - "There've been some serious guard casualties this week." + "Questa settimana ci sono stati molti caduti tra le guardie." ], "kg226b": [ - "There've been some serious guard casualties this week." + "Questa settimana ci sono stati molti caduti tra le guardie." ], "kg227": [ - "Yeah, some rebel fighter is stirring up the pot good." + "Sì, un ribelle sta combinando un inferno." ], "kg227a": [ - "Yeah, some rebel fighter is stirring the pot good." + "Sì, un ribelle sta combinando un inferno." ], "kg227b": [ - "Some rebel fighter is stirring the pot good." + "Sì, un ribelle sta combinando un inferno." ], "kg228": [ - "I'd love to be the one to take him out." + "Come vorrei essere io a farlo fuori." ], "kg228a": [ - "I'd love to be the one to take him out." + "Come vorrei essere io a farlo fuori." ], "kg228b": [ - "Oh I'd love to be the one to take him out." + "Come vorrei essere io a farlo fuori." ], "kg229": [ - "Let's get drinks later." + "Più tardi beviamo un goccio." ], "kg229a": [ - "Let's get drinks later." + "Più tardi beviamo un goccio." ], "kg229b": [ - "Let's get drinks later." + "Più tardi beviamo un goccio." ], "kg230": [ - "I got a bad feeling about this war." + "Questa guerra mi mette una certa ansia." ], "kg230a": [ - "I got a bad feeling about this war." + "Questa guerra mi mette una certa ansia." ], "kg230b": [ - "I got a bad feeling about this war." + "Questa guerra mi mette una certa ansia." ], "kg231": [ - "I hear there are more Metal Head attacks", - "than HQ's admitting." + "Ci sono troppi attacchi di Teste", + "di Metallo." ], "kg231a": [ - "I hear there are more Metal Head attacks", - "than HQ's admitting." + "Ci sono troppi attacchi di", + "Teste di Metallo." ], "kg231b": [ - "Yeah, I hear there are more Metal Head attacks", - "than HQ's admitting." + "Ci sono troppi attacchi di Teste", + "di Metallo." ], "kg232": [ - "The reports I've seen aren't good.", - "I think the city's in trouble." + "I rapporti che ho visto non sono buoni,", + "credo che la città sia nei guai." ], "kg232a": [ - "The reports I've seen aren't good.", - "I think the city's in trouble." + "I rapporti che ho visto non sono buoni.", + "Credo che la città sia nei guai." ], "kg232b": [ - "The reports I've seen aren't good.", - "I think the city's in trouble." + "I rapporti che ho visto non sono buoni,", + "credo che la città sia nei guai." ], "kg233": [ - "I'm worried about this new guy", - "fighting for the Underground." + "Mi preoccupa il nuovo combattente", + "del Mondo Sotterraneo." ], "kg233a": [ - "I'm worried about this new guy", - "fighting for the Underground." - ], - "kg233b": [ - "I'm worried about this new guy fighting for the Underground.", - "fighting for the Underground." + "Mi preoccupa il nuovo combattente", + "del Mondo Sotterraneo." ], "kg234": [ - "Yeah, they say he can change into some kind of... monster." + "Sì, dicono che possa trasformarsi in un mostro." ], "kg234a": [ - "Yeah, they say he can change into some kind of monster." + "Sì, dicono che possa trasformarsi in un mostro." ], "kg234b": [ - "They say he can change into some kind of monster." + "Sì, dicono che possa trasformarsi in un mostro." ], "kg235": [ "Don't worry, his head'll be on the tower wall soon enough." @@ -5738,31 +5721,31 @@ "Hehehe..." ], "kg241a": [ - "Suspect in known Underground vehicle!" + "Sospetto in veicolo del Mondo Sotterraneo!" ], "kg242a": [ - "He's got a cargo, move in!" + "Ha un carico a bordo, muoviamoci!" ], "kg243a": [ "Stop that vehicle!" ], "kg244a": [ - "You're under arrest, pull over!" + "Sei in arresto, fermo!" ], "kg245a": [ - "Surrender the vehicle!" + "Consegna il veicolo!" ], "kg246a": [ - "We are in pursuit!" + "Siamo in inseguimento!" ], "kg247a": [ - "He's got a package!" + "Ha un pacco con sé!" ], "kg248a": [ - "Suspect has suspicious cargo!" + "L'individuo ha un carico sospetto!" ], "kg249a": [ - "We think it's an illegal shipment." + "Pensiamo sia un carico illegale." ], "kg250a": [ "All units close in on vehicle!" @@ -5858,46 +5841,46 @@ "There's a kid, check him out." ], "kg281a": [ - "The Baron wants every kid in this city arrested." + "Il Barone vuole che ogni bambino in città sia arrestato." ], "kg282a": [ - "Surrender the child!" + "Molla il bambino!" ], "kg283a": [ - "Give up the kid!" + "Molla il bambino!" ], "kg284a": [ - "If they won't surrender, kill them all!" + "Se non si arrendono, uccideteli!" ], "kg285a": [ - "Don't kill the kid." + "Non uccidete il bambino." ], "kg286a": [ - "The Baron wants the kid alive!" + "Il Barone vuole il bambino vivo!" ], "kg287a": [ - "Find the boy!" + "Trovate il bambino!" ], "kg288a": [ - "That could be the kid the Baron wants." + "Forse è il bambino che il Barone vuole." ], "kg289a": [ - "After them!" + "Seguiteli!" ], "kg290a": [ - "Don't move, boy!" + "Non muoverti, ragazzo!" ], "kg291a": [ - "Take out that mutt!" + "Eliminate quel bastardo!" ], "kg292a": [ - "We should kill 'em all!" + "Dobbiamo ucciderli!" ], "kg293a": [ - "They've taken a vehicle!" + "Hanno preso un veicolo!" ], "kg294a": [ - "If you get a clear shot, take it!" + "Se ce l'hai a tiro, spara!" ], "kg295a": [ "Suspect is fleeing in vehicle!" @@ -5906,22 +5889,22 @@ "Suspect's vehicle moving through section seven." ], "kg297a": [ - "We think the kid's with that Underground freak." + "Pensiamo che il bambino sia con quello strano tipo." ], "kg298a": [ - "Take 'em out, but keep the kid alive!" + "Fattelo fuori, ma non colpite il bambino!" ], "kg299a": [ - "They're on foot again!" + "Sono di nuovo a piedi!" ], "kg300a": [ "What is that thing?!" ], "kg301a": [ - "Shoot that thing, shoot it!" + "Sparate quella cosa, sparate!" ], "kg302a": [ - "What's he doing?!" + "Cosa sta facendo?!" ], "kg303a": [ "It's that monster!" @@ -5979,35 +5962,35 @@ "This is a raid, do not resist!" ], "kg321a": [ - "Move in!" + "Andiamo!" ], "kg322a": [ - "By order of Baron Praxis,", - "everyone here is to be terminated!" + "Per ordine del Barone Praxis,", + "qui tutti devono essere terminati!" ], "kg323a": [ - "Surrender and you will not suffer much." + "Arrendetevi e non soffrirete molto." ], "kg324a": [ - "It's that Underground monster freak!" + "È quel mostro del Mondo Sotterraneo!" ], "kg325a": [ - "Get him!" + "Prendetelo!" ], "kg326a": [ - "All units converge on Water Slums!" + "Tutte le unità, convergere ai Water Slums!" ], "kg327a": [ - "We've got an Underground fighter!" + "Abbiamo un combattente dal Mondo Sotterraneo!" ], "kg328a": [ - "Burn 'em down!" + "Bruciateli!" ], "kg329a": [ - "Stay together!" + "State uniti!" ], "kg330a": [ - "We've got 'em cornered!" + "L'abbiamo intrappolato!" ], "kg331a": [ "Suspect cornered in section two." @@ -6016,43 +5999,43 @@ "Non c'è via di fuga!" ], "kg333a": [ - "Resistance is futile!" + "La resistenza è inutile!" ], "kg334a": [ - "Give up the artifact, eco freak!" + "Molla l'artefatto, scherzo della natura!" ], "kg335a": [ - "We've cut 'em off!" + "L'abbiamo tagliato fuori!" ], "kg336a": [ - "He's trapped!" + "È in trappola!" ], "kg337a": [ "We got 'em!" ], "kg338a": [ - "We're taking heavy fire!" + "Siamo sotto attacco!" ], "kg339a": [ - "We're taking heavy casualties, send in backup!" + "Stiamo subendo perdite, mandate i rinforzi!" ], "kg340a": [ - "This guy knows how to fight!" + "Questo ragazzo sa come combattere!" ], "kg341a": [ - "Hold your ground!" + "Mantenete le posizioni!" ], "kg342a": [ - "Do not retreat!" + "Non ritiratevi!" ], "kg343a": [ - "We lost Beta squad!" + "La squadra Beta è andata!" ], "kg344a": [ - "We need more men!" + "Mi servono uomini!" ], "kg345a": [ - "He's on the south path!" + "È sul percorso sud!" ], "kg346a": [ "He's in the water!" @@ -6067,7 +6050,7 @@ "Intruder alert, sound the alarm!" ], "kg350a": [ - "The Fortress is under attack!" + "La Fortezza è sotto attacco!" ], "kg351a": [ "This is our house, boy!" @@ -6304,7 +6287,7 @@ "Oof!" ], "kgv001": [ - "Stop!" + "Fermo!" ], "kgv002": [ "Aprite il fuoco!" @@ -6328,7 +6311,7 @@ "Eat this!" ], "kgv009": [ - "Fire, fire!" + "Fuoco, fuoco!" ], "kgv010": [ "Give it up, outlaw!" @@ -6337,7 +6320,7 @@ "Chiudete l'area." ], "kgv012": [ - "Call in reinforcements!" + "Servono rinforzi!" ], "kgv013": [ "Riot in progress!" @@ -6346,7 +6329,7 @@ "Call for backup!" ], "kgv015": [ - "Stop the vehicle!" + "Ferma il veicolo!" ], "kgv016": [ "Sei in arresto!" @@ -6355,7 +6338,7 @@ "Fermo!" ], "kgv018": [ - "Slow down!" + "Rallenta!" ], "kgv019": [ "Move over!" @@ -6364,7 +6347,7 @@ "Fuori dal veicolo!" ], "kgv021": [ - "Call in more Hellcats!" + "Chiamate i Hellcat!" ], "kgv022": [ "Requesting backup!" @@ -6373,60 +6356,60 @@ "High speed chase in sector four!" ], "kgv024": [ - "Suspect in vehicle!" + "Sospetto in un veicolo!" ], "kgv025": [ "Suspect fleeing into sector five." ], "kor001": [ - "I am so proud of you Jak, and you too, Daxter!", - "Together you have done real damage to the Baron.", - "We may win this war yet!" + "Sono così orgoglioso di te Jak, e anche di te, Daxter!", + "Insieme avete inflitto un grosso danno al Barone.", + "Ora potremmo vincere questa guerra!" ], "kor002": [ - "Excellent work, you are proving to be quite an asset.", - "Without eco, the Baron will soon topple,", - "and the city's future will be in our hands." + "Ottimo lavoro, ti stai dimostrando un valido aiuto.", + "Senza eco, il Barone sarà presto in ginocchio", + "e il futuro della città sarà nelle nostre mani." ], "kor004": [ - "Another blow to the Baron, my good friends!", - "Very soon, our fortunes will change!" + "Un altro colpo inflitto al Barone, amici miei!", + "Presto i nostri destini cambieranno!" ], "krew001": [ - "Jak, this is Krew. I just talked to my racing client", - "and she told me you were pretty good with that JET-Board", - "of hers. My sources say a shipment of Krimzon Guard", - "listening equipment just arrived in the Port.", - "None of us, including the Underground, want those devices", - "up and running. It's not good for business.", - "Ride the JET-Board out into the Port", - "and destroy every Krimzon Guard crate you find.", - "There's sure to be a defense perimeter,", - "so watch out, 'ey?" + "Jak, qui è Krew. Ho parlato con il mio cliente", + "e mi ha detto che sei abbastanza abile con il suo JET-Board.", + "Ho saputo da fonti sicure che un carico di apparecchiature per la sorveglianza", + "destinato alle Guardie Kremizi è arrivato al Porto.", + "Nessuno di noi, incluso il Mondo Sotteraneo, vuole che questi", + "dispositivi entrino in funzione. Non è un bene per gli affari.", + "Vai al Porto con il JET-Board e distruggi", + "e distruggi tutte le casse delle Guardie Kremizi.", + "Ci sarà un perimetro difensivo, quindi", + "fai attenzione, hm?" ], "krew002": [ - "Excellent work, Jak. Even I am impressed.", - "I should keep unscrupulous Krimzon Guards", - "out of our business.", - "What's the world coming to when you can't buy off", - "a few guards with bribes?" + "Ottimo lavoro, Jak. Hai impressionato anche me.", + "Questo dovrebbe tenere quelle Guardie Kremizi", + "lontano dai nostri affari.", + "Che mondo è se non è più possibile corrompere", + "qualche guardia, hm?" ], "krew003": [ - "Ooooh... the bedtime stories were true!", - "The fabled Heart of Mar was hidden inside that ugly statue", - "of the old boy.", - "Nothing fractured, nothing gained! That's my motto. Hahaha...", - "For your loyalty, you'll find an excellent gun upgrade", - "stashed in a crate in the Port." + "Ooooh... a volte le favole diventano realtà!", + "Il leggendario Cuore di Mar era in quella mostruosa statua", + "del vecchio ragazzino.", + "Se non si distrugge, non si guadagna! Questo è il mio motto. Ahahahah...", + "Come premio per la tua fedeltà, troverai un potenziamento", + "per il cannone all'interno di una cassa nel Porto." ], "krew004": [ - "That's one turret down. Keep looking!" + "Una torretta distrutta. Continuate a cercare!" ], "krew005": [ - "Two turrets. Good work so far!" + "Due torrette. Bene fino ad ora!" ], "krew006": [ - "Three turrets gone. Nice! Keep it up!" + "Tre torrette andate. Bene! Continuate così!" ], "krew007": [ "Four turrets trashed. Haha... Lovely, boys! Go get 'em!" @@ -6439,17 +6422,17 @@ "Hah, I like the way you work." ], "krew010": [ - "Brass work, boys! You destroyed all the turrets, eh?", - "Now, come back to the Hip Hog." + "Ottimo lavoro, ragazzi! Avete distrutto tutte le torrette.", + "Ora, tornate alla Coscia di Porco." ], "kwbf001": [ - "You know I can't play fair!", - "I have a secret weapon: my duplicity field!", - "Say hello to my little friends...", - "Ah, multiple me! Hahahaha... How delightful." + "Lo sai che non posso combattere onestamente!", + "Ho un'arma segreta: il campo duplicatore!", + "Saluta il mio amico...", + "Moltiplicarmi! Ahahahah... Che bellezza." ], "kwbf002": [ - "Let me introduce you to my... \"crew.\"" + "Permettimi di presentarti alla mia truppa." ], "kwbf003": [ "Let's dance!" @@ -6464,16 +6447,16 @@ "My, don't my twins look stunning?" ], "kwbf007": [ - "You can't stop us all!" + "Non puoi fermarci tutti!" ], "kwbf008": [ "Surprise! More of me than you can handle." ], "kwbf009": [ - "I've a few good men to help me." + "Ho chiamato in aiuto un paio di uomini." ], "kwbf010": [ - "Get him!" + "Prendetelo!" ], "kwbf011": [ "UARGH! Try stopping me now!" @@ -6485,22 +6468,22 @@ "I grow weary of this. We end it now." ], "kwbf014": [ - "Hm-hm, I move pretty fast for a big man, 'ey?" + "Sono abbastanza veloce vista la mia stazza, eh?" ], "kwbf015": [ - "I float like a butterfly and sting like a wumpbee!" + "Volo come una farfalla e pungo come un'ape!" ], "kwbf016": [ - "Urghh!" + "Ough!" ], "kwbf017": [ - "Aurgh!" + "Auuuh!" ], "kwbf018": [ - "Arghh!" + "Eargh!" ], "kwbf019": [ - "Urrghh!" + "Uuuooah!" ], "kwbf020": [ "Urgh, ow!" @@ -6512,7 +6495,7 @@ "Now I have you!" ], "kwbf023": [ - "You cannot win, Jak!" + "Non puoi vincere, Jak!" ], "kwbf024": [ "Here's some pain!" @@ -6521,13 +6504,13 @@ "No!" ], "kwbf026": [ - "You're trying my patience!" + "La mia pazienza ha un limite!" ], "kwbf027": [ - "Stand still!" + "Stai fermo!" ], "kwbf028": [ - "Haha, how did that feel?" + "Ahahah, come ti senti?" ], "kwbf029": [ "You should have walked away when you had a chance." @@ -6536,7 +6519,7 @@ "Pop this!" ], "kwbf031": [ - "You can't stop the bomb, Jak!" + "Non puoi fermare la bomba, Jak!" ], "kwbf032": [ "Hahahaha, that felt good!" @@ -6545,7 +6528,7 @@ "I am the weapon master!" ], "kwbf034": [ - "Had enough?" + "Ne hai prese abbastanza?" ], "kwbf035": [ "Here we come!" @@ -6569,7 +6552,7 @@ "Finally... I get to put you in your place!" ], "kwbf042": [ - "Arghh! You little...!" + "Aughh! Tu...piccolo...!" ], "ora006": [ "Bring me 200 more Metal Head Skull Gems", @@ -6584,34 +6567,34 @@ "over a Dark Power." ], "ora009": [ - "You do not have enough Skull Gems.", - "Come back when you have collected more." + "Non hai abbastanza Gemme del Teschio.", + "Torna quando ne avrai raccolte di più." ], "ora010": [ "I need more Skull Gems." ], "ora011": [ - "Trust not your reliance on weapons." + "Non riporre eccessivamente nelle armi." ], "ora012": [ - "Use only your body and brain for this challenge." + "Usa solo il corpo e il cervello per questa sfida." ], "ora013": [ - "Weapons are for the weak." + "Le armi sono per i deboli." ], "ora014": [ - "You must not use weapons in this challenge." + "Non devi utilizzare armi in questa sfida." ], "pek001": [ - "Groark! I can't believe you actually did this thing!", - "Onin says she will search timelines for answers", - "about these sacred relics. I will find you then." + "Aark! Non posso credere che ci siate riusciti!", + "Onin ha detto che cercherà nelle linee temporali notizie", + "su queste sacre reliquie. Ci vediamo dopo." ], "pek002": [ - "Groark! Whoa... well I'll be a moncaw's uncle, the Light Tower", - "actually does exist! The beam of light is shining somewhere", - "in the city! The Tomb of Mar was right under our noses", - "all along. And thanks to me, you found it!" + "Oh... per mille piume di scimmia, la Torre di Luce esiste!", + "Il raggio di luce splende nella città!", + "La Tomba di Mar è stata tutto il tempo sotto i nostri nasi.", + "E grazie a me, l'avete trovata!" ], "pek003": [ "Wow! As I live and molt, one step closer to the Tomb.", @@ -6638,40 +6621,40 @@ "Keep going, you can do it!" ], "pek014": [ - "Pop any more than the true number of each symbol,", - "and you will be penalized! Groark!" + "Non pensare di far scoppiare simboli che non ci sono,", + "sarai penalizzato! Aark!" ], "pek015": [ - "Ready? Go!" + "Pronto? Via!" ], "pek016": [ "That symbol wasn't there, penalty!" ], "pek017": [ - "Hah, Onin got you! Pop only symbols that you see." + "Hah, Onin ti ha beccato! Fa' scoppiare solo i simboli che vedi." ], "pek018": [ "Here comes another round!", "Give him another burst, Onin girl!" ], "pek019": [ - "She got you again! What is your problem?" + "Ti ha beccato di nuovo! Qual è il problema?" ], "pek020": [ - "I can't believe you've made it this far!" + "Non posso credere che tu sia arrivato fin qui!" ], "pek021": [ - "Quickly! You are missing symbols!" + "Svelto! Stai perdendo dei simboli!" ], "pek022": [ - "You missed some!" + "Ne hai mancati alcuni!" ], "pek023": [ "Faster! Faster!" ], "pek024": [ - "Give it to him, Onin! More, Onin, more!", - "You go, girl, shake what your momma gave you!" + "Fagliela vedere, Onin! Vai, Onin, vai!", + "Avanti, bella, dacci dentro come solo tu sai fare!" ], "pek025": [ "Rockin' in the club." @@ -6680,7 +6663,7 @@ "He can't do that many!" ], "pek027": [ - "What? He's still going?" + "Cosa? È ancora in gioco?" ], "pek028": [ "Let's see if he can handle it." @@ -6689,17 +6672,17 @@ "Go! Come on!" ], "pek030": [ - "Okay, so you're good." + "Okay, non sei male." ], "pek031": [ - "Wow! Not bad." + "Uau! Non male." ], "pek032": [ "Well, I laid an egg." ], "pek033": [ - "Amazing! You actually won!", - "I am without words, and that is rare." + "Incredibile! Hai vinto!", + "Sono senza parole, un evento molto raro." ], "pek034": [ "You got enough points, congratulations!" @@ -6742,8 +6725,8 @@ "it is your only way out." ], "prop004": [ - "Don't try to make a fool out of me, Jak.", - "Just because I haven't killed you yet doesn't", + "Non provare a prendermi in giro, Jak.", + "Solo perché non ti ho ancora ucciso, non vuol", "mean I'm not onto you. The citizens of this city", "worship me because I offer them safety.", "All I ask in return is for their lives.", @@ -6760,7 +6743,7 @@ "Report all sightings immediately!" ], "prop006": [ - "Brave citizens, today is the anniversary of the great", + "Coraggiosi cittadini, oggi è l'anniversario della grande", "battle that ruined our city section we now call", "Dead Town. Remember those who died", "that day and how much we owe the Metal Heads", @@ -6787,7 +6770,7 @@ "and executed." ], "prop009": [ - "Serve your city." + "Servi la tua città." ], "prop010": [ "Sacrifice for your city, and all will prosper!" @@ -6799,7 +6782,7 @@ "All Metal Heads must die!" ], "prop013": [ - "Work hard, and be grateful." + "Lavora duro e sii riconoscente." ], "prop014": [ "Denuncia i disonesti." @@ -6808,7 +6791,7 @@ "Ricorda, anche i tuoi amici possono essere i tuoi nemici." ], "prop016": [ - "Turn in all who subvert." + "Denuncia i sovversivi." ], "prop017": [ "Strength is our only option!" @@ -6839,7 +6822,7 @@ "La giustizia è rapida." ], "prop026": [ - "Il movimento mondo sotterrano è morto!" + "Il movimento Mondo Sotterraneo è morto!" ], "prop027": [ "Join the Krimzon Guard and your family", @@ -6873,7 +6856,7 @@ "Senza la mia forza, non ci sarebbe nessuna città." ], "prop037": [ - "Follow me to a safer future!" + "Seguitemi in un futuro sicuro!" ], "prop038": [ "You are safe inside the walls with me." @@ -6882,7 +6865,7 @@ "Sfidami... e muori." ], "prop040": [ - "Benvenuti a Città Rifugio.", + "Benvenuti a Città Rifugio!", "Tutte le leggi sono in vigore per la vostra sicurezza.", "Obbeditemi e non sarete puniti." ], @@ -6901,8 +6884,8 @@ "be allowed to threaten me or this city's order!" ], "prop044": [ - "To all citizens of this great city, there is a monster", - "among you, masquerading as a man!", + "A tutti i cittadini di questa grande città, tra di voi", + "c'è un mostro, mascherato da un uomo!", "He is dangerous and must be destroyed!", "I offer a reward of eco for his capture, or, if you", "have a loved one in prison, I will exchange them for", @@ -6939,22 +6922,11 @@ ], "prop049": [ "I am disappointed with this city's lack of", - "committment and sacrifice. Work harder! Eat less!", + "commitment and sacrifice. Work harder! Eat less!", "Drink only when I tell you! Sleep is optional.", "We are at war with an outside threat,", "don't make me declare war on you as well!" ], - "prop050": [ - "Greetings, people of this wonderful utopia. This year's", - "championship race will begin shortly. All citizens", - "not under house arrest are invited to come down to", - "the Stadium and watch your favorite son Erol", - "once again show how the Krimzon Guard are the elite", - "warriors of this city. Bring the whole family! The first", - "one thousand children will get a mandatory", - "Krimzon Guard recruitment package and be", - "\"asked\" to join the Guard for life, what a treat!" - ], "prop051": [ "This is your Baron, I am still in control!", "And I assure you, there's absolutely no Metal Heads", @@ -6983,24 +6955,6 @@ "tougher than it looks, imagine how much worse", "it would be if the Metal Heads were in charge!" ], - "prop054": [ - "We've had a few incidents with our lower class labor", - "force lately. If your Lurker is acting up, call Krimzon", - "Animal Control. Is your Lurker in a tree? Stuck in a", - "sewer grate? Foaming at the mouth? Call", - "the friendly officers of the K.A.C. and they will deal", - "with your furry slave. with all the love and care it", - "deserves... then haul it away for reconditioning.", - "Remember, Lurkers can be dangerous!" - ], - "prop055": [ - "Per favore donate generosamente al fondo eco del Barone.", - "Your munificent donation wil be used for a variety", - "of humanitarian needs: bombs, guns, armor, genetic", - "alteration research, all in the name of preserving this", - "wonderful city of ours. Give often, give freely...", - "or it will be taken from you!" - ], "prop056": [ "It can be so lonely at the top and looking down from", "up here I can see that this dirty city is in desperate", @@ -7037,10 +6991,10 @@ "to the end." ], "sam001": [ - "This is Samos. Jak, I need you to go out to the ruins", - "in Dead Town and visit my old hut. It's now time to retrieve", - "something I hid there long ago, good luck! And Daxter...", - "clean up my place while you're out there!" + "Parla Samos. Jak, ho bisogno che tu vada alle rovine", + "della Città Morta a visitare la mia vecchia capanna. È il momento di recuperare", + "qualcosa che ho nascosto molto tempo fa. Buona fortuna!", + "Ah, Daxter, dai una ripulita in giro già che ci sei!" ], "sam002": [ "This is Samos. Now that you boys are here", @@ -7075,92 +7029,92 @@ "We'll meet you at the Nest." ], "sigc001": [ - "Hold on there, we need to teach you how to use this baby!" + "Ehi, fermati, abbiamo bisogno che tu impari a usare questa bellezza!" ], "sigc002": [ - "The Scatter Gun is a good short-range weapon", - "with a wide field of fire." + "Il Mitra è un'arma a corta gittata", + "con un buon arco di tiro." ], "sigc003": [ - "To fire the weapon, press the trigger." + "Per fare fuoco, premi il grilletto." ], "sigc004": [ - "Good! Some kick, huh?" + "Un discreto rinculo!" ], "sigc005": [ - "It's not the fastest firing weapon in the world, though." + "Certo non si tratta dell'arma più veloce al mondo." ], "sigc006": [ - "You can put your weapon away or pull it out at anytime." + "Puoi mettere via o estrarre la tua arma quando vuoi." ], "sigc007": [ - "Try putting the weapon away." + "Prova a metterla via." ], "sigc008": [ - "Easy, huh?" + "Facile, eh?" ], "sigc009": [ - "Now take the weapon back out." + "Ora estraila di nuovo." ], "sigc010": [ - "Good!" + "Bene!" ], "sigc011": [ - "You can find red ammo inside Krimzon Guard crates." + "Troverai le munizioni rosse nelle casse delle Guardie Kremizi." ], "sigc012": [ - "Shoot the crates." + "Spara alle casse." ], "sigc013": [ - "Great, now you're ready!" + "Ottimo, ora sei pronto!" ], "sigc014": [ - "Want to try the Scatter Gun course?" + "Vuoi tentare l'addestramento per il Mitra?" ], "sigc015": [ - "The blaster is a good all-around choice", - "with a nice rate of fire." + "Il Blaster è un'arma per ogni occasione", + "a una buona cadenza di fuoco." ], "sigc016": [ - "This weapon requires more aiming ability." + "Quest'arma richiede una maggiore capacità di mira." ], "sigc017": [ - "You can switch weapon modes at anytime." + "Puoi cambiare le modalità di fuoco quando vuoi." ], "sigc018": [ - "You can find yellow ammo in crates." + "Puoi trovare le munizioni gialle nelle casse." ], "sigc022": [ - "Would you like to test your skills on the gun course?" + "Vuoi metterti alla prova con l'addestramento alle armi?" ], "sigc023": [ "Which course do you want to play?" ], "sigc024": [ - "Shoot every target. The faster you shoot each target", - "the more points you'll get." + "Spara ogni bersaglio. Più velocemente colpisci", + "più punti riceverai." ], "sigc025": [ - "Hold your fire on civvies.", - "Hit a friendly target and points will be deducted." + "Non sparare sui civili.", + "Se colpisci un bersaglio amico, ti verranno tolti dei punti." ], "sigc026": [ - "Good luck." + "Buona fortuna." ], "sigc027": [ - "Lock and load. Ready, go!" + "Colpo in canna. Pronto, via!" ], "sigc028": [ "Perfect! You can be my backup any day." ], "sigc029": [ - "You did it, excellent shooting!" + "Ce l'hai fatta, ottima mira!" ], "sigc030": [ - "Nice shooting! You got potential, kid!" + "Bella mira! Hai stoffa, ragazzo!" ], "sigc031": [ - "Not bad, you'll do." + "Non male, ce la farai." ], "sigc032": [ "Try again, rookie. You're still a bit rusty with that hardware." @@ -7256,15 +7210,15 @@ "Now switch back to the Blaster." ], "sigc073": [ - "You can combo your attacks by kicking,", - "then firing your weapon." + "Noi Cacciatori del Deserto dobbiamo essere veloci.", + "Combina gli attacchi: sferra un calcio e poi spara col'arma." ], "sigc074": [ "Try a kick-shot combo." ], "sigc075": [ - "Kick the first target, then shoot while kicking", - "to automatically hit the second target." + "Dai un calcio al primo bersaglio, poi spara mentre calci", + "e colpirai automaticamente il secondo." ], "sigc076": [ "Great move!" @@ -7279,123 +7233,123 @@ "Give it another shot." ], "sigc080": [ - "Now that's a Wastelander move!", - "They won't know what hit 'em!" + "Ecco una mossa da Cacciatore del Deserto!", + "Non sapranno nemmeno cosa li ha colpiti!" ], "sigc081": [ "Think you can handle the Blaster course?" ], "sigf001": [ - "You wasted 'em all! I'm still not sure why combat Metal Heads", - "are scouting this close to the city. To be honest,", - "I wasn't sure you could handle this gig, nice work!" + "Li avete annientati! Chi sa che ci facevano quelle Teste di Metallo", + "da combattimento vicino alla città. A dire il vero,", + "non pensavo che ce l'avreste fatta. Complimenti, ragazzi!" ], "sigt003": [ - "Here we go!" + "Andiamo!" ], "sigt004": [ - "Follow me!" + "Seguimi!" ], "sigt005": [ - "Get behind me while I toast that tank." + "Resta dietro di me, sparo al serbatoio." ], "sigt006": [ - "Hurry up kid, I don't have all day!" + "Svelti ragazzi, non c'è molto tempo!" ], "sigt007": [ - "This way!" + "Da questa parte!" ], "sigt008": [ - "Toast those bad boys up ahead." + "Friggi quei cattivi là davanti." ], "sigt009": [ - "Quick! Drop the bridge!" + "Svelto! Abbassa il ponte!" ], "sigt010": [ "Jump up and grab the bridge to bring it down." ], "sigt011": [ - "Let's get across the bridge before they come back." + "Attraversiamo il ponte prima che tornino." ], "sigt012": [ - "There's our first target, keep the other creatures back", - "while I charge up the Peacemaker." + "Ecco il primo bersaglio, tenete lontane le creature", + "mentre carico il Peace Maker." ], "sigt013": [ - "That's one fried Metal Head." + "Una testa di metallo, servita rovente." ], "sigt014": [ - "Let's get to the next target." + "Andiamo al prossimo obiettivo." ], "sigt015": [ - "With Metal Heads I say shoot first, ask questions later." + "Con le teste di metallo, prima si spara e dopo si fanno domande." ], "sigt017": [ - "Stay with me!" + "Vieni qui e stammi vicino!" ], "sigt019": [ - "Waste the suckers!" + "Falli a pezzi!" ], "sigt020": [ - "Great, kid, great! Don't get cocky." + "Ottimo ragazzo, ma non ti bottare alla testa!" ], "sigt021": [ - "There's the second scumbag, sittin' pretty." + "Ecco il secondo rifiuto, tutto per noi." ], "sigt022": [ - "Cover me!" + "Coprimi!" ], "sigt023": [ - "Boom, baby! One less Metal Head to think about." + "Bum! Una testa di metallo in meno." ], "sigt024": [ - "Next target." + "Prossimo bersaglio." ], "sigt025": [ - "Watch my six, while I toast this bad boy.", - "The trick is to not hit the pipes." + "Guardami le spalle mentre io friggo questo rottame.", + "Il trucco sta nel non colpire i tubi." ], "sigt026": [ - "Now that's what I call blowing someone's mind." + "Questo è quello che chiamo far fuori qualcuno!" ], "sigt027": [ - "Gotta thread the needle this time." + "Serve uno strumento accurato questa volta." ], "sigt028": [ - "Hahaha, Metal Head flambé." + "Ahahah, teste di metallo flambé!" ], "sigt029": [ - "Look out! We've got company!" + "Attenzione! Abbiamo compagnia!" ], "sigt030": [ - "Damn! My gun's jammed, take over!" + "Accidenti! La mia arma è inceppata, al riparo!" ], "sigt031": [ - "Get 'em while I fix my gun!" + "Devo sistemare la mia arma!" ], "sigt032": [ - "Okay, the Peacemaker is back online. Let's move!" + "Ok, il Peace Maker funziona di nuovo. Muoviamoci!" ], "sigt033": [ - "Last target, then we go home." + "Ultimo bersaglio, poi si va a casa." ], "sigt036": [ - "Here comes trouble." + "Cominciano i problemi." ], "sigt037": [ - "Did ya miss me?" + "Mi avevi perso?" ], "sigt038": [ - "Say \"good night,\" baby." + "Dì le tue preghiere, piccolo." ], "sigt039": [ - "Thanks for covering my butt, that was close!" + "Grazie per la copertura, ci ha mancato poco!" ], "sigt043": [ "Stay with me!" ], "sigt044": [ - "Stay close or we'll both be dead!" + "Resta vicino o saremo morti!" ], "sigt045": [ "Get over here and stay close!" @@ -7422,23 +7376,23 @@ "You want some of this?!" ], "sigt057": [ - "Drop that lift-cap while I hold them off." + "Abbassa quel trespolo, io li trattengo." ], "sigt058": [ "Take 'em all out!" ], "sigt059": [ - "Great, no time to celebrate." + "Grande, ma non c'è tempo." ], "sigt060": [ - "If I can't shoot it, it's someone else's problem.", - "You do something with those blocks." + "Se non posso a sparargli, sarà un problema di qualcun altro.", + "Fai qualcosa con quei blocchi." ], "sigt061": [ - "You gotta figure out the blocks, man." + "Devi capire cosa fare con quei blocchi." ], "sigt062": [ - "Did you hear something?" + "Hai sentito qualcosa?" ], "sigt063": [ "That's one big ugly Metal Head." @@ -7453,40 +7407,40 @@ "Gone with the wind." ], "sigt067": [ - "Later alligator." + "Ci vediamo, amico!" ], "sigt068": [ - "I think that's the last we'll see of him." + "Credo che sia l'ultima volta che lo vediamo." ], "sigt069": [ - "You figure this out, I'll cover your butt." + "Risolvi questo, io ti proteggerò le chiappe." ], "sigt070": [ - "This is your gig, baby. Solve it, so we can go home." + "Questo è il tuo compito, amico. Risolvilo e ce ne andiamo a casa." ], "sigt071": [ "Great, here comes that bad boy again. Move!" ], "sigt072": [ - "Run!" + "Scappa!" ], "sigt073": [ - "Go, go, go!" + "Via, via, via!" ], "sigt074": [ - "He's gaining!" + "Si sta avvicinando!" ], "sigt075": [ - "Keep moving!" + "Continua a muoverti!" ], "sigt076": [ - "Faster!" + "Più veloce!" ], "sigt077": [ - "It's gonna be close!" + "È sempre più vicino!" ], "sigt078": [ - "Move your butts!" + "Muovete le chiappe!" ], "sigt082": [ "Buddy, you don't wanna piss me off." @@ -7522,7 +7476,7 @@ "I love the smell of burning metal!" ], "sigt103": [ - "Just a walk in the park." + "Una passeggiata nel parco." ], "sigt104": [ "Follow me!" @@ -7537,7 +7491,7 @@ "Over here!" ], "sigt108": [ - "Rollin' baby!" + "Andiamo, baby!" ], "sigt109": [ "Blow 'em a kiss of death." @@ -7549,46 +7503,22 @@ "Kiss your shiny butt goodbye!" ], "sigt112": [ - "Born to kill baby!" + "Born to kill, baby!" ], "sigt113": [ "Two to the chest, one to the head." ], - "spot004": [ - "Come out and cheer for me as I destroy the competition once again on the track.", - "This year's racing final will be to die for, I guarantee more thrills and more spills.", - "This time I want blood!...Bring the kids." - ], "tess001": [ - "Hey, guys! This is Tess. Before Krew left, I saw him hide", - "something in the game machine here. Knowing Krew,", - "it's probably something valuable.", - "You might wanna come check it out." - ], - "tor001": [ - "The operation was a success. All Underground members are safe.", - "Come back to the hideout, I have a new mission for you while we wait for this alert to blow over." - ], - "tor002": [ - "That should take some heat off the streets. Good work, I couldn't have done it better myself." - ], - "tor003": [ - "That's it, Jak, you're up! Try not to trigger any alarms, the garrison guards will be tough.", - "Get to the prison cell block and find the prisoners. Once there, we'll turn on the Warp Gate inside to get you all back out. Good luck." - ], - "tor004": [ - "Ok, my old access codes should help Vin turn off the magnetic seal for the Fortress door." - ], - "tor005": [ - "Jak, this is Torn, the city is under Metal Head attack. There's a large force moving toward the city wall from the ocean.", - "We need people manning the tower gunpods to stop that assault. Meet me at the seaside ocean wall in the Port, hurry!", - "We need every man we can get!" + "Ehi, ragazzi! Parla Tess. Ho visto che Krew, prima di andarsene,", + "ha nascosto qualcosa qui nella macchina da gioco. Conoscendolo,", + "probabilmente sarà qualcosa di prezioso.", + "Fareste meglio a venire a vedere." ], "tor007": [ - "Jak, it's a guard roadblock, get out of there!" + "Jak, un posto di blocco delle guardie, esci di lì!" ], "tor008": [ - "They've set up a roadblock, they're onto you!" + "Hanno predisposto un blocco stradale, ti stanno cercando!" ], "torn024": [ "More coming in!" @@ -7606,16 +7536,16 @@ "Wow! What an animal!" ], "tswm005": [ - "You got it!" + "Preso!" ], "tswm006": [ - "Nice slam!" + "Bel colpo!" ], "tswm007": [ "Ooh ho ho, baby!" ], "tswm008": [ - "Great shot, Daxter!" + "Bel colpo, Daxter!" ], "tswm009": [ "You're almost there!" @@ -7669,7 +7599,7 @@ "Yes! You're the man! I mean... the animal." ], "tswm026": [ - "You beat the game, Daxter!" + "Hai battuto il gioco, Daxter!" ], "tswm027": [ "Where'd you learn to pound like that?" @@ -7765,13 +7695,13 @@ "I knew you could do it." ], "vin002": [ - "Okay, the B-Zone Power Grid is back online.", - "Have fun being killed in the Palace." + "Okay, la griglia energetica della Zona B funziona di nuovo.", + "Divertitevi a fare una brutta fine nel Palazzo." ], "vin003": [ - "You destroyed the last of the Metal Head eggs!", - "That should give us a little more eco for the city.", - "Good work!" + "Hai distrutto l'ultimo uovo di Teste di Metallo!", + "Questo dovrebbe darci un po' più di Eco per la città.", + "Bel lavoro!" ], "vin004": [ "You still haven't gotten all the Metal Head eggs!", @@ -7779,9 +7709,9 @@ "a nervous breakdown!" ], "vin011": [ - "Thank goodness you blew up those wells.", - "I sure don't want any more Metal Heads coming around here.", - "Good work, boys! I owe ya one." + "Grazie al cielo hai distrutto quelle sorgenti.", + "Non c'era bisogno di avere altre Teste di Metallo in giro.", + "Bel lavoro, ragazzi! Vi sono debitore." ], "vin012": [ "Good work, guys! The fewer Metal Head eggs", @@ -7789,9 +7719,9 @@ "we'll have to fight!" ], "vin013": [ - "Jak... Kor...", - "Construction... Site...", - "Ngh..." + "Jak...Kor...", + "Presto...il sito...", + "Eh-agh..." ], "vin014": [ "Once again you guys have saved my butt!", @@ -7799,51 +7729,47 @@ "God knows I could use one. Thanks for the help!" ], "vin015": [ - "The shield wall is down! I repeat - the shield wall is down!", - "Sabotage! Kor did it!", - "I knew Metal Heads would be the end of me!", - "OH NO! Metal Heads are at the door!!", - "They're breaking through!!", - "Too many of them!! Jak!!! AHHHH!!!" - ], - "ys001": [ - "Excellent work, boys! Come on back to the Hideout,", - "I have another task for you." + "Il muro di protezione è caduto! Ripeto - il muro di protezione è CA-DU-TO!", + "Sabotaggio! È stato Kor!", + "Lo sapevo, le Teste di Metallo mi faranno a pezzi!", + "OH NO! Le Teste di Metallo sono alla porta!", + "Stanno entrando!", + "Sono troppe! Jak! AHHHH!!!" ], "ys002": [ - "Nice shooting, my boy!", - "Good work, Jak!", - "We'll all sleep a little easier tonight." + "Bella mira, ragazzo!", + "Bel lavoro, Jak!", + "Stanotte dormiremo tutti più tranquilli." ] }, "speakers": { - "agent": "Agent", - "ashelin": "Ashelin", - "baron": "Baron Praxis", + "agent": "Agente", + "ashelin": "Ashlin", + "baron": "Barone Praxis", "brutter": "Brutter", - "citizen-female": "Citizen", - "citizen-male": "Citizen", + "citizen-female": "Cittadina", + "citizen-male": "Cittadino", "computer": "Computer", "darkjak": "Dark Jak", "daxter": "Daxter", "errol": "Erol", "grim": "Grim", - "guard": "Krimzon Guard", - "guard-a": "Guard A", - "guard-b": "Guard B", + "guard": "Guardia Kremizi", + "guard-a": "Guardia A", + "guard-b": "Guardia B", "jak": "Jak", "jinx": "Jinx", - "keira": "Keira", - "keira-before-class-3": "Mechanic", - "kid": "Kid", + "keira": "Kiera", + "keira-before-class-3": "Meccanico", + "kid": "Bambino", "kor": "Kor", "krew": "Krew", "metalkor": "Metal Kor", - "metalkor-before-consite": "Metal Head Leader", + "metalkor-before-consite": "Capo delle Teste di Metallo", "metalkor-intro": "???", "mog": "Mog", "onin": "Onin", - "oracle": "Oracle", + "oracle": "Oracolo", "pecker": "Pecker", "precursor": "Precursor", "samos": "Samos", @@ -7851,7 +7777,7 @@ "tess": "Tess", "torn": "Torn", "vin": "Vin", - "youngsamos": "Young Samos", + "youngsamos": "Samos giovane", "youngsamos-before-rescue": "Samos" } } diff --git a/game/assets/jak2/subtitle/subtitle_lines_ja-JP.json b/game/assets/jak2/subtitle/subtitle_lines_ja-JP.json index d58a25f4fa..6fa9817c56 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_ja-JP.json +++ b/game/assets/jak2/subtitle/subtitle_lines_ja-JP.json @@ -11,9 +11,9 @@ "Jump onto that crate to get over the barricade." ], "DSbop004": [ - "Ooh, that's a high ledge!", - "デカイ段差!ジャンプして空中でもう一度ジャンプだよ!!", - "to reach that one." + "デカイ段差!", + "ジャンプして空中でもう一度ジャンプだよ!!", + "ジャンプして空中でもう一度ジャンプだよ!!" ], "DSbop005": [ "Good job, see? You still got it!" @@ -35,21 +35,21 @@ "Works out some of that anger, eh?" ], "DSbop010": [ - "There are lots of Krimzon Guard crates lying around", - "for the taking. Break that crate!" + "そこら辺に、クリムゾンガードの木箱があるから、", + "壊しちゃおうぜ!" ], "DSbop011": [ - "Good job! That crate had a health pack inside.", - "Pick it up, you'll wanna keep healthy, Jak, or uh heh...", - "who'll do the fighting?" + "イエーイ!ライフパック発見!", + "体力回復させて、オイラのために戦ってくれよ!", + "体力回復させて、オイラのために戦ってくれよ!" ], "DSbop016": [ - "If you jump then dive, you'll crash down to the ground", - "hard enough to break lots of things.", - "Breaking stuff's fun, right?" + "ジャンプしてから飛び込めば、つえー攻撃になるんだぜ!", + "ジャンプしてから飛び込めば、つえー攻撃になるんだぜ!", + "床でも箱でも壊っすちまえ!" ], "DSbop017": [ - "Guards, Jak! Do your, uh... stuff." + "クリムゾンガードだ!いっちゃお!やって…" ], "agnt001": [ "Hey hey, drive carefully!" @@ -713,7 +713,8 @@ ], "bb06int": [ "Jak, we need you to take out another group of Bomb Bots.", - "These mobile weapons keep showing up in the city, we gotta take them out as soon as possible." + "These mobile weapons keep showing up in the city,", + "we gotta take them out as soon as possible." ], "bb06win": [ "Another pile of bomb bot scrap metal for the KG", @@ -724,8 +725,10 @@ "You lost an agent! NOT good at all, Jak! Mission failed!" ], "bb07int": [ - "Torn here, I need you to go out and move more of our Agents to new locations in the city.", - "KG spies are watching our every move, so look out for trouble. Good luck." + "Torn here, I need you to go out and move more of our Agents", + "to new locations in the city.", + "KG spies are watching our every move,", + "so look out for trouble. Good luck." ], "bb07win": [ "Nice shuttle work! You're keepin' people alive out there." @@ -737,7 +740,8 @@ "bb08int": [ "Jak, some of our Agents have been compromised again.", "Find each one and take them to special hideouts in the city.", - "The guard patrols are on high alert, so this is going to be a tough one. Keep your head down!" + "The guard patrols are on high alert,", + "so this is going to be a tough one. Keep your head down!" ], "bb08win": [ "That was good driving, Jak.", @@ -1753,7 +1757,7 @@ "Surrender yourself. You are under arrest." ], "cityv055": [ - "There is no escape." + "逃げても無駄です。" ], "cityv056": [ "You are in a restricted sector. This sector is on high alert." @@ -2158,7 +2162,7 @@ "Let's go back to the Underground Hideout." ], "ds043": [ - "You can get a longer jump by rolling into it." + "転がりジャンプでロング・ジャンプ!" ], "ds044": [ "Use a long jump to get across this gap." @@ -2167,8 +2171,8 @@ "Nice form!" ], "ds046": [ - "If you duck before you jump, you'll go higher.", - "You'll need a high jump to reach the top of this ledge, Jak." + "しゃがみジャンプで高く飛べるぜ!", + "するならあの段差に届くよな?" ], "ds047": [ "Ooh, that's a high one.", @@ -2330,10 +2334,10 @@ "There's Mar's gun, Jak! Let's go check it out." ], "ds162": [ - "These Precursor Orbs are worth a lot now.", - "We might find a few hidden around,", - "or get some doing difficult tasks.", - "We'll be able to buy stuff with 'em!" + "この世界じゃ、オーブは貴重だぜ!", + "苦労しなきゃ手に入るしねー", + "苦労しなきゃ手に入るしねー", + "集めて、何かと交換しようぜ!" ], "ds163": [ "Jak, now that we have the Palace Security Pass,", @@ -2343,9 +2347,9 @@ "Back up to get out of the mech." ], "ds165": [ - "We're free, Jak! Thanks to me.", - "Nice to breathe some fresh air, huh?", - "We'll get that Baron Praxis guy, alright!" + "自由だ!さすがオイラ!", + "空気が美味いね!この気持ちバロンにも伝えたいね!", + "空気が美味いね!この気持ちバロンにも伝えたいね!" ], "ds166": [ "I'm not getting out of this pod", @@ -4911,10 +4915,10 @@ "Activating security defenses." ], "kg121": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg121a": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg122": [ "I've got civvies in sight." @@ -5001,7 +5005,7 @@ "Do it!" ], "kg139": [ - "Go, go, go!" + "ゴー、ゴー、ゴー!" ], "kg140": [ "Flank 'em!" @@ -5689,11 +5693,11 @@ "fighting for the Underground." ], "kg233b": [ - "I'm worried about this new guy fighting for the Underground.", + "I'm worried about this new guy", "fighting for the Underground." ], "kg234": [ - "Yeah, they say he can change into some kind of... monster." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ "Yeah, they say he can change into some kind of monster." @@ -6939,7 +6943,7 @@ ], "prop049": [ "I am disappointed with this city's lack of", - "committment and sacrifice. Work harder! Eat less!", + "commitment and sacrifice. Work harder! Eat less!", "Drink only when I tell you! Sleep is optional.", "We are at war with an outside threat,", "don't make me declare war on you as well!" @@ -6947,13 +6951,14 @@ "prop050": [ "Greetings, people of this wonderful utopia. This year's", "championship race will begin shortly. All citizens", - "not under house arrest are invited to come down to", - "the Stadium and watch your favorite son Erol", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", "once again show how the Krimzon Guard are the elite", - "warriors of this city. Bring the whole family! The first", - "one thousand children will get a mandatory", - "Krimzon Guard recruitment package and be", - "\"asked\" to join the Guard for life, what a treat!" + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ "This is your Baron, I am still in control!", @@ -6984,20 +6989,22 @@ "it would be if the Metal Heads were in charge!" ], "prop054": [ - "We've had a few incidents with our lower class labor", - "force lately. If your Lurker is acting up, call Krimzon", - "Animal Control. Is your Lurker in a tree? Stuck in a", - "sewer grate? Foaming at the mouth? Call", - "the friendly officers of the K.A.C. and they will deal", - "with your furry slave. with all the love and care it", - "deserves... then haul it away for reconditioning.", + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", "Remember, Lurkers can be dangerous!" ], "prop055": [ "Please give generously to the Baron eco fund.", - "Your munificent donation wil be used for a variety", - "of humanitarian needs: bombs, guns, armor, genetic", - "alteration research, all in the name of preserving this", + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", "wonderful city of ours. Give often, give freely...", "or it will be taken from you!" ], @@ -7549,15 +7556,17 @@ "Kiss your shiny butt goodbye!" ], "sigt112": [ - "Born to kill baby!" + "Born to kill, baby!" ], "sigt113": [ "Two to the chest, one to the head." ], "spot004": [ - "Come out and cheer for me as I destroy the competition once again on the track.", - "This year's racing final will be to die for, I guarantee more thrills and more spills.", - "This time I want blood!...Bring the kids." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ "Hey, guys! This is Tess. Before Krew left, I saw him hide", @@ -7566,23 +7575,32 @@ "You might wanna come check it out." ], "tor001": [ - "The operation was a success. All Underground members are safe.", - "Come back to the hideout, I have a new mission for you while we wait for this alert to blow over." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "That should take some heat off the streets. Good work, I couldn't have done it better myself." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "That's it, Jak, you're up! Try not to trigger any alarms, the garrison guards will be tough.", - "Get to the prison cell block and find the prisoners. Once there, we'll turn on the Warp Gate inside to get you all back out. Good luck." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "Ok, my old access codes should help Vin turn off the magnetic seal for the Fortress door." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Jak, this is Torn, the city is under Metal Head attack. There's a large force moving toward the city wall from the ocean.", - "We need people manning the tower gunpods to stop that assault. Meet me at the seaside ocean wall in the Port, hurry!", - "We need every man we can get!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ "Jak, it's a guard roadblock, get out of there!" @@ -7807,8 +7825,8 @@ "Too many of them!! Jak!!! AHHHH!!!" ], "ys001": [ - "Excellent work, boys! Come on back to the Hideout,", - "I have another task for you." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Nice shooting, my boy!", @@ -7818,40 +7836,40 @@ }, "speakers": { "agent": "Agent", - "ashelin": "Ashelin", - "baron": "Baron Praxis", - "brutter": "Brutter", + "ashelin": "アシュリン", + "baron": "バロン・プラクシス", + "brutter": "ブラッター", "citizen-female": "Citizen", "citizen-male": "Citizen", - "computer": "Computer", - "darkjak": "Dark Jak", - "daxter": "Daxter", - "errol": "Erol", - "grim": "Grim", - "guard": "Krimzon Guard", + "computer": "コンピューター", + "darkjak": "ダーク・ジャック", + "daxter": "ダクスター", + "errol": "エロール", + "grim": "グリム", + "guard": "紅装甲衛兵(クリムゾンガード)", "guard-a": "Guard A", "guard-b": "Guard B", - "jak": "Jak", - "jinx": "Jinx", - "keira": "Keira", + "jak": "ジャック", + "jinx": "ジンクス", + "keira": "ケイラ", "keira-before-class-3": "Mechanic", - "kid": "Kid", - "kor": "Kor", - "krew": "Krew", - "metalkor": "Metal Kor", + "kid": "キッド", + "kor": "コール", + "krew": "クルー", + "metalkor": "メタル・コール", "metalkor-before-consite": "Metal Head Leader", "metalkor-intro": "???", - "mog": "Mog", - "onin": "Onin", - "oracle": "Oracle", - "pecker": "Pecker", - "precursor": "Precursor", - "samos": "Samos", - "sig": "Sig", - "tess": "Tess", - "torn": "Torn", - "vin": "Vin", - "youngsamos": "Young Samos", - "youngsamos-before-rescue": "Samos" + "mog": "モグ", + "onin": "オニン", + "oracle": "オラクルの像", + "pecker": "ペッカー", + "precursor": "プリカーソル", + "samos": "セイジ", + "sig": "シーグ", + "tess": "テス", + "torn": "トーン", + "vin": "ビン", + "youngsamos": "若いセイジ", + "youngsamos-before-rescue": "セイジ" } } diff --git a/game/assets/jak2/subtitle/subtitle_lines_lt-LT.json b/game/assets/jak2/subtitle/subtitle_lines_lt-LT.json index 1765e646a1..da30c7da87 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_lt-LT.json +++ b/game/assets/jak2/subtitle/subtitle_lines_lt-LT.json @@ -713,7 +713,8 @@ ], "bb06int": [ "Jak, we need you to take out another group of Bomb Bots.", - "These mobile weapons keep showing up in the city, we gotta take them out as soon as possible." + "These mobile weapons keep showing up in the city,", + "we gotta take them out as soon as possible." ], "bb06win": [ "Another pile of bomb bot scrap metal for the KG", @@ -724,8 +725,10 @@ "You lost an agent! NOT good at all, Jak! Mission failed!" ], "bb07int": [ - "Torn here, I need you to go out and move more of our Agents to new locations in the city.", - "KG spies are watching our every move, so look out for trouble. Good luck." + "Torn here, I need you to go out and move more of our Agents", + "to new locations in the city.", + "KG spies are watching our every move,", + "so look out for trouble. Good luck." ], "bb07win": [ "Nice shuttle work! You're keepin' people alive out there." @@ -737,7 +740,8 @@ "bb08int": [ "Jak, some of our Agents have been compromised again.", "Find each one and take them to special hideouts in the city.", - "The guard patrols are on high alert, so this is going to be a tough one. Keep your head down!" + "The guard patrols are on high alert,", + "so this is going to be a tough one. Keep your head down!" ], "bb08win": [ "That was good driving, Jak.", @@ -4911,10 +4915,10 @@ "Activating security defenses." ], "kg121": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg121a": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg122": [ "I've got civvies in sight." @@ -5689,11 +5693,11 @@ "fighting for the Underground." ], "kg233b": [ - "I'm worried about this new guy fighting for the Underground.", + "I'm worried about this new guy", "fighting for the Underground." ], "kg234": [ - "Yeah, they say he can change into some kind of... monster." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ "Yeah, they say he can change into some kind of monster." @@ -6939,7 +6943,7 @@ ], "prop049": [ "I am disappointed with this city's lack of", - "committment and sacrifice. Work harder! Eat less!", + "commitment and sacrifice. Work harder! Eat less!", "Drink only when I tell you! Sleep is optional.", "We are at war with an outside threat,", "don't make me declare war on you as well!" @@ -6947,13 +6951,14 @@ "prop050": [ "Greetings, people of this wonderful utopia. This year's", "championship race will begin shortly. All citizens", - "not under house arrest are invited to come down to", - "the Stadium and watch your favorite son Erol", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", "once again show how the Krimzon Guard are the elite", - "warriors of this city. Bring the whole family! The first", - "one thousand children will get a mandatory", - "Krimzon Guard recruitment package and be", - "\"asked\" to join the Guard for life, what a treat!" + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ "This is your Baron, I am still in control!", @@ -6984,20 +6989,22 @@ "it would be if the Metal Heads were in charge!" ], "prop054": [ - "We've had a few incidents with our lower class labor", - "force lately. If your Lurker is acting up, call Krimzon", - "Animal Control. Is your Lurker in a tree? Stuck in a", - "sewer grate? Foaming at the mouth? Call", - "the friendly officers of the K.A.C. and they will deal", - "with your furry slave. with all the love and care it", - "deserves... then haul it away for reconditioning.", + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", "Remember, Lurkers can be dangerous!" ], "prop055": [ "Please give generously to the Baron eco fund.", - "Your munificent donation wil be used for a variety", - "of humanitarian needs: bombs, guns, armor, genetic", - "alteration research, all in the name of preserving this", + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", "wonderful city of ours. Give often, give freely...", "or it will be taken from you!" ], @@ -7549,15 +7556,17 @@ "Kiss your shiny butt goodbye!" ], "sigt112": [ - "Born to kill baby!" + "Born to kill, baby!" ], "sigt113": [ "Two to the chest, one to the head." ], "spot004": [ - "Come out and cheer for me as I destroy the competition once again on the track.", - "This year's racing final will be to die for, I guarantee more thrills and more spills.", - "This time I want blood!...Bring the kids." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ "Hey, guys! This is Tess. Before Krew left, I saw him hide", @@ -7566,23 +7575,32 @@ "You might wanna come check it out." ], "tor001": [ - "The operation was a success. All Underground members are safe.", - "Come back to the hideout, I have a new mission for you while we wait for this alert to blow over." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "That should take some heat off the streets. Good work, I couldn't have done it better myself." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "That's it, Jak, you're up! Try not to trigger any alarms, the garrison guards will be tough.", - "Nueikite į kalėjimo kamerų bloką ir suraskite kalinius. Ten nuvykę įjungsime viduje esančius Kelio vartus, kad visi grįžtumėte į laisvę. Sėkmės." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "Ok, my old access codes should help Vin turn off the magnetic seal for the Fortress door." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Džekai, čia Tornas, miestą užpuolė metalo galvos. Nuo vandenyno link miesto sienos juda didelės pajėgos.", - "We need people manning the tower gunpods to stop that assault. Meet me at the seaside ocean wall in the Port, hurry!", - "We need every man we can get!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ "Jak, it's a guard roadblock, get out of there!" @@ -7807,8 +7825,8 @@ "Too many of them!! Jak!!! AHHHH!!!" ], "ys001": [ - "Excellent work, boys! Come on back to the Hideout,", - "I have another task for you." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Nice shooting, my boy!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_nl-NL.json b/game/assets/jak2/subtitle/subtitle_lines_nl-NL.json index d2ab9eed69..3349c8c3a5 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_nl-NL.json +++ b/game/assets/jak2/subtitle/subtitle_lines_nl-NL.json @@ -713,7 +713,8 @@ ], "bb06int": [ "Jak, je moet nog een groep Bomb Bots uitschakelen.", - "Deze mobiele wapens blijven in de stad verschijnen, we moeten ze zo snel mogelijk uitschakelen." + "These mobile weapons keep showing up in the city,", + "we gotta take them out as soon as possible." ], "bb06win": [ "Nog een stapel schroot van bombots voor de KG", @@ -724,8 +725,10 @@ "Je bent een agent kwijt! Helemaal niet goed, Jak! Missie gefaald!" ], "bb07int": [ - "Hier verscheurd, wil ik dat je eropuit gaat en meer van onze agenten naar nieuwe locaties in de stad verplaatst.", - "KG-spionnen houden al onze bewegingen in de gaten, dus pas op voor problemen. Succes." + "Torn here, I need you to go out and move more of our Agents", + "to new locations in the city.", + "KG spies are watching our every move,", + "so look out for trouble. Good luck." ], "bb07win": [ "Mooi pendelwerk! Je houdt mensen daarbuiten in leven." @@ -737,7 +740,8 @@ "bb08int": [ "Jak, sommige van onze agenten zijn opnieuw gecompromitteerd.", "Vind ze allemaal en breng ze naar speciale schuilplaatsen in de stad.", - "De wachtpatrouilles zijn in opperste staat van paraatheid, dus dit wordt een lastige. Houd je hoofd laag!" + "The guard patrols are on high alert,", + "so this is going to be a tough one. Keep your head down!" ], "bb08win": [ "Dat was goed rijden, Jak.", @@ -4911,10 +4915,10 @@ "Beveiligingsmechanismen activeren." ], "kg121": [ - "Gelieve te adviseren, beschrijving van het onderwerp." + "Please advise, suspect's description." ], "kg121a": [ - "Graag advies en een beschrijving van het onderwerp." + "Please advise, suspect's description." ], "kg122": [ "Ik heb burgerkleding op het oog." @@ -5689,11 +5693,11 @@ "vechten voor de ondergrondse." ], "kg233b": [ - "Ik maak me zorgen over deze nieuwe man die voor de Underground vecht.", + "I'm worried about this new guy", "vechten voor de ondergrondse." ], "kg234": [ - "Ja, ze zeggen dat hij kan veranderen in een soort... monster." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ "Ja, ze zeggen dat hij in een soort monster kan veranderen." @@ -6939,7 +6943,7 @@ ], "prop049": [ "Ik ben teleurgesteld over het gebrek aan deze stad", - "toewijding en opoffering. Werk harder! Eet minder!", + "commitment and sacrifice. Work harder! Eat less!", "Drink alleen als ik het je vertel! Slapen is optioneel.", "We zijn in oorlog met een dreiging van buitenaf,", "laat mij ook niet de oorlog aan jou verklaren!" @@ -6947,13 +6951,14 @@ "prop050": [ "Gegroet, mensen van deze prachtige utopie. Deze jaren", "De kampioensrace zal binnenkort beginnen. Alle burgers", - "die niet onder huisarrest staan, worden uitgenodigd om naar beneden te komen", - "het Stadion en kijk naar je favoriete zoon Erol", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", "laat opnieuw zien hoe de Krimzonwacht de elite is", - "strijders van deze stad. Neem het hele gezin mee! De eerste", - "duizend kinderen krijgen een verplichtje", - "Krimzon Guard recruteringspakket en be", - "\"gevraagd\" om voor het leven bij de Garde te gaan, wat een traktatie!" + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ "Dit is jouw Baron, ik heb nog steeds de controle!", @@ -6984,22 +6989,24 @@ "Dat zou het geval zijn als de Metal Heads de leiding hadden!" ], "prop054": [ - "We hebben een paar incidenten gehad met onze arbeiders uit de lagere klassen", - "kracht de laatste tijd. Als je Lurker zich gedraagt, bel dan Krimzon", - "Dier controle. Zit jouw lurker in een boom? Vastgelopen in een", - "riool rooster? Schuimvorming in de mond? Telefoongesprek", - "de vriendelijke officieren van de K.A.C. en zij zullen handelen", - "met je harige slaaf. met alle liefde en zorg", - "verdient... en hem dan weghalen voor reconditionering.", - "Vergeet niet dat Lurkers gevaarlijk kunnen zijn!" + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", + "Remember, Lurkers can be dangerous!" ], "prop055": [ "Geef alstublieft genereus aan het Baron ecofonds.", - "Uw royale donatie zal voor een verscheidenheid worden gebruikt", - "van humanitaire behoeften: bommen, wapens, pantsering, genetische behoeften", - "wijzigingsonderzoek, allemaal in naam van het behoud hiervan", - "prachtige stad van ons. Geef vaak, geef vrijelijk...", - "anders wordt het je afgenomen!" + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", + "wonderful city of ours. Give often, give freely...", + "or it will be taken from you!" ], "prop056": [ "Het kan zo eenzaam zijn aan de top en van daaruit naar beneden kijkend", @@ -7549,15 +7556,17 @@ "Kus je glanzende kont vaarwel!" ], "sigt112": [ - "Geboren om baby te vermoorden!" + "Born to kill, baby!" ], "sigt113": [ "Twee tegen de borst, één tegen het hoofd." ], "spot004": [ - "Kom naar buiten en moedig mij aan terwijl ik de concurrentie opnieuw op de baan vernietig.", - "De racefinale van dit jaar zal om voor te sterven zijn, ik garandeer meer spanning en meer lekkages.", - "Deze keer wil ik bloed!...Breng de kinderen mee." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ "Hallo jongens! Dit is Tess. Voordat Krew vertrok, zag ik hem zich verstoppen", @@ -7566,23 +7575,32 @@ "Misschien wil je eens komen kijken." ], "tor001": [ - "De operatie was een succes. Alle Underground-leden zijn veilig.", - "Kom terug naar de schuilplaats. Ik heb een nieuwe missie voor je terwijl we wachten tot dit alarm voorbij is." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "Dat zou wat warmte uit de straten moeten halen. Goed gedaan, ik had het zelf niet beter kunnen doen." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "Dat is alles, Jak, je bent wakker! Probeer geen alarm te activeren, de garnizoenswachten zullen streng zijn.", - "Ga naar het gevangeniscelblok en vind de gevangenen. Eenmaal daar, zetten we de Warp Gate binnen aan, zodat jullie er allemaal weer uit kunnen komen. Succes." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "Oké, mijn oude toegangscodes zouden Vin moeten helpen de magnetische verzegeling voor de deur van het Fort te sluiten." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Jak, dit is Torn, de stad wordt aangevallen door Metal Head. Er beweegt een grote kracht vanuit de oceaan richting de stadsmuur.", - "We hebben mensen nodig die de torenkanonpods bemannen om die aanval te stoppen. Ontmoet me bij de oceaanmuur aan de kust in de haven, schiet op!", - "Wij hebben iedere man nodig die we kunnen krijgen!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ "Jak, het is een wegversperring voor de bewakers, ga daar weg!" @@ -7807,8 +7825,8 @@ "Te veel van hen!! Jak!!! AHHHH!!!" ], "ys001": [ - "Uitstekend werk, jongens! Kom terug naar de Hideout,", - "Ik heb nog een taak voor je." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Lekker schieten, mijn jongen!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_no-NO.json b/game/assets/jak2/subtitle/subtitle_lines_no-NO.json index afcaf059c6..3849a6c5ca 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_no-NO.json +++ b/game/assets/jak2/subtitle/subtitle_lines_no-NO.json @@ -713,7 +713,8 @@ ], "bb06int": [ "Jak, we need you to take out another group of Bomb Bots.", - "These mobile weapons keep showing up in the city, we gotta take them out as soon as possible." + "These mobile weapons keep showing up in the city,", + "we gotta take them out as soon as possible." ], "bb06win": [ "Another pile of bomb bot scrap metal for the KG", @@ -724,8 +725,10 @@ "You lost an agent! NOT good at all, Jak! Mission failed!" ], "bb07int": [ - "Torn here, I need you to go out and move more of our Agents to new locations in the city.", - "KG spies are watching our every move, so look out for trouble. Good luck." + "Torn here, I need you to go out and move more of our Agents", + "to new locations in the city.", + "KG spies are watching our every move,", + "so look out for trouble. Good luck." ], "bb07win": [ "Nice shuttle work! You're keepin' people alive out there." @@ -737,7 +740,8 @@ "bb08int": [ "Jak, some of our Agents have been compromised again.", "Find each one and take them to special hideouts in the city.", - "The guard patrols are on high alert, so this is going to be a tough one. Keep your head down!" + "The guard patrols are on high alert,", + "so this is going to be a tough one. Keep your head down!" ], "bb08win": [ "That was good driving, Jak.", @@ -4911,10 +4915,10 @@ "Activating security defenses." ], "kg121": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg121a": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg122": [ "I've got civvies in sight." @@ -5689,11 +5693,11 @@ "fighting for the Underground." ], "kg233b": [ - "I'm worried about this new guy fighting for the Underground.", + "I'm worried about this new guy", "fighting for the Underground." ], "kg234": [ - "Yeah, they say he can change into some kind of... monster." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ "Yeah, they say he can change into some kind of monster." @@ -6939,7 +6943,7 @@ ], "prop049": [ "I am disappointed with this city's lack of", - "committment and sacrifice. Work harder! Eat less!", + "commitment and sacrifice. Work harder! Eat less!", "Drink only when I tell you! Sleep is optional.", "We are at war with an outside threat,", "don't make me declare war on you as well!" @@ -6947,13 +6951,14 @@ "prop050": [ "Greetings, people of this wonderful utopia. This year's", "championship race will begin shortly. All citizens", - "not under house arrest are invited to come down to", - "the Stadium and watch your favorite son Erol", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", "once again show how the Krimzon Guard are the elite", - "warriors of this city. Bring the whole family! The first", - "one thousand children will get a mandatory", - "Krimzon Guard recruitment package and be", - "\"asked\" to join the Guard for life, what a treat!" + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ "This is your Baron, I am still in control!", @@ -6984,20 +6989,22 @@ "it would be if the Metal Heads were in charge!" ], "prop054": [ - "We've had a few incidents with our lower class labor", - "force lately. If your Lurker is acting up, call Krimzon", - "Animal Control. Is your Lurker in a tree? Stuck in a", - "sewer grate? Foaming at the mouth? Call", - "the friendly officers of the K.A.C. and they will deal", - "with your furry slave. with all the love and care it", - "deserves... then haul it away for reconditioning.", + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", "Remember, Lurkers can be dangerous!" ], "prop055": [ "Please give generously to the Baron eco fund.", - "Your munificent donation wil be used for a variety", - "of humanitarian needs: bombs, guns, armor, genetic", - "alteration research, all in the name of preserving this", + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", "wonderful city of ours. Give often, give freely...", "or it will be taken from you!" ], @@ -7549,15 +7556,17 @@ "Kiss your shiny butt goodbye!" ], "sigt112": [ - "Born to kill baby!" + "Born to kill, baby!" ], "sigt113": [ "Two to the chest, one to the head." ], "spot004": [ - "Come out and cheer for me as I destroy the competition once again on the track.", - "This year's racing final will be to die for, I guarantee more thrills and more spills.", - "This time I want blood!...Bring the kids." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ "Hey, guys! This is Tess. Before Krew left, I saw him hide", @@ -7566,23 +7575,32 @@ "You might wanna come check it out." ], "tor001": [ - "The operation was a success. All Underground members are safe.", - "Come back to the hideout, I have a new mission for you while we wait for this alert to blow over." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "That should take some heat off the streets. Good work, I couldn't have done it better myself." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "That's it, Jak, you're up! Try not to trigger any alarms, the garrison guards will be tough.", - "Get to the prison cell block and find the prisoners. Once there, we'll turn on the Warp Gate inside to get you all back out. Good luck." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "Ok, my old access codes should help Vin turn off the magnetic seal for the Fortress door." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Jak, this is Torn, the city is under Metal Head attack. There's a large force moving toward the city wall from the ocean.", - "We need people manning the tower gunpods to stop that assault. Meet me at the seaside ocean wall in the Port, hurry!", - "We need every man we can get!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ "Jak, it's a guard roadblock, get out of there!" @@ -7807,8 +7825,8 @@ "Too many of them!! Jak!!! AHHHH!!!" ], "ys001": [ - "Excellent work, boys! Come on back to the Hideout,", - "I have another task for you." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Nice shooting, my boy!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_pl-PL.json b/game/assets/jak2/subtitle/subtitle_lines_pl-PL.json index 6fcf8745cc..b40bddfecc 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_pl-PL.json +++ b/game/assets/jak2/subtitle/subtitle_lines_pl-PL.json @@ -19,34 +19,34 @@ "Dobra robota, widzisz? Dalej to potrafisz!" ], "DSbop006": [ - "Nigdy nie znalazłem tropu ani Keiry, ani Samosa.", + "Nigdy nie znalazłem śladu ani Keiry, ani Samosa.", "Nie mam pojęcia, gdzie oni poszli." ], "DSbop007": [ - "Nie wiem, gdzie wziął nas ten szalony pojazd szczelinowy, ale...", + "Nie mam pojęcia, gdzie wziął nas ten szalony pojazd szczelinowy, ale...", "To jakieś wielkie miasto!" ], "DSbop008": [ "To ciężkie miejsce, Jak. Pamiętasz JEDNAK", - "Pamiętasz, jak się walczy, prawda? Spróbuj rozbić tę skrzynię kopnięciem." + "jak się walczy, prawda? Spróbuj rozbić tę skrzynię kopniakiem." ], "DSbop009": [ "Dobra robota partnerze, świetny kopniak!", - "Oczyść trochę tej złości, co nie?" + "Rozładowuje trochę tej całej złości, co?" ], "DSbop010": [ - "Jest wiele skrzyń Strażnika Krimzonu leżących wokół", + "Jest wiele skrzyń Straży Krimzonu leżących wokół", "do wzięcia. Rozwal tę skrzynię!" ], "DSbop011": [ "Dobra robota! Ta skrzynia miała w środku apteczkę.", - "Podnieś to, jeśli będziesz chciał zachować zdrowie Jak, lub, uh heh...", + "Podnieś ją, jeśli chcesz zostać przy życiu, lub, uh heh...", "kto zajmie się walką?" ], "DSbop016": [ - "Jeśli podskoczysz potem zanurz, rozbijesz się na ziemię", - "wystarczająco ciężko, aby rozbić wiele rzeczy.", - "Przerywasz zabawę, prawda?" + "Jeśli podskoczysz, a potem zanurkujesz, rozbijesz się o ziemię", + "wystarczająco mocno, aby rozwalić sporo rzeczy.", + "Rozwalanie rzeczy to sama frajda, prawda?" ], "DSbop017": [ "Straż, Jak! Rób swoje, uh... sztuczki." @@ -58,7 +58,7 @@ "Uważaj!" ], "agnt003": [ - "Uważaj!" + "Otwórz oczy!" ], "agnt004": [ "Łoł łoł łoł łoł!" @@ -79,10 +79,10 @@ "Ten akurat zabolał!" ], "agnt010": [ - "Bądź czujny, przed nami trudna część miasta." + "Bądź czujny, przed nami ciemna strona miasta." ], "agnt011": [ - "Teraz jesteśmy na to gotowi!" + "Teraz mamy przerąbane!" ], "agnt012": [ "Krzywdzisz cywilów!" @@ -91,13 +91,13 @@ "Nie uderzaj w cywilów, stary!" ], "agnt014": [ - "Człowieku, uważaj na ludzi!" + "Stary, walisz w ludzi!" ], "agnt015": [ "Patrz, gdzie lecisz!" ], "agnt016": [ - "Dalej!" + "Lecisz!" ], "agnt017": [ "Trzymaj głowę nisko!" @@ -106,49 +106,49 @@ "Strzelają do nas!" ], "agnt019": [ - "Jesteśmy martwi jeśli nie będziesz jechał szybciej!" + "Będziemy martwi, jak nie depniesz!" ], "agnt020": [ "Tak trzymaj!" ], "agnt021": [ - "Zrób to, chłopie, zrób to!" + "Zrób to, chłopie, dajesz!" ], "agnt022": [ "Pospiesz się, stary!" ], "agnt023": [ - "Nie będę jechał z tyłu, weź dwuosobowe!" + "Nie będę jechał z tyłu, weź dwuosobowy!" ], "agnt024": [ - "Zdobądź większy pojazd!" + "Znajdź większy wóz!" ], "agnt025": [ "Zdobądź większy pojazd." ], "agnt026": [ - "Zdobądź jedno z dwoma miejscami, czy tak?" + "Znajdź jakiś z dwoma miejscami, dobra?" ], "agnt027": [ - "Zdobądź większy pojazd." + "Zdobądź inny pojazd." ], "agnt028": [ - "Są na nas." + "Wywęszyli nas." ], "agnt029": [ - "Jesteśmy śledzeni." + "Śledzą nas." ], "agnt030": [ - "Dostajemy łomot!" + "Dostajemy bęcki!" ], "agnt031": [ - "Nie możemy zabrać tak dużo!" + "Nie wytrzymamy tak dużo dłużej!" ], "agnt032": [ - "Próbujesz zginąć!?" + "Próbujesz się zabić!?" ], "agnt033": [ - "Gdzie Torn cię znalazł?" + "Skąd cię Torn wytrzasnął?" ], "agnt034": [ "Na pewno jesteś po naszej stronie?" @@ -166,10 +166,10 @@ "Chwała Marowi, że tu dotarliście, Strażnicy Krimzon są wszędzie!" ], "agnt039": [ - "To dobry czas, aby stąd uciekać!" + "Najwyższy czas, zjeżdżajmy stąd!" ], "agnt040": [ - "Dobrze, dobrze, już czas. RUSZAJ, RUSZAJ, RUSZAJ!" + "Dobrze, dobrze, w samą porę. RUCHY, RUCHY, RUCHY!" ], "agnt041": [ "Nareszcie, musimy się ruszyć!" @@ -178,16 +178,16 @@ "Stary, już myślałem, że się nie pojawisz." ], "agnt043": [ - "Nie za późno, lecimy!" + "Jak zwykle w porę, lećmy!" ], "agnt044": [ - "Szybko doprowadź mnie do mojego nowego bezpiecznego domu!" + "Zabierz mnie do mojej nowej kryjówki, migiem!" ], "agnt045": [ "Dzięki, powodzenia!" ], "agnt046": [ - "Dobra robota, idź i ocal resztę naszych chłopaków." + "Dobra robota, leć ocalić resztę naszych chłopców." ], "agnt047": [ "OK, ja stąd spadam!" @@ -196,7 +196,7 @@ "Do zobaczenia na następnym spotkaniu." ], "agnt049": [ - "Dzięki, za ocalenie życia." + "Dzięki, co bym bez ciebie zrobił." ], "agnt050": [ "Tutaj wysiadam." @@ -241,25 +241,25 @@ "Ten akurat zabolał." ], "agnt064": [ - "Bądź czujny, przed nami trudna część miasta." + "Bądź czujny, przed nami ciemna strona miasta." ], "agnt065": [ - "Teraz jesteśmy na to gotowi." + "Teraz mamy przerąbane." ], "agnt066": [ "Krzywdzisz cywilów!" ], "agnt067": [ - "Nie bij cywili!" + "Nie wal w cywilów, stary!" ], "agnt068": [ - "Człowieku, uważaj na ludzi!" + "Stary, walisz w ludzi!" ], "agnt069": [ "Patrz, gdzie lecisz!" ], "agnt070": [ - "Idź, człowieku, idź!" + "Ruszaj, stary, ZJEŻDŻAJ!" ], "agnt071": [ "Trzymaj głowę nisko!" @@ -268,40 +268,40 @@ "Strzelają do nas!" ], "agnt073": [ - "Będziemy martwi jeśli nie będziesz jechał szybciej!" + "Będziemy martwi, jak nie depniesz!" ], "agnt074": [ "Tak trzymaj!" ], "agnt075": [ - "Zrób to, chłopie, zrób to!" + "Zrób to, chłopie, dajesz!" ], "agnt076": [ "Pospiesz się, stary!" ], "agnt077": [ - "Nie będę jechał z tyłu, weź dwuosobowe!" + "Nie będę jechał z tyłu, weź dwuosobowy!" ], "agnt078": [ "Zdobądź większy pojazd." ], "agnt079": [ - "Są na nas!" + "Wywęszyli nas!" ], "agnt080": [ "Jesteśmy śledzeni!" ], "agnt081": [ - "Dostajemy łomot!" + "Dostajemy bęcki!" ], "agnt082": [ - "Nie możemy zabrać tak dużo." + "Nie wytrzymamy tak dużo dłużej." ], "agnt083": [ - "Próbujesz zginąć?" + "Próbujesz się zabić?" ], "agnt084": [ - "Gdzie Torn cię znalazł?" + "Skąd cię Torn wytrzasnął?" ], "agnt085": [ "Na pewno jesteś po naszej stronie?" @@ -316,13 +316,13 @@ "Śmierć Baronowi!" ], "agnt089": [ - "Chwała Marowi, że tu dotarliście, Strażnicy Krimzon są wszędzie!" + "Chwała Marowi, że tu dotarliście, Straż Krimzonu jest wszędzie!" ], "agnt090": [ - "To dobry czas, aby stąd uciekać!" + "Najwyższy czas, zjeżdżajmy stąd!" ], "agnt091": [ - "Dobrze, dobrze, już czas. RUSZAJ, RUSZAJ, RUSZAJ!" + "Dobrze, w samą porę. RUCHY, RUCHY, RUCHY!" ], "agnt092": [ "Nareszcie, musimy iść!" @@ -331,25 +331,25 @@ "Stary, już myślałem, że się nie pojawisz." ], "agnt094": [ - "Nie za późno, lecimy!" + "Jak zwykle w porę, lećmy!" ], "agnt095": [ - "Szybko doprowadź mnie do mojego nowego bezpiecznego domu!" + "Zabierz mnie do mojej nowej kryjówki, migiem!" ], "agnt096": [ "Dzięki, powodzenia!" ], "agnt097": [ - "Dobra robota, idź i ocal resztę naszych chłopaków." + "Dobra robota, leć ocalić resztę naszych chłopców." ], "agnt098": [ - "Okej, ja stąd spadam!" + "Dobra, ja stąd spadam!" ], "agnt099": [ - "Do następnego razu!" + "Do następnego spotkania!" ], "agnt100": [ - "Dzięki, za ocalenie życia." + "Dzięki, co bym bez ciebie zrobił." ], "agnt101": [ "Tutaj wysiadam." @@ -403,16 +403,16 @@ "Patrz na drogę!" ], "agnt118": [ - "Uważaj!" + "Otwórz oczy!" ], "agnt119": [ "Dzięki za podwózkę." ], "agnt120": [ - "Do następnego razu." + "Do następnego spotkania." ], "agnt121": [ - "Dobra, chodźmy!" + "Dobra, lećmy!" ], "agnt122": [ "Jedź, stary, jedź!" @@ -442,13 +442,13 @@ "Ok, dzięki, powodzenia!" ], "agnt131": [ - "Co zajęło cię tak długo?" + "Co ci zajęło tak długo?" ], "agnt132": [ "Poruszaj się tak, jakbyś miał cel, człowieku!" ], "agnt133": [ - "Idź, idź, KG są za nami!" + "Jedź, Jedź, KG są za nami!" ], "agnt134": [ "Bądź czujny, jesteśmy prawie na miejscu!" @@ -464,7 +464,7 @@ ], "asha003": [ "Pozwól, że cię zmniejszę do odpowiednich rozmiarów...", - "Nie żebyś miał jakiekolwiek." + "Nie żebyś miał jakieś." ], "asha004": [ "Małe karabiny mnie nie podniecają." @@ -485,7 +485,7 @@ "Oto niektóre." ], "asha010": [ - "Gotowy na innych?" + "Gotowy na kolejne?" ], "asha011": [ "Jakie to uczucie?" @@ -515,16 +515,16 @@ "Nie mądrze!" ], "asha020": [ - "Słuchaj, kumplu, po czyjej jesteś stronie?" + "Słuchaj, koleś, po czyjej jesteś stronie?" ], "asha021": [ - "Nie zmuszaj mnie do bolesnich działań." + "Nie zmuszaj mnie, żebym cię skrzywdziła." ], "asha022": [ "Zrób to jeszcze raz, a ja cię powale." ], "asha023": [ - "Naucz się kontrolować swoją broń, kumplu." + "Naucz się kontrolować swoją broń, koleś." ], "asha024": [ "Gdzie nauczyłeś się tak walczyć?" @@ -536,7 +536,7 @@ "Nie rób tego ponownie." ], "asha027": [ - "Może powinienem być za tobą." + "Może powinnam być za tobą." ], "asha028": [ "Nie wezmę tego!" @@ -551,7 +551,7 @@ "Nie próbuj tego ponownie!" ], "asha032": [ - "Ładny strzał." + "Dobrze strzelasz." ], "asha033": [ "Dobrze strzelasz, niebieski chłopaczku." @@ -572,7 +572,7 @@ "Potrzebuję pomocy!" ], "asha039": [ - "O cholera, jest ich naprawdę dużo!" + "W mordę, naprawdę jest ich dużo!" ], "asha040": [ "Idą kolejni." @@ -581,7 +581,7 @@ "Mam go." ], "asha042": [ - "Więcej ognia!" + "Więcej siły ognia!" ], "asha043": [ "Jeszcze raz!" @@ -636,16 +636,16 @@ "asht006": [ "Myślę, że teraz nadszedł czas na działanie.", "Metalowe Łby są tak skupione na atakowaniu miasta,", - "Mogli pozostawić swoje gniazdo bezbronnie.", - "Jak, musisz wyjść z Wasteland.", - "I sforsuj barierę Gniazda, jeśli potrafisz.", - "Może jeśli wejdziesz do wnętrza i wyciągniesz dowódcę MetalHead'ów.", + "że mogli pozostawić swoje gniazdo bezbronne.", + "Jak, musisz się dostać na Pustkowia.", + "I sforsuj bramę Gniazda, w jakikolwiek sposób.", + "Może jeśli wejdziesz do środka i pokonasz dowódcę Metalowych Łbów.", "Armia się załamie. To ryzykowne, ale...", "ale może to być nasza jedyna szansa." ], "bar001": [ "Nie zwracaj uwagi na bezpodstawne plotki o", - "Niskie zasoby eko. Jako twój baron, zapewniam Cię,", + "małych zasoby eco. Jako twój baron, zapewniam was,", "miasto posiada niekończącą się dostawę eco.", "Ci, którzy twierdzą, że nam brakuje,", "próbują tylko przestraszyć i odwrócić się!", @@ -659,12 +659,12 @@ "Myślę, że powinieneś więcej ćwiczyć." ], "bb01int": [ - "Jak, to jest Torn. Podziemie potrzebuje dobrych kierowców", - "podczas naszych misji związanych z pojazdami. Udowodnij swoje umiejętności.", + "Jak, tu Torn. Podziemie potrzebuje dobrych kierowców", + "podczas naszych misji z użyciem pojazdu. Udowodnij swoje umiejętności.", "Wykonaj wyzwanie z pierścieniem, a może pozwolimy ci dołączyć do akcji." ], "bb01win": [ - "Nie tak źle, myślę, że możemy z nich skorzystać.", + "Nieźle, myślę, że skorzystamy z twojej pomocy.", "Oto mała nagroda za twój wysiłek." ], "bb02fail": [ @@ -672,7 +672,7 @@ ], "bb02int": [ "Chcielibyśmy zobaczyć, jak udowodnisz swoje umiejętności kierowania. Weź udział", - "inne Wyzwanie Pierścienia, zobaczmy co masz do dyspozycji." + "w kolejnym Wyzwaniu z Pierścieniami, zobaczmy na co cię stać." ], "bb02win": [ "Nieźle. Możesz być moim kierowcą w każdej chwili." @@ -682,50 +682,53 @@ ], "bb03int": [ "Kolejne wyzwanie Pierścienia oddzieli mężczyzn od małych chłopców.", - "Zobaczmy, czy potrafisz sobie z tym poradzić." + "Zobaczmy, czy poradzisz sobie z tym." ], "bb03win": [ - "Świetnie prowadzisz. Zaczynam coraz bardziej wierzyć, że naprawdę potrafisz jeździć.", - "Pomóż nam, Jak." + "Świetnie jeździłeś. Zaczynam myśleć, że naprawdę możesz", + "nam pomóc, Jak." ], "bb04fail": [ "Źle, miałem nadzieję, że możesz to zrobić, próbuj dalej." ], "bb04int": [ - "Torn tutaj. Nie wiem w ogóle, dlaczego ci pozwalam spróbować", - "Ring Challenge, sam nigdy go nie pokonałem. Chyba jestem chorobliwie", - "ciekawy. Pokonaj go, a będziesz najlepszym kierowcą", + "Tu Torn. Nawet nie wiem, dlaczego ci pozwalam spróbować ten", + "Wyzwanie z pierścieniami, sam nigdy go nie zrobiłem. Chyba jestem chorobliwie", + "ciekawy. Ukończ to, a będziesz najlepszym kierowcą", "Podziemia kiedykolwiek miało." ], "bb04win": [ - "Bardzo dobrze, Jaki! Jesteś najlepszym kierowcą, kiedykolwiek mieliśmy." + "Bardzo dobrze, Jaki! Jesteś najlepszym kierowcą, jakiego kiedykolwiek mieliśmy." ], "bb05fail": [ - "Nie zdobyłeś wszystkich Bomb Botów, Jak!" + "Nie zniszczyłeś wszystkich Bomb Botów, Jak!" ], "bb05int": [ - "Jak, raporty mówią, że więcej robotów bomb rośnie w mieście.", - "Są niebezpiecznym zagrożeniem i potrzebuję abyś znalazł", + "Jak, raporty mówią, że więcej robotów bomb włóczy się po mieście.", + "Są poważnym zagrożeniem i potrzebuję abyś znalazł", "i zniszczyć każdego z nich, zanim zaszkodzą naszym interesom" ], "bb05win": [ "Dobra robota! To powinno zaszkodzić budżetowi wojennemu Barona." ], "bb06int": [ - "Jak, musimy cię wysłać, aby zlikwidować kolejną grupę Bomb Botów.", - "Te mobilne bronie ciągle pojawiają się w mieście, musimy je jak najszybciej zlikwidować." + "Jak, musimy cię wysłać, abyś zlikwidował kolejną grupę Bomb Botów.", + "These mobile weapons keep showing up in the city,", + "we gotta take them out as soon as possible." ], "bb06win": [ - "Kolejny stos złomu bomb metalowego dla KG", - "kompaktory śmieci. Misja zakończona, podziemie", - "bardzo wdzięczny za Twoją usługę." + "Kolejny stos złomu po bombach dla KG", + "zgniatarki na śmieci. Misja zakończona, Podziemie jest", + "bardzo wdzięczne za Twoją pomoc." ], "bb07fail": [ - "Straciłeś agenta! NIE dobrze! Misja się nie powiodła!" + "Straciłeś agenta! NIE dobrze, Jak! Misja się nie powiodła!" ], "bb07int": [ - "Torn tutaj, potrzebuję, żebyś wyszedł i przeniósł więcej naszych agentów do nowych lokalizacji na mieście.", - "Szpiedzy KG obserwują nasz każdy krok, więc szukają problemów. Powodzenia." + "Torn here, I need you to go out and move more of our Agents", + "to new locations in the city.", + "KG spies are watching our every move,", + "so look out for trouble. Good luck." ], "bb07win": [ "Dobra praca z transportem! Trzymasz ludzi przy życiu na zewnątrz." @@ -737,7 +740,8 @@ "bb08int": [ "Jak, niektórzy z naszych agentów zostali ponownie skompromitowani.", "Znajdź każdą z nich i zabierz je do specjalnych kryjówek na mieście.", - "Patrole strażników są na wysokim poziomie alarmowym, więc będzie to trudne. Trzymaj głowę nisko!" + "The guard patrols are on high alert,", + "so this is going to be a tough one. Keep your head down!" ], "bb08win": [ "To była dobra jazda - Jak.", @@ -753,7 +757,7 @@ ], "bb09win": [ "Szybka robota, Jak! Pewnego dnia możemy nawet", - "invite you to these meetings." + "zaproszę cię na te spotkania." ], "bb10fail": [ "Nie wystarczająco szybko, kolego! Musisz być szybki", @@ -818,7 +822,7 @@ "o co prosiliśmy." ], "bb15farr": [ - "Get off the bike and get clear, Jak!!" + "Zejdź ze skutera i wtop się w tłum, Jak!!" ], "bb15int": [ "Jak, znaleźliśmy bombę w slumsach", @@ -862,12 +866,12 @@ "Nadal nie jestem pewny czy Deska odrzutowa jest użyteczna." ], "bb18int": [ - "Oto kolejne świetne miejsce do oceny wydajności.", - "Na odrzutowej desce. Spróbuj zdobyć tutaj wystarczająco ilość punktów." + "Oto kolejne świetne miejsce do oceny wydajności", + "Deski Odrzutowej. Spróbuj tutaj zdobyć wystarczającą ilość punktów." ], "bb18win": [ - "Słodkie ruchy Jak. KG miałby trudny czas", - "catching us on those babies." + "Słodkie ruchy Jak. KG miałoby trudne chwile", + "aby nas złapać na tych maleństwach." ], "bb19fail": [ "Nie dostałeś wszystkiego. Spróbuj ponownie." @@ -904,7 +908,7 @@ "Oto mała nagrodya za pozostanie z nami." ], "bb22fail": [ - "You didn't get the booths fast enough, Jak." + "Nie zdążyłeś zdobyć doładowania wystarczająco szybko, Jak." ], "bb22int": [ "Niektóre z propagandy Barona są niepokojące", @@ -1016,7 +1020,7 @@ "Byłeś za wolny na tym torze." ], "bb40int": [ - "I'd like to see you take the JET-Board through another", + "Chciałbym zobaczyć, jak zabierasz Deskę Odrzutową na kolejny", "Ring Course. Sprawimy, że ten będzie nieco bardziej interesujący,", "Zobaczmy, czy uda ci się ukończyć go na czas." ], @@ -1282,10 +1286,10 @@ "Jesteś nikim!" ], "bf087": [ - "Moja tarcza się ładuje!" + "Moja tarcza jest teraz naładowana!" ], "bf088": [ - "Try these on for size!" + "Wypróbuj je na własnej skórze!" ], "bf089": [ "Powinienem był cię zabić dawno temu!" @@ -1732,7 +1736,7 @@ "Obszar zastrzeżony. Obrona aktywowana." ], "cityv048": [ - "You are trespassing. Defenses coming online." + "Naruszasz strefę zastrzeżoną. Aktywacja systemów obronnych." ], "cityv049": [ "Żałuje użycia siły. Systemy uzbrajają się." @@ -1898,7 +1902,7 @@ "Oto nagroda." ], "cityv149": [ - "potrzebuję zasilania awaryjnego dla moich konwerterów Eko.", + "Potrzebuję zasilania awaryjnego dla moich konwerterów Eco.", "Szybkie włączanie wszystkich dostępnych obwodów", "ustabilizować siatkę Eko." ], @@ -1936,16 +1940,16 @@ "Oto twoja nagroda." ], "cityv158": [ - "Emergency response needed.", - "Runaway bomb bots detected and headed for", - "populated areas. Neutralize all bomb bots", + "Potrzebna natychmiastowa odpowiedź.", + "Wykryto uciekające roboty bombowe i skierowały się", + "w stronę zaludnionych obszarów. Zneutralizuj wszystkie roboty bombowe", "zanim będzie za późno." ], "cityv159": [ - "You failed to neutralize the runaway bomb bots." + "Nie udało ci się zneutralizować uciekających robotów bombowych." ], "cityv160": [ - "You destroyed the runaway bomb bots.", + "Zniszczyłeś uciekające roboty bombowe.", "Miasto ci dziękuje." ], "cityv161": [ @@ -1969,13 +1973,13 @@ ], "cityv167": [ "Metalowe Łby zostały wykryte w kursie broni.", - "Zneutralizuj je wszystkie natychmiast." + "Zneutralizuj ich wszystkich natychmiast." ], "cityv168": [ "Nie zabiłeś ich wszystkich." ], "cityv169": [ - "Świetne strzelanie. Zagrożenie wyeliminowane." + "Świetnie strzelałeś. Zagrożenie wyeliminowane." ], "cityv170": [ "Zdobądź rekord na Desce odrzutowej i otrzymaj nagrodę." @@ -1990,7 +1994,7 @@ "Gratulacje, udało ci się osiągnąć wystarczająco duży wynik." ], "cityv174": [ - "Welcome to the Stadium Central Computer.", + "Witaj w centralnym komputerze Stadionu.", "Proszę wybrać wyzwanie." ], "cityv175": [ @@ -2018,22 +2022,22 @@ "Gratulacje, udało Ci się osiągnąć brązowy rekord." ], "cityv182": [ - "Care to try for a high score record?" + "Chcesz spróbować pobić rekord najlepszego wyniku?" ], "cityv183": [ - "Would you like to try for a high score?" + "Czy chcesz spróbować uzyskać najlepszy wynik?" ], "cityv184": [ "Witamy w Wyścigowych Próbach Czasowych." ], "cityv185": [ - "Would you like to race for a record time?" + "Czy chcesz się ścigać o rekord czasu?" ], "cityv186": [ "Wybierz swój tor." ], "cityv187": [ - "Would you like to try for a course record?" + "Chcesz spróbować pobić rekord kursu?" ], "cityv188": [ "Czy chciałbyś użyć Kul, aby kupić sekret?" @@ -2051,7 +2055,7 @@ "Proszę opuścić Strój Tytana." ], "cityv193": [ - "Proszę opuścić Strój Tytana." + "Musisz opuścić Strój Tytana." ], "cityv194": [ "Pojazdy muszą pozostać w granicach miasta." @@ -2075,16 +2079,16 @@ "Strzelaj w Metalowego Łba, kiedy on opuści swoją tarczę!" ], "daxm004": [ - "Hit him in his stomach!" + "Walnij go w brzuch!" ], "daxm005": [ - "Whoa! That path dropped like uh... a rock!" + "Whoa, ta ścieżka spadła jak... kamień!" ], "daxm006": [ - "Smack the box, baby!" + "Uderz w pudło, kochaniutki!" ], "daxm007": [ - "That's what I call a rocky road!" + "To właśnie nazywam skalistą drogą!" ], "daxm008": [ "Musimy się dostać na górę!" @@ -2103,7 +2107,7 @@ ], "ds006": [ "Wreszcie, teraz możemy spotkać się z Cieniem!", - "What do ya gotta do around this place to get noticed?" + "Co trzeba zrobić w tej okolicy, żeby zostać zauważonym?" ], "ds012": [ "To musi być Rubinowy Klucz do miasta." @@ -2122,25 +2126,25 @@ "To musi być amunicja i pociski rakietowe, które Torn kazał nam wysadzić!" ], "ds018": [ - "Get the tank to shoot the missile!" + "Spraw, aby czołg strzelił do pocisku!" ], "ds019": [ - "Break those tubes in the center." + "Zniszcz te rury na środku." ], "ds020": [ - "Please tell me you remember how to roll..." + "Powiedz mi, że pamiętasz, jak się turlać..." ], "ds023": [ - "Let's rock!" + "Dajmy czadu!" ], "ds024": [ - "Here we go!" + "No to zaczynamy!" ], "ds025": [ - "All right!" + "W porządku!" ], "ds026": [ - "O tak!" + "Tak!" ], "ds028": [ "O tak!" @@ -2158,31 +2162,31 @@ "Wracajmy do Kryjówki Podziemia." ], "ds043": [ - "You can get a longer jump by rolling into it." + "Możesz wydłużyć skok, wpierw wykonując przewrót." ], "ds044": [ - "Use a long jump to get across this gap." + "Aby przedostać się przez tę przepaść, wykonaj przewrót i skocz." ], "ds045": [ - "Nice form!" + "Niezła forma!" ], "ds046": [ - "If you duck before you jump, you'll go higher.", - "You'll need a high jump to reach the top of this ledge, Jak." + "Jeśli kucniesz przed skokiem, To skacząc z tej pozycji, dostaniesz się wyżej.", + "Jak, aby dostać się na szczyt tej półki, będziesz musiał skoczyć wzwyż." ], "ds047": [ - "Ooh, that's a high one.", + "Och ta krawędź jest wysoko.", "Będziesz musiał skoczyć,", "potem skocz jeszcze raz w powietrzu, żeby tam się dostać." ], "ds048": [ - "Hit 'em again, Jak!" + "Uderz ich jeszcze raz, Jak!" ], "ds049": [ - "Do a spin kick!" + "Zrób kopniak obrotowy!" ], "ds050": [ - "Robotank, run!" + "Roboczogł, biegnij!" ], "ds051": [ "Hej, powinniśmy zostać z Sigiem." @@ -2218,17 +2222,17 @@ "O oł, Sig ma kłopoty!" ], "ds062": [ - "There's another Metal Head going after our boy!", + "Kolejny Metalowy Łeb poluje na naszego chłopa!", "Zestrzel to, Zestrzel to!" ], "ds063": [ "Pilnuj Siga, Jak!" ], "ds064": [ - "Whoa, Sig's really getting roughed up!" + "Whoa, Sig naprawdę się wkurzył!" ], "ds065": [ - "Shoot 'em, shoot 'em!" + "Zestrzel ich, zestrzel ich!" ], "ds066": [ "Sig zginie, to i my zginiemy." @@ -2243,34 +2247,34 @@ "Musimy znaleźć zawór, żeby włączyć z powrotem wodę." ], "ds094": [ - "Robotank, run!" + "Roboczogł, biegnij!" ], "ds095": [ "Znowu pojawił się ten czołg!" ], "ds096": [ - "Get the tank to shoot the missile!" + "Spraw, aby czołg strzelił do pocisku!" ], "ds099": [ - "We need to get to the top of that tower!" + "Musimy dostać się na szczyt tej wieży!" ], "ds100": [ - "Climb the ruined tower, Jak!" + "Wejdź na zrujnowaną wieżę, Jak!" ], "ds111": [ - "We should come back with the Titan Suit to do this path." + "Powinniśmy wrócić ze zbroją Tytana, aby zrobić sobie ścieżkę." ], "ds112": [ - "You've got a mechanical fist, Jak. Use it!" + "Masz mechaniczną pięść, Jak. Użyj jej!" ], "ds113": [ "Zniszcz drzwi!" ], "ds114": [ - "800 pound Tigorilla comin' through!" + "330 kilogramowa Tigorilla nadchodzi!" ], "ds115": [ - "Smashing work, Jak! Oh, that was funny." + "Świetna robota, Jak! Och, to było zabawne." ], "ds116": [ "Strzel w platformę, Jak." @@ -2285,16 +2289,16 @@ "Traf go w brzuch." ], "ds120": [ - "Whoa, that path dropped like a... a rock!" + "Whoa, ta ścieżka spadła jak... kamień!" ], "ds121": [ - "Smack the box, baby!" + "Uderz w pudło, kochaniutki!" ], "ds128": [ "Dobrze, skończyliśmy." ], "ds129": [ - "Shoot the gun, Jak!" + "Strzelaj z broni, Jak!" ], "ds143": [ "Powinniśmy utrzymać przy życiu ludzi Krew, Jak!" @@ -2324,7 +2328,7 @@ "Mamy towarzystwo, Jak! Dużo strażników!" ], "ds160": [ - "That's right, we're bad! The Precursor Stone is ours!" + "Właśnie tak, jesteśmy najlepsi! Kamień Prekursora jest nasz!" ], "ds161": [ "Tam jest broń Mara, Jak! Chodźmy to sprawdzić." @@ -2340,7 +2344,7 @@ "chodźmy się zabawić na chacie dużego mężczyzny!" ], "ds164": [ - "Cofnij się, aby wydostać się z mecha." + "Cofnij się, aby wyjść z mecha." ], "ds165": [ "Jesteśmy wolni, Jak! Dzięki mnie.", @@ -2374,7 +2378,7 @@ "Hej!" ], "ds178": [ - "Hey, watch that!" + "Hej, uważaj!" ], "ds179": [ "Ooh!" @@ -2404,13 +2408,13 @@ "W porządku!" ], "ds188": [ - "Move over!" + "Przesuń się!" ], "ds189": [ - "Orange Lightning coming through!" + "Nadchodzi Pomarańczowa Błyskawica!" ], "ds190": [ - "Rollin' with the homies!" + "Bujajcie się stąd frajerzy!" ], "ds191": [ "Jesteś mój!" @@ -2425,7 +2429,7 @@ "Jak mam jeździć tym czymś?" ], "ds195": [ - "Yeah, that's right! I'm bad!" + "O tak, O to chodzi! Jestem wredny!" ], "ds196": [ "Z drogi!" @@ -2452,10 +2456,10 @@ "Gaz do dechy!" ], "ds204": [ - "Ooooah, I gotta catch up!" + "Ooo, Muszę nadgonić!" ], "ds205": [ - "Turn and burn, baby!" + "Leż i płoń, kotku!" ], "ds206": [ "Ooo, to będzie bliskie!" @@ -2464,134 +2468,134 @@ "Żryj mój kurz, kolego!" ], "ds208": [ - "Gotcha!" + "Mam cię!" ], "ds209": [ - "This is my track, grandma!" + "To moja trasa, babciu!" ], "ds210": [ "Naucz się jeździć!" ], "ds211": [ - "Turn, turn!" + "Skręć, skręć!" ], "ds212": [ "Gaz do dechy!" ], "ds213": [ - "Oooh, I won, I won!" + "Ooo, wygrałem, wygrałem!" ], "ds214": [ - "Yeee, that's a good lap time." + "Tak, to dobry czas okrążenia." ], "ds215": [ - "Oh, yeah! I'm rockin'!" + "O tak! Rządzę!" ], "ds216": [ - "Another lap in the record book!" + "Kolejne okrążenie w księgi rekordów!" ], "ds217": [ - "Take a good look at my tail!" + "Przyjrzyj się dobrze mojemu ogonowi!" ], "ds218": [ "Wahoo!" ], "ds219": [ - "Hey, fang boy, hurry up and get in,", + "Hej, fang chłopcze, pośpiesz się i wsiadaj,", "Zabierzemy cię do Bruttera!" ], "ds220": [ - "Here's your boy, Brutter! We're off to get another animal!" + "Tu masz swojego chłopaka, Brutter! My lecimy po kolejne zwierzę!" ], "ds221": [ - "Yo, animal lover, get your furry butt in the vehicle!" + "Ej, miłośniku zwierząt, zabierz swój futrzany tyłek do pojazdu!" ], "ds222": [ - "Here's another beast of burden!" + "Oto kolejna uciążliwa bestia!" ], "ds223": [ - "In the vehicle, buddy, we can save you!" + "W pojeździe, kolego, możemy cię uratować!" ], "ds224": [ - "Another Lurker freed." + "Kolejny Lurker uwolniony." ], "ds225": [ - "Let's move, eco breath! We gotta get you to Brutter." + "Ruszajmy, eco dechu! Musimy cię zabrać do Bruttera." ], "ds226": [ - "Hey, Brutter! Look what the cat turkey dragged in." + "Hej, Brutterze! Zobacz co przysmyczył kot." ], "ds227": [ - "Lookie what we found!" + "Spójrz coś my znaleźli!" ], "ds228": [ - "You recognize this monster?" + "Poznajesz tego potwora?" ], "ds229": [ "Udało nam się! Ocaliliśmy ich wszystkich!" ], "ds230": [ - "Catch the paddywagon, Jak!" + "Złap tę więźniarkę, Jak!" ], "ds231": [ - "Crash the paddywagon!" + "Rozbij tę więźniarkę!" ], "ds232": [ - "A little more damage and we got the sucker!" + "Jeszcze trochę uszkodzeń i mamy frajera!" ], "ds233": [ - "He's smoking, Jak! Hit him again!" + "On się pali, Jak! Uderz go ponownie!" ], "ds234": [ - "That caused some damage!" + "To spowodowało pewne szkody!" ], "ds235": [ - "One more like that and he's through!" + "Jeszcze jeden raz i będzie po nim!" ], "ds236": [ - "Find the next vehicle!" + "Znajdź następny pojazd!" ], "ds237": [ - "Yes, we took it out!" + "Tak, pozbyliśmy się tego!" ], "ds238": [ - "Hunt and destroy, baby!" + "Poluj i niszcz, stary!" ], "ds239": [ - "Hit it, hit it!" + "Uderz to, uderz!" ], "ds240": [ - "Take it out!" + "Zdejmij to!" ], "ds241": [ - "Pick up the Lurker, Jak!" + "Zgarnij Lurkera, Jak!" ], "ds242": [ - "Get the Lurker!" + "Zgarnij Lurkera!" ], "ds243": [ - "We need to pick up that Lurker back there." + "Musimy zabrać tego Lurkera stamtąd." ], "ds244": [ - "Usually, I don't like to be this close to Lurkers." + "Zwykle nie lubię przebywać tak blisko Lurkerów." ], "ds245": [ - "Ehehe, you seem like a nice, uh... animal." + "Ehehe, wyglądasz na miłe, uh... zwierzę." ], "ds246": [ - "Easy, buddy. Don't bite me!" + "Spokojnie, kolego. Nie gryź mnie!" ], "ds247": [ - "Hey, stop slobbering on me!" + "Hej przestań się na mnie ślinić!" ], "ds248": [ - "He's recharging!" + "On się Ładuje!" ], "ds249": [ - "Ooh, we got him good that time!" + "Oo, Tym razem nieźle go załatwiliśmy!" ], "ds250": [ - "Yeah, now he's hurtin'!" + "Tak, teraz go boli!" ], "ds251": [ "Dobry strzał, Jak!" @@ -2600,7 +2604,7 @@ "Nadchodzą!" ], "ds253": [ - "Yeah, we got him!" + "Tak, mamy go!" ], "ds254": [ "Jak, ukryj się za filarami, gdy strzela!" @@ -2612,49 +2616,49 @@ "Kopnij bombę w jego kierunku, Jak!" ], "ds257": [ - "That one hit him!" + "Ten go trafił!" ], "ds258": [ "Uważaj!" ], "ds259": [ - "Jump the gap!" + "Przeskocz przepaść!" ], "ds260": [ - "Yeah, you hit him!" + "Tak, trafiłeś go!" ], "ds261": [ - "As if there wasn't enough of Krew already." + "Jakby Krew już było za mało." ], "ds262": [ - "Shoot 'em all, Jak! We'll sort 'em out later..." + "Zastrzel ich wszystkich, Jak! Rozwiążemy je później..." ], "ds263": [ - "There's the real Krew! Shoot him!" + "Tu jest prawdziwy Krew! Zestrzel go!" ], "ds264": [ "Masz go!" ], "ds265": [ - "Watch your back, Jak!" + "Uważaj na plecy, Jak!" ], "ds266": [ - "They're comin' again!" + "Znowu Oni nadchodzą!" ], "ds267": [ - "Now you've got us mad." + "Teraz nas wkurzyłeś." ], "ds268": [ - "Good shot, Jak! The big man is hurtin' now." + "Dobry strzał, Jak! Wielkolud teraz cierpi." ], "ds269": [ - "And the challenger is down for the count!" + "A pretendent został zmieciony z planszy!" ], "ds270": [ - "Keep movin', baby! He's gonna shoot!" + "Ruszaj się stary! On będzie strzelał!" ], "ds271": [ - "Wooh, here come some Metal Heads!" + "Woo, nadchodzą Metalowe Łby!" ], "ds272": [ "Chroń dzieciaka!" @@ -2666,65 +2670,65 @@ "Więcej Metalowych Łbów!" ], "ds275": [ - "Shoot Kor's legs out, Jak!" + "Strzelaj w nogi Kora, Jak!" ], "ds276": [ - "He's down, Jak! Hit him in the head!" + "On upadł, Jak! Atakuj go w głowę!" ], "ds277": [ - "Boot to the head, boot to the head!" + "Kop w głowę, kop w głowę!" ], "ds278": [ - "I think we should hide somewhere!" + "Myślę, że gdzieś powinniśmy się ukryć!" ], "ds279": [ - "Take cover before he blows!" + "Skryj się, zanim uderzy!" ], "ds280": [ - "Yeah, you got him good that time!" + "Tak, tym razem dobrze go załatwiłeś!" ], "ds281": [ - "Oh, man, now he's angry!" + "Oh, stary, teraz jest zły!" ], "ds282": [ - "Get him, Jak!" + "Dorwij go, Jak!" ], "ds283": [ - "He's gonna shoot!" + "On będzie strzelał!" ], "ds284": [ - "Nice hit, partner!" + "Dobre trafienie, partnerze!" ], "ds285": [ - "That had to hurt him." + "To musiało go zaboleć." ], "ds286": [ - "You messed with the wrong heroes, buddy!" + "Zadarłeś z niewłaściwymi bohaterami, kolego!" ], "ds287": [ - "Shoot him again, Jak!" + "Strzel do niego jeszcze raz, Jak!" ], "ds288": [ - "Jak, we're taking a beating!" + "Jak, dostajemy łomot!" ], "ds289": [ "Trzymaj się z dala od Mrocznego Eco!" ], "ds302": [ - "We've almost got him, Jak!" + "Prawie go mamy, Jak!" ], "ds303": [ - "That's it! You did it!" + "To już koniec! Udało ci się!" ], "ds305": [ - "Shoot the switch to change the coveyor belt's", - "kierunek!" + "Strzel w przełącznik, aby zmienić kierunek", + "taśmociągu!" ], "ds306": [ - "You gotta shoot the switch, Jak!" + "Musisz strzelić w przełącznik, Jak!" ], "ds307": [ - "Find the switch to change the conveyor's direction!" + "Znajdź przełącznik taśmociągu, aby zmienić jego kierunek!" ], "ds321": [ "Zdejmij te wieżyczki!" @@ -2733,152 +2737,152 @@ "Strzelaj w działka, Jak!" ], "ds323": [ - "Doin' some damage!" + "Dostają obrażenia!" ], "ds324": [ - "Get in the Titan Suit!" + "Wskakuj do Stroju Tytana!" ], "ds325": [ - "Shoot that ship!" + "Zestrzel ten statek!" ], "ds326": [ - "Yeah, that ship's feelin' it now!" + "Tak, ten statek teraz to poczuł!" ], "ds327": [ "Oo, bezpośrednie trafienia." ], "ds328": [ - "I think you hurt it that time!" + "Myślę, że tym razem to poczuli!" ], "ds329": [ - "The ship's goin' down! You did it, Jak!" + "Statek spada! Udało ci się, Jak!" ], "ds353": [ - "That must be the missile Torn wants us to blow up!" + "To musi być pociski rakietowe, które Torn kazał nam wysadzić!" ], "ds354": [ - "Break those tubes in the center, Jak!" + "Zniszcz te rury na środku, Jak!" ], "ds372": [ - "Gotta ride the JET-Board on this one, Jak!" + "Muszę przejechać się na tej Desce Odrzutowej, Jak!" ], "ds375": [ - "Look out for the ray!" + "Uważaj na promień!" ], "ds378": [ - "We gotta break all the support cables!" + "Musimy zerwać wszystkie liny wspomagające!" ], "ds379": [ - "Grind on the support bases to break the cables." + "Prześlizgnij się na hakach, aby zerwać liny." ], "ds394": [ - "Spider! Spider! Huff... huff... I hate spiders!" + "Pająk! Pająk! Huff... huff... Nienawidzę pająków!" ], "ds395": [ - "Gotta run, gotta run!" + "Muszę uciekać, muszę uciekać!" ], "ds398": [ - "The first beam!" + "Pierwsza wiązka!" ], "ds399": [ - "The second beam! The door's opening!" + "Druga wiązka! Drzwi się otwierają!" ], "ds404": [ - "There's Sig!" + "Tu jest Sig!" ], "ds405": [ - "Get the blocks to go into the slots, Jak!" + "Włóż kloce do szczelin, Jak!" ], "ds406": [ - "Shoot or kick the blocks!" + "Strzelaj lub kopaj bloki!" ], "ds407": [ - "You have to get the blocks in the slots faster!" + "Musisz szybciej umieszczać bloki w szczelinach!" ], "ds408": [ "Biegnij, Jak!" ], "ds409": [ - "Keep moving!" + "Ruszajmy dalej!" ], "ds410": [ - "We gotta stay ahead of that thing!" + "Musimy trzymać się z dala od tego czegoś!" ], "ds439": [ - "Shoot all the Metal Head eggs, Jak!" + "Strzelaj do wszystkich jaj Metalowych Łbów, Jak!" ], "ds440": [ - "We didn't get all those nasty eggs!" + "Nie zniszczyliśmy wszystkich tych paskudnych jajek!" ], "ds441": [ - "We missed some Metal Head eggs!" + "Pominęliśmy jakieś jajka Metalowych Łbów!" ], "ds461": [ - "We gotta jump onto the crate dangling from the crane!" + "Musimy wskoczyć na skrzynię zwisającą z dźwigu!" ], "ds462": [ - "Use your hoverboard on this path!" + "Użyj twojej Deski odrzutowej na tej ścieżce!" ], "ds463": [ - "You can grind to cross those pipes using your", - "deska odrzutowa!" + "Możesz się prześliznąć, przez te rury używając swojej", + "deski odrzutowej!" ], "ds464": [ - "Ride the half-pipe to the end!" + "Przejedź po tej rampie aż do końca!" ], "ds466": [ - "You gotta drop a bomb into each well, Jak!" + "Musisz wrzucić bombę do każdego szybu, Jak!" ], "ds467": [ - "Use the ramp to get high enough to drop the bomb in!" + "Użyj rampy, aby dostać się wystarczająco wysoko, aby zrzucić bombę!" ], "ds468": [ - "Gotta jump higher!" + "Musisz skoczyć wyżej!" ], "ds469": [ - "Only a minute before we're toast, Jak!" + "Jeszcze tylko minuta i jesteśmy ugotowani, Jak!" ], "ds470": [ - "30 seconds left, then we go BOOM!" + "Zostało 30 sekund, potem będzie BOOM!" ], "ds471": [ "Zostało dziesięć sekund, Jak!" ], "ds472": [ - "That's one well down, five to go!" + "Jeden szyb z głowy, zostało jeszcze pięć!" ], "ds473": [ - "Two wells are history, four left!" + "Dwa szyby już są historią, zostały cztery!" ], "ds474": [ - "Three wells cut, only three to go!" + "Zostały odcięte trzy szyby, zostały tylko trzy!" ], "ds475": [ - "That's the fourth well, two bad boys left!" + "To był czwarty szyb, zostało dwóch hultai!" ], "ds476": [ - "You got the fifth well, only one to go!" + "Masz piąty szyb, został tylko jeden!" ], "ds477": [ - "You got 'em all, Jak!" + "Ogarnąłeś wszystkie, Jak!" ], "ds478": [ - "The last well is up where we rescued Vin!" + "Ostatni szyb jest na górze, gdzie uratowaliśmy Vina!" ], "ds479": [ - "Now he's vulnerable!" + "Teraz jest bezbronny!" ], "ds480": [ "Zdejmij go!" ], "ds481": [ - "Get him while he's vulnerable!" + "Dorwij go, póki jest bezbronny!" ], "ds482": [ - "Here he comes..." + "Oto nadchodzi..." ], "ds483": [ - "How's it feel to have your pants down, Baron?" + "Jakie to uczucie mieć opuszczone spodnie, Baronie?" ], "ds484": [ "Zestrzel go, Zestrzel go!" @@ -2887,89 +2891,89 @@ "Uważaj!" ], "ds487": [ - "Easy, Jak, we gotta get this guy to safety!" + "Spokojnie, Jak, musimy zabrać tego gościa w bezpieczne miejsce!" ], "ds488": [ - "We're takin' a lotta damage, buddy!" + "Odnosimy spore obrażenia, koleś!" ], "ds489": [ - "We're gettin' our butts kicked!" + "Dostajemy srogie manto!" ], "ds490": [ "Może powinienem prowadzić..." ], "ds491": [ - "Let's go, wondergoon,", - "we'll take you to a safe place in the city!" + "Chodźmy, cudaku,", + "zabierzemy cię w bezpieczne miejsce w mieście!" ], "ds492": [ - "Okay, ride's over, out you go!" + "OK, koniec jazdy, wsiadaj!" ], "ds493": [ - "All aboard the Underground railroad!", - "Next stop: Your new safehouse!" + "Wszyscy na pokład linii Podziemia", + "Następny przystanek: Twoja nowa kryjówka!" ], "ds494": [ - "I believe this is your stop!" + "Wierzę, że to twój przystanek!" ], "ds495": [ - "Daxter's Freedom Fighter Taxi Service!", - "Hurry up, buddy, we ain't got all day." + "Taksówka Bojownika o Wolność Daxtera!", + "Pospiesz się, kolego, nie mamy całego dnia." ], "ds496": [ - "Home free, baby!", - "Don't forget to tell Torn how well we did!" + "W końcu spokoju, dziecinko!", + "Nie zapomnij powiedzieć Tornowi, jak dobrze nam poszło!" ], "ds497": [ - "You looking for a lift, fighter boy?" + "Szukasz podwózki, bojowniku?" ], "ds498": [ - "Okay, this is where you get off. So... get off." + "OK, tutaj wysiadasz. Więc... wysiadaj." ], "ds499": [ - "We did it, Jak!", - "We got all the fighters to the new safehouses!" + "Udało nam się, Jak!", + "Zabraliśmy wszystkich bojowników do nowych kryjówek!" ], "ds500": [ - "Statues are becoming an endangered species around here." + "Posągi stają się tutaj zagrożonym gatunkiem." ], "ds501": [ - "I got us a talkbox.", - "The city people use these things to communicate", - "with each other." + "Załatwiłem nam komunikator.", + "Mieszkańcy miasta używają tych rzeczy do komunikacji", + "ze sobą." ], "ds502": [ - "Let's go see Onin and her crazy monkey bird." + "Chodźmy zobaczyć Onina i jej szalonego małpiego ptaka." ], "ds503": [ - "I think we need to go back to the city, Jak." + "Myślę, że musimy wrócić do miasta, Jak." ], "dsek001": [ - "Kid! Stay with him, Jak!" + "Dzieciak! Trzymaj się z nim, Jak!" ], "dsek002": [ - "Catch up to them, Jak!" + "Dogoń ich, Jak!" ], "dsek003": [ "Gdzie oni poszli?!" ], "dsek004": [ - "There they go again!" + "Znowu się ulotnili!" ], "dsek005": [ - "Uh oh, here comes trouble!" + "Och, nadchodzą kłopoty!" ], "dsek006": [ "Więcej strażników!?" ], "dsek007": [ - "Kid, please! You're killin' me!" + "Mały, proszę! Dostaje zadyszki przez ciebie!" ], "dsek008": [ - "Here, poochie, poochie..." + "Tutaj, piesku, piesku..." ], "dsek009": [ - "There goes that crazy crocadog again...!" + "Znowu ten szalony krokopies!" ], "dsek010": [ "Goń dzieciaka!" @@ -2981,13 +2985,13 @@ "Krokopies!" ], "dsek013": [ - "Phew, finally... let's get these two to Kor!" + "Uff, w końcu... Zabierzmy tę dwójkę do Kora!" ], "ero001": [ "Zejdź mi z drogi!" ], "ero002": [ - "I own this track!" + "Ta trasa należy do mnie!" ], "ero003": [ "Poddaj się, Eco dziwolągu!" @@ -2996,16 +3000,16 @@ "Czas zemsty." ], "ero005": [ - "Let's make this interesting!" + "Zróbmy, żeby było ciekawie!" ], "ero006": [ - "Eat wall!" + "Żryj ścianę!" ], "ero007": [ "Pora umierać!" ], "ero008": [ - "Move over!" + "Przesuń się!" ], "ero009": [ "Złap mnie teraz, frajerze!" @@ -3014,49 +3018,49 @@ "Jestem dla Ciebie zbyt szybki!" ], "ero011": [ - "Now you're racing with the big boys!" + "Teraz ścigasz się z dużymi chłopcami!" ], "ero012": [ - "Here's one for the Baron." + "Oto jeden dla Barona." ], "ero013": [ - "Take this!" + "A masz!" ], "ero014": [ - "You're making this too easy!" + "Za bardzo to ułatwiasz!" ], "ero015": [ "Hahaha, na razie!" ], "ero016": [ - "You want some?" + "Szukasz guza?" ], "ero017": [ - "Now you see why I never lose." + "Teraz widzisz, dlaczego nigdy nie przegrywam." ], "ero018": [ - "The crowd loves me!" + "Publika mnie kocha!" ], "ero019": [ "Ahh!" ], "ero020": [ - "Here's some pain!" + "A teraz zaboli!" ], "ero021": [ - "Try to erase these!" + "Spróbuj znieść to!" ], "ero022": [ - "How's your reflexes?" + "Jak tam twój refleks?" ], "ero023": [ - "Too much for you?!" + "Czyżby to było za dużo dla ciebie?!" ], "ero024": [ - "Had enough?" + "Masz dosyć?" ], "ero025": [ - "Avoid this, smart-ass!" + "Uniknij to, cwaniaku!" ], "ero026": [ "Powiedz dobranoc, eco świrze!" @@ -3065,25 +3069,25 @@ "Nie możesz mnie pokonać!" ], "ero028": [ - "I'd die before I let you win!" + "Prędzej umrę, nim pozwolę ci wygrać!" ], "ero029": [ "To będzie twoje ostatnie okrążenie." ], "ero030": [ - "Crash and burn!" + "Próbowałeś i przegrałeś!" ], "ero031": [ "Do końca!" ], "ero032": [ - "Last lap to live!" + "Ostatnie okrążenie o życie!" ], "ero033": [ - "Now we end this!" + "Teraz to zakończymy!" ], "ero034": [ - "You won't see the finish line!" + "Nie zobaczysz linii mety!" ], "ero035": [ "GIŃ!" @@ -3110,7 +3114,7 @@ "AHHHHHHH!" ], "ero043": [ - "Here we go." + "Zaczynamy." ], "ero044": [ "Do zobaczenia później." @@ -3125,61 +3129,61 @@ "Ten wyścig jest mój!" ], "ero048": [ - "You can never be as fast as me!" + "Nigdy nie będziesz tak szybki jak ja!" ], "ero049": [ "Keira pragnie prawdziwego mężczyzny." ], "ero050": [ - "Bad luck, old chap." + "Pech, stary." ], "ero051": [ "Niezła próba." ], "ero052": [ - "Move over!" + "Przesuń się!" ], "ero053": [ - "Out of my way!" + "Zejdź mi z drogi!" ], "ero054": [ - "Coming through!" + "Przeganiam cię!" ], "ero055": [ "Pa pa!" ], "ero056": [ - "Here I come!" + "Nadchodzę!" ], "ero057": [ - "Get used to watching my back!" + "Przyzwyczaj się do osłaniania moich pleców!" ], "ero058": [ "To jest moje miasto, eco świrze." ], "ero059": [ - "Looking sloppy, Jak." + "Wyglądasz marnie, Jak." ], "ero060": [ - "Give it up!" + "Odpuść sobie!" ], "ero061": [ "Nie tym razem." ], "ero062": [ - "Getting a bit nervous?" + "Trochę się denerwujemy?" ], "ero063": [ "Wróć tutaj!" ], "ero064": [ - "Move over, slowpoke!" + "Suń się, ślamazaro!" ], "ero065": [ - "This is where I beat you." + "I to jest ten moment gdzie cię pokonuje." ], "ero066": [ - "Final stretch!" + "Ostatnia prosta!" ], "ero067": [ "To koniec!" @@ -3188,13 +3192,13 @@ "To miasto należy do mnie." ], "ero069": [ - "What? Where'd you come from?" + "Co? Skąd się wziąłeś?" ], "ero070": [ "Miałeś farta." ], "ero071": [ - "You can't handle the speed!" + "Nie poradzisz sobie z prędkością!" ], "ero072": [ "Giń, świrze." @@ -3221,53 +3225,53 @@ "Uff!" ], "ero080": [ - "Beat it, freak!" + "Walcz, dziwaku!" ], "ero081": [ - "Care to get back in the chair?" + "Chcesz wrócić na to krzesło?" ], "ero082": [ "Ten wyścig był za prosty." ], "ero083": [ - "It was easier than I thought to beat you." + "Pokonanie ciebie było łatwiejsze, niż myślałem." ], "ero084": [ - "Not even close, Keira's betting on the wrong man." + "To nawet nie było blisko, Keira postawiła na złego mężczyznę." ], "ero085": [ - "Loser! You disgust me!" + "Nieudacznik! Obrzydzasz mnie!" ], "ero086": [ - "You see Jak, I win, and I get what I want.", - "Someday I will be Baron, then the city will really pay!" + "Widzisz Jak, Ja wygrywam I dostaję, to czego chcę.", + "Kiedyś zostanę Baronem i wtedy miasto naprawdę za to zapłaci!" ], "ero087": [ - "I should have known you'd be no match." + "Powinienem był wiedzieć, że nie będziesz się równać." ], "ero088": [ - "I win, Keira's going to love me!" + "Wygrałem, Keira mnie pokocha!" ], "ero089": [ - "Maybe you should go back to wherever you came from." + "Może powinieneś wrócić tam, skąd przyszedłeś." ], "ero090": [ - "I'll get a victory kiss from Keira later." + "Później dostanę od Keiry pocałunek zwycięstwa." ], "ero091": [ - "Again I prove my superiority." + "Po raz kolejny udowodnię moją wyższość." ], "ero092": [ - "You see? You are no match for me." + "Widzisz! Nie możesz się ze mną równać." ], "ero093": [ - "Too bad, I win!" + "Jaka szkoda. Ja wygrałem!" ], "ero094": [ - "Hahahaha, pathetic insect, I win!" + "Hahahaha, żałosny insekcie, Ja wygrałem!" ], "ero095": [ - "You can never defeat me!" + "Nigdy mnie nie pokonasz!" ], "ero096": [ "Ahhh!...ahh." @@ -3297,76 +3301,76 @@ "DAUGHH!" ], "erol001": [ - "I'm looking for you, eco freak,", - "and when I find you, you'll wish you died in prison." + "Szukam cię, dziwolągu Eco,", + "a kiedy cię znajdę, będziesz żałować, że nie umarłeś w więzieniu." ], "erol002": [ - "This is Erol. Looks like you're running out of friends.", - "We've arrested them all and thrown them into your", - "favorite prison. By the way, that blonde girl Tess", - "screamed so delightfully when she was arrested.", - "I can't wait for her turn in the chair.", + "Tu Erol. Wygląda na to, że kończą ci się przyjaciele.", + "Aresztowaliśmy ich wszystkich i wrzuciliśmy do twojego", + "ulubionego więzienia. A swoją drogą, ta blondynka Tess", + "krzyczała tak rozkosznie, kiedy została aresztowana.", + "Nie mogę się doczekać jej kolei na krześle.", "Hahahahaha...." ], "erol003": [ - "This is Erol. Just remember, the only reason I'm letting you", - "walk is so I can face you in the championship race!" + "Tu Erol, Pamiętaj, jedynym powodem, dla którego ci pozwalam", + "odejść, żeby móc zmierzyć się z tobą w wyścigu o mistrzostwo!" ], "hal001": [ - "Quiet! Here comes pretty boy." + "Cicho! Nadchodzi goguś." ], "hal002": [ - "'Bout time you showed up. Okay, let's do this." + "W samą porę się pojawiłeś. OK, zróbmy to." ], "hal003": [ - "Krew said you'll protect us all the way to the statue." + "Krew powiedział, że będziesz nas chronić aż do posągu." ], "hal004": [ - "We go down!" + "Idziemy w dół!" ], "hal006": [ - "This way!" + "Tędy!" ], "hal007": [ - "AHH! It's a Metal Head! Shoot it, shoot it!" + "AHH! To Metalowy Łeb! Zastrzel to, zastrzel to!" ], "hal008": [ - "Stay with us!" + "Zostań z nami!" ], "hal009": [ - "Man, Krew's gonna be pissed if you mess this up." + "Człowieku, Krew będzie wkurzony, jeśli to schrzanisz." ], "hal010": [ - "Don't leave us to die!" + "Nie zostawiaj nas na śmierć" ], "hal011": [ - "You ditch us and Krew's gonna mess you up!" + "Porzuć nas, a Krew cię zrujnuje!" ], "hal012": [ - "We need to stay together." + "Musimy się trzymać razem." ], "hal013": [ - "I thought this guy was supposed to be protecting us!" + "Myślałem, że ten facet miał nas chronić!" ], "hal014": [ - "That's it! We're calling the mission off,", - "we don't go until you're serious." + "Starczy! Odwołujemy misję,", + "nie pójdziemy, dopóki nie zaczniesz tego traktować poważnie." ], "hal015": [ - "I'm not getting killed because of this loser,", - "this mission is over." + "Nie dam się zabić przez tego frajera,", + "Ta misja jest skończona." ], "hal019": [ - "Let's go back before we all get killed." + "Wracajmy, zanim wszyscy zginiemy." ], "hal020": [ - "Ugh, this place stinks." + "Uch, to miejsce śmierdzi." ], "hal021": [ - "I got a bad feeling about this place." + "Mam złe przeczucia co do tego miejsca." ], "hal022": [ - "Uh oh, I think I wet myself." + "Uh oh, Myślę, że się zmoczyłem." ], "hal023": [ "Nie! Proszę!" @@ -3378,16 +3382,16 @@ "Uhh, słyszę rzeczy." ], "hal026": [ - "Let's go back." + "Wracajmy." ], "hal027": [ - "Move your butts, or I'll move 'em for ya!" + "Ruszcie swoje tyłki albo, Ja je za was poruszę!" ], "hal028": [ - "This job beats being a garbage man." + "Ta praca jest gorsza od bycia śmieciarzem." ], "hal029": [ - "Ain't the smell of sulphur grand?" + "Czyż zapach siarki nie jest wspaniały?" ], "hal030": [ "Zakryj uszy!" @@ -3396,223 +3400,223 @@ "Kocham tę robotę." ], "hal032": [ - "Great, now we're trapped in this slime pit!" + "Świetnie, teraz utknęliśmy w tym śluzie!" ], "hal033": [ - "Shoot, baby, shoot!" + "Strzelaj, młody, strzelaj!" ], "hal034": [ - "Ahh! The ceiling's crawling!" + "Ach! To pełza po suficie!" ], "hal035": [ - "I can't get away!" + "Nie mogę uciec!" ], "hal036": [ - "There's one coming right at me!" + "Jeden z nich idzie prosto na mnie!" ], "hal037": [ - "It sees me!" + "Widzi mnie!" ], "hal038": [ - "Ahh! Stay away!" + "Ahh! Trzymaj się z dala!" ], "hal039": [ - "It's hitting me!" + "Atakuje mnie!" ], "hal040": [ - "Gahh, I'm gonna die here!" + "Gahh, Umrę tutaj!" ], "hal041": [ - "I'm getting zapped!" + "Razi mnie prąd!" ], "hal042": [ - "This'll be the end of me!" + "To będzie mój koniec!" ], "hal043": [ - "Help me! I've got eight kids to feed!" + "Pomóż mi! Mam ośmioro dzieci do wykarmienia!" ], "hal044": [ - "Nice work, those were some nasty Metal Heads." + "Dobra robota, to były paskudne Metalowe Łby." ], "hal045": [ - "There you are, why don't you make yourself useful?" + "Tu jesteście, dlaczego nie zrobisz z siebie pożytku?" ], "hal046": [ - "Keep moving!" + "Ruszać się!" ], "hal047": [ - "On we go, we're not getting any younger." + "Chodźmy, stojąc tutaj nie staniemy się młodsi." ], "hal048": [ - "Ahh! They're crawling down the walls!" + "Ach! Spełzają ze ścian!" ], "hal049": [ - "Way to go, this is where I come in." + "Dobra robota, tu wkraczam ja." ], "hal050": [ - "You mean cover your ass! Fire in the hole!" + "Masz na myśli, chroń swój tyłek! Ognia!" ], "hal051": [ - "You better keep your head down, sugar." + "Lepiej nie podnoś głowy, cukiereczku." ], "hal052": [ - "Your bad breath, let's move." + "Masz paskudny oddech, chodźmy." ], "hal053": [ - "That straightened your hair, huh?", - "Hehe, next time you'll listen to me. Okay, let's move." + "To wyprostowało ci włosy, co?", + "Hehe, następnym razem mnie posłuchasz. Okej, idziemy dalej." ], "hal054": [ "O, to musiało boleć.", - "I told you to keep back, but no one ever listens to Jinx." + "Mówiłem ci, żebyś pilnował tyłów, ale nikt nigdy nie słucha Jinx'a." ], "hal055": [ - "More of those monsters!" + "Więcej tych potworów!" ], "hal056": [ - "So what, we got a dream team here. Do your stuff, Jak!" + "I co z tego, mamy tu zespół marzeń. Rób swoje, Jak!" ], "hal057": [ - "Jak! Get your butt up here and do your thing." + "Jak! Rusz tu tyłek i rób swoje." ], "hal058": [ - "Take 'em out, blue boy." + "Zdejmij ich, niebieski chłopcze." ], "hal059": [ - "You're pretty handy with that iron, blondie." + "Całkiem nieźle sobie radzisz z tym żelastwem, blondasku." ], "hal060": [ "Zamknij się, Mog." ], "hal061": [ - "Here they come again!" + "Znowu nadchodzą!" ], "hal062": [ - "Get up here and earn your keep!" + "Wejdź tutaj i zarób na swoje utrzymanie!" ], "hal063": [ - "Krew was right about you. You got the magic, man." + "Krew miał co do ciebie rację. Masz w sobie to coś, stary." ], "hal064": [ - "Nice fighting, man, I'm beginning to like you." + "Niezła walka, stary, zaczynam cię lubić." ], "hal065": [ - "Okay... that doesn't look good. Jak, you're up!" + "Okej... to nie wygląda dobrze. Jak twoja kolej!" ], "hal066": [ - "Wow! Beams of death!", - "I'm staying right here 'til you do something about that." + "Łał! Promienie śmierci!", + "Zostaje tutaj, dopóki czegoś z tym nie zrobisz." ], "hal067": [ - "Uhhh, Jak. I think you're the man for this job." + "Uhhh, Jak. Myślę, że jesteś właściwym człowiekiem do tej roboty." ], "hal068": [ - "Jump the beams, Jak." + "Przeskocz promienie, Jak." ], "hal069": [ "Niezłe ruchy." ], "hal070": [ - "Yeah... you wish, tubby." + "Tak... chciałbyś, grubasku." ], "hal071": [ - "We're staying put 'til you take out those Metal Heads." + "Nie ruszamy się, póki nie załatwisz tych Metalowych Łbów." ], "hal072": [ - "Sweet as a ballerina, hehehehe..." + "Słodki jak balerina, hehehehe..." ], "hal073": [ - "Knock 'em silly, Jak!" + "Skop im dupska, Jak!" ], "hal074": [ - "This one's gonna be loud!" + "Ten będzie głośny!" ], "hal075": [ "To jest zbyt proste." ], "hal080": [ - "We ain't moving, 'til you kill 'em all!" + "Nigdzie nie pójdziemy, póki ich wszystkich nie zabijesz!" ], "hal081": [ - "OK, let's get out of here before more come back." + "Okej, Wynośmy się stąd, zanim wrócą kolejni." ], "hal082": [ - "You're earning your dough today. Let's finish this!" + "Zarobisz dzisiaj swoją forsę. Skończmy to!" ], "hal083": [ - "I'm impressed, Jak. I'll put in a good word with the boss." + "Jestem pod wrażeniem, Jak. Szepnę dobre słówko szefowi." ], "hal084": [ "Tak, zrób to, Jinx." ], "hal085": [ - "Man, Jinx, what'd you put in those boomsticks?" + "Człowieku, Jinx, coś ty włożył do tych ładunków wybuchowych?" ], "hal086": [ - "Look at him go." + "Spójrz jak szybko dorasta." ], "hal087": [ "Chciałbym tak skakać." ], "hal088": [ - "Get away from me, you crazy monster!" + "Odejdź ode mnie, ty zwariowany potworze!" ], "hal090": [ - "This is where I come in, cover your ears." + "Tu właśnie wkraczam ja, zakryjcie swoje uszy." ], "hal091": [ "Uwaga, granat!" ], "hal092": [ - "And on we go." + "No to lecimy." ], "hal093": [ "Proszę, pozwól mi." ], "hal094": [ - "One unclogged sewer, comin' up." + "Jedno za sypnięte przejście, ogarnięte." ], "hal095": [ - "This is my boomshtick!" + "To mój boomsztyk!" ], "hal096": [ "Boom, dziecinko!" ], "hal097": [ - "We're clear, let's move." + "Jesteśmy bezpieczni, ruszajmy." ], "hal101": [ - "Ahh! That's gonna leave a mark." + "Ahh! Będzie po tym ślad." ], "hal102": [ - "Die! A little help would be good!" + "Zdychaj! Przydałaby się mała pomoc!" ], "hal103": [ - "Watch it, pretty boy, or I'll rearrange your face." + "Hej uważaj, przystojniaku, albo dostaniesz w mordę." ], "hal104": [ - "You got an itchy trigger finger." + "Palec cię świerzbi na spuście." ], "hal107": [ "Bułka z masłem." ], "hal108": [ - "Get over here, Jak!" + "Chodź tu, Jak!" ], "hal109": [ - "Stay close, pretty boy!" + "Trzymaj się blisko, przystojniaku!" ], "hal111": [ - "Keep with us, tough guy!" + "Trzymaj się z nami, twardzielu!" ], "hal112": [ - "You're in the way, Jak, move!" + "Stoisz na drodze, Jak, rusz się!" ], "hal113": [ - "I wouldn't stand there if I were you!" + "Nie stałbym tam, na twoim miejscu!" ], "hal114": [ - "This is gonna be loud." + "To będzie głośne." ], "hal115": [ "Oh!" @@ -3627,14 +3631,14 @@ "To pułapka!" ], "hal119": [ - "Yeah, why did we sign up for this?" + "Pewnie, dlaczego się na to pisaliśmy?" ], "hal120": [ - "I got 30 keys of high explosives strapped to my back...", + "Mam 30 ładunków wybuchowych przypiętych do moich pleców...", "Świetnie..." ], "hal121": [ - "Just shut your whiny traps and keep moving." + "Zamknij swoje marudne dupsko i chodź dalej." ], "hal122": [ "Uh, Czy musimy?" @@ -3643,37 +3647,37 @@ "Uhh, słyszeliście to?" ], "hal124": [ - "We are so dead, man." + "Już po nas, stary." ], "hal125": [ - "Shut up! I'll go ahead and check it out..." + "Zamknij się! Pójdę przodem i sprawdzę to..." ], "hal126": [ - "Man, that thing's ugly." + "Kurczę, to coś jest brzydkie." ], "hal127": [ - "Get him, man, before he gets us." + "Dorwij go, człowieku, zanim on nas dorwie." ], "hal128": [ - "They're coming up from behind, too!" + "Oni nadchodzą też od tyłu!" ], "hal129": [ "Jak jest moim bohaterem." ], "hal130": [ - "Sounds like I got gas." + "Brzmi jakby ktoś miał gazy." ], "hal131": [ "Nienawidzę Krew." ], "hal132": [ - "I'm sure not going back that way!" + "Na pewno nie wrócę tamtą drogą!" ], "hal133": [ - "It's coming for me!" + "Idzie po mnie!" ], "hal134": [ - "I think it wants me!" + "Myślę, że chce mnie!" ], "hal135": [ "Pomóż mi, Jak!" @@ -3682,22 +3686,22 @@ "Ja umrę!" ], "hal137": [ - "It got me!" + "Ma mnie!" ], "hal138": [ "Jak! Ocal mnie!" ], "hal139": [ - "Ughh! It got me!" + "Ughh! Ma mnie!" ], "hal140": [ - "Oughh! That beam smarts." + "Oughh! Ten promień jest sprytny." ], "hal141": [ - "I've been shot!" + "Zostałem postrzelony!" ], "hal142": [ - "I'm hit!" + "Zostałem trafiony!" ], "hal143": [ "Ughh!" @@ -3706,13 +3710,13 @@ "Ughh! Pomóż mi!" ], "hal145": [ - "Hey man, watch it!" + "Hej, stary, uważaj!" ], "hal146": [ - "Ohh, hit me again and I'll pound you!" + "Och, uderz mnie jeszcze raz, a ci przewalę!" ], "hal147": [ - "Nobody's my friend..." + "Nikt nie jest moim przyjacielem..." ], "hal148": [ "Uff!" @@ -3724,7 +3728,7 @@ "Ahh!" ], "hal151": [ - "He's got me!" + "On mnie ma!" ], "hal152": [ "Gahh!! Nie no znowu!" @@ -3733,19 +3737,19 @@ "Umieram!" ], "hal154": [ - "Any more like that, then I'm history." + "Jeszcze jedno takie coś, a przejdę do historii." ], "hal155": [ - "I'm getting shot!" + "Zostałem postrzelony!" ], "hal156": [ - "Sure! Why don't you kill me too?" + "Jasne! Dlaczego mnie też nie zabijesz?" ], "hal157": [ - "Check your targets, wimp boy!" + "Sprawdź swoje cele, Cieniasie!" ], "hal158": [ - "Shoot the shine-heads, not me!" + "Strzelaj do świecących łbów, nie do mnie!" ], "hal159": [ "Ahh!" @@ -3766,70 +3770,70 @@ "Uważaj!" ], "hal166": [ - "We're not doing this with a rookie, I'm calling this off!" + "Nie będziemy tego robić z żółtodziobem, Odwołuję to!" ], "hal167": [ - "That's it, we're done! Come back when you're serious." + "Wystarczy, skończyliśmy! Wróć, kiedy będziesz poważny." ], "hal168": [ - "I'm cornered!" + "Jestem przygwożdżony!" ], "hal169": [ - "It's gonna shoot me!" + "To coś mnie zastrzeli!" ], "hal170": [ "Jaki! Zrób coś!" ], "hal171": [ - "Ahh! It got me!" + "Ahh! Mam mnie!" ], "hal172": [ "Nie nie nie! Pomocy!" ], "hal173": [ - "They're getting too close, Jak!" + "Podchodzą za blisko, Jak!" ], "hal174": [ - "It's gonna get me!" + "Dopadnie mnie!" ], "hal175": [ - "I'm getting killed here!" + "Zginę tutaj!" ], "hal176": [ - "Jak! I'm about to be metal meat!" + "Jak! Zaraz stanę się metalowym żarciem!" ], "hal177": [ - "Aghh! That beam burns!" + "Aghh! Ten promień pali!" ], "hal178": [ - "It's shooting me!" + "Strzela do mnie!" ], "hal179": [ - "Watch out for the beam!" + "Uważaj na promień!" ], "hal180": [ - "I'm shot!" + "Jestem postrzelony!" ], "hal181": [ - "I'm trapped!" + "Jestem uwięziony!" ], "hal182": [ - "Get back... I'm gonna detonate this one remotely." + "Wracaj... Zdetonuje ten zdalnie." ], "hal183": [ "He-hah!" ], "hal184": [ - "Alright!" + "W porządku!" ], "hal185": [ - "Let's go!" + "Jazda!" ], "hal186": [ "Ruszajcie się!" ], "hal187": [ - "That's a lot of Metal Heads." + "To jest mnóstwo Metalowych Łbów." ], "hal188": [ "Uff!" @@ -3841,10 +3845,10 @@ "Oughh..." ], "hal191": [ - "Krew's dead for getting me into this!" + "Krew już nie żyje za to, że mnie w to wciągnął!" ], "jak001": [ - "Alright!" + "W porządku!" ], "jak002": [ "O tak!" @@ -3853,7 +3857,7 @@ "Wooo!" ], "jak004": [ - "Here we go!" + "Zaczynamy!" ], "jak005": [ "Nieźle!" @@ -3862,7 +3866,7 @@ "Rock 'n roll!" ], "jak007": [ - "Right on!" + "Dobra!" ], "jak008": [ "Spoko!" @@ -3874,10 +3878,10 @@ "O tak!" ], "jak011": [ - "Comin' through!" + "Nadciągam!" ], "jak012": [ - "Look out!" + "Uważaj!" ], "jak013": [ "Ostatnie okrążenie!" @@ -3892,43 +3896,43 @@ "Łoł!" ], "jak017": [ - "Hold on, Dax!" + "Trzymaj się, Dax!" ], "jak018": [ - "Hang on, Dax!" + "Trzymaj się, Dax!" ], "jak020": [ - "Whoa... boy that was close." + "łoo... chłopie to było blisko." ], "jak021": [ - "No!" + "Nie!" ], "jak022": [ - "Not this time." + "Nie tym razem." ], "jak023": [ "Huargh!" ], "jak024": [ - "Lean, baby, lean!" + "Z chyl się, stary, z chyl!" ], "jak025": [ - "Catch him on the inside!" + "Złapiemy go po drugiej stronie!" ], "jak026": [ - "This is MY show!" + "To MÓJ pokaz!" ], "jak027": [ - "Haha, we got him!" + "Haha, Mamy go!" ], "jak028": [ - "Watch out!" + "Uważaj!" ], "jak029": [ - "You're dead, Erol!" + "Już nie żyjesz, Erol!" ], "jak030": [ - "See ya!" + "Do zobaczenia!" ], "jak031": [ "Haha!" @@ -3943,91 +3947,91 @@ "Później." ], "jak035": [ - "We gotta catch up!" + "Musimy nadgonić!" ], "jak036": [ "Tu jest!" ], "jak037": [ - "Come on, baby, show me what you got!" + "No dawaj, skarbie pokaż mi, na co cię stać!" ], "jak038": [ - "Here we go!" + "Zaczynamy!" ], "jak039": [ "Urgh!" ], "jak040": [ - "I'll take this." + "Wezmę to." ], "jak041": [ - "I need to borrow this." + "Potrzebuje to pożyczyć." ], "jak042": [ - "Move over, buddy!" + "Przesuń się, kolego!" ], "jak044": [ - "Outta the vehicle!" + "Wyłaź z pojazdu!" ], "jak045": [ - "Outta my way, buddy!" + "Zejdź mi z drogi, kolego!" ], "jak046": [ - "Thanks for the lift." + "Dzięki za podwózkę." ], "jak047": [ - "Mind if I drive?" + "Nie masz nic przeciwko, jeśli poprowadzę?" ], "jak048": [ - "I like the color of this vehicle." + "Podoba mi się kolor tego pojazdu." ], "jak049": [ - "Mine now." + "Jest teraz mój." ], "jak050": [ - "'Scuse me, but I need this." + "Przepraszam, ale potrzebuję tego." ], "jak051": [ - "Take a hike, buddy!" + "Zjeżdżaj, kolego!" ], "jak052": [ - "Try walking." + "A próbowałeś chodzić na spacery?" ], "jak053": [ - "Sorry, but I'm in a hurry!" + "Przepraszam, ale się spieszę!" ], "jak054": [ - "Gotta go!" + "Muszę iść!" ], "jak055": [ - "Get another vehicle!" + "Zdobądź inny pojazd!" ], "jak056": [ - "Road hog!" + "Pirat drogowy!" ], "jak057": [ - "Brake yourself!" + "Zatrzymaj się!" ], "jak059": [ - "Haha, you want some?" + "Haha, szukasz guza?" ], "jak060": [ - "Get some!" + "Chcesz więcej!" ], "jak061": [ - "Yeah, feel it!" + "Tak, poczuj to!" ], "jak062": [ "Giń!" ], "jak063": [ - "Badass comin' through!" + "Twardziel nadchodzi!" ], "jak064": [ - "Be afraid. Be very afraid." + "Bój się. Bardzo się bój." ], "jak065": [ - "Oooh, that's gotta hurt." + "Ooo, to będzie bolało." ], "jak066": [ "Oto zemsta." @@ -4042,47 +4046,47 @@ "To jest moje miasto, Kor!" ], "jak070": [ - "Surprise... you can't kill me in my dark form." + "Niespodzianka... nie możesz zabić mnie w mojej mrocznej formie." ], "jak071": [ - "Now you pay!" + "Teraz zapłacisz!" ], "jak072": [ - "Go back to the past, Kor! 'Cause you're history." + "Wracaj do przeszłości, Kor! Bo jesteś historią." ], "jak073": [ - "I win." + "Wygrałem." ], "jak074": [ - "You should have killed me when you had the chance, Praxis." + "Powinieneś był mnie zabić, kiedy miałeś szansę, Praxis." ], "jak075": [ - "Daxter, just shut up and watch my back." + "Daxter, zamknij się i pilnuj moje plecy." ], "jak076": [ - "Whatever, Daxter." + "Nieważne, Daxter." ], "jak077": [ - "Will you stop yappin'?" + "Przestaniesz gadać?" ], "jak078": [ - "When you got smaller, so did your brain." + "Kiedy stałeś się mniejszy, to i twój mózg także." ], "jak079": [ - "You're on MY shoulder. YOU'RE the sidekick." + "Jesteś na MOIM ramieniu. TY JESTEŚ pomocnikiem." ], "jak080": [ - "As long as you're on MY shoulder, keep your mouth shut." + "Dopóki jesteś na MOIM ramieniu, trzymaj gębę na kłódkę." ], "jd001": [ - "Hey, kid! Wait! Come back!", + "Hej, mały! Czekaj! Wracaj!", "Musimy go ochronić!" ], "jk001": [ "Poczekaj, MŁODY!" ], "jk002": [ - "There he goes!" + "I znowu polazł!" ], "jk003": [ "Zostaw go w spokoju!" @@ -4091,13 +4095,13 @@ "MŁODY!" ], "jk005": [ - "Pick on someone your own size!" + "Wybierz kogoś swojego rozmiaru!" ], "jk006": [ "Młody, uważaj!" ], "jk007": [ - "How do YOU like it when somebody fights back?" + "Jak ci się podoba, gdy ktoś się broni?" ], "jk008": [ "Zostaw dzieciaka w spokoju!" @@ -4106,7 +4110,7 @@ "To tylko dziecko!" ], "jk010": [ - "Keep away from him!" + "Trzymaj się z dala od niego!" ], "jk011": [ "Teraz mnie wkurzyłeś!" @@ -4115,77 +4119,77 @@ "Żryj to!" ], "jk013": [ - "Back off!" + "Cofnij się!" ], "jk014": [ - "We gotta get in the vehicle with the Kid!" + "Musimy wsiąść do pojazdu z Dzieciakiem!" ], "jk015": [ - "Hold on!" + "Trzymać się!" ], "jk016": [ - "Keep your head down, Kid!" + "Trzymaj głowę nisko, chłopcze!" ], "jk017": [ - "Stick with me, Kid, and you'll be safe." + "Trzymaj się mnie, Dzieciaku, a będziesz bezpieczny." ], "jk018": [ - "Stay with me, Kid!" + "Trzymaj się ze mną, Dzieciaku!" ], "jk019": [ - "Get in the vehicle, Dax!" + "Wsiadaj to pojazdu, Dax!" ], "kei001": [ - "You can get on and off the JET-Board at any time." + "Możesz wsiąść i zejść z Deski Odrzutowej w każdym momencie." ], "kei002": [ "Możesz skakać na swojej Desce Odrzutowej!" ], "kei003": [ - "Jump up on that ledge." + "Skocz na tę półkę." ], "kei004": [ - "Try jumping up on that crate." + "Spróbuj wskoczyć na tę skrzynię." ], "kei005": [ "Przeskocz nad tą przeszkodą." ], "kei006": [ - "You can get a higher jump by ducking before you jump!" + "Możesz uzyskać wyższy skok robiąc to z przykucu, zanim skoczysz!" ], "kei007": [ - "Try doing a duck jump over that obstacle." + "Spróbuj zrobić skok z przykucu przez tą przeszkodą." ], "kei008": [ - "Jump and jump again a little after you've landed", - "for an even bigger launch!" + "Skacz i skocz ponownie chwilę po wylądowaniu", + "aby uzyskać jeszcze większy podskok!" ], "kei009": [ - "Try getting up on that higher ledge with a boost jump!" + "Spróbuj dostać się na wyższą półkę za pomocą doładowanego skoku!" ], "kei010": [ - "You can spin in the air!" + "Możesz wirować w powietrzu!" ], "kei011": [ - "Land a perfect 360 for a speed boost!" + "Wykonaj idealny obrót, aby zwiększyć prędkość!" ], "kei012": [ "Niezły obrót!" ], "kei013": [ - "You can land on a rail and grind across it." + "Możesz wylądować na poręczy i prześlizgnąć się po niej." ], "kei014": [ - "Try grinding on that rail." + "Spróbuj prześlizgnąć się na tej poręczy." ], "kei016": [ - "You can do flips while you jump!" + "Podczas skoku możesz wykonywać salta!" ], "kei017": [ - "You can also do tricks for fun." + "Możesz także wykonywać triki dla zabawy." ], "kei018": [ - "Try to put a number of moves together to get points." + "Spróbuj połączyć ze sobą kilka ruchów, aby zdobyć punkty." ], "kei019": [ "Zdobądź wystarczającą ilość punktów, by wygrać wyzwanie!" @@ -4197,32 +4201,32 @@ "Dobra robota!" ], "kei022": [ - "Close, but not quite there." + "Blisko, ale nie do końca." ], "kei023": [ "Spróbuj ponownie." ], "kei024": [ - "A little more work and you just might win!" + "Jeszcze trochę pracy i możesz wygrać!" ], "kei025": [ - "No good! Not enough points." + "Nie dobrze! Nie starczyło punktów." ], "kei026": [ - "The Underground said you needed some help,", - "you won't be able to catch those Metal Heads in the", - "Forest on foot so I've left my JET-Board at the airlock", - "near the city exit. Since you're helping the Underground,", + "Podziemie powiedziało, że potrzebujesz pomocy,", + "nie będziesz w stanie złapać tych Metalowych Łbów w", + "Lesie na piechotę, więc zostawiłam moją Deskę Odrzutową przy śluzie.", + "w pobliżu wyjścia z miasta. Skoro pomagasz Podziemiu,", "Pozwolę ci nawet to zatrzymać!" ], "kei027": [ "Jak, to Keira. Nie zapomnij - Nadal potrzebuję dwóch artefaktów", - "to make the Rift Rider work! I need the Time Map and the", - "Heart of Mar Energy Gem, or we're not going anywhere!" + "żeby Jeździec Szczeliny działał! Potrzebuję Mapy Czasu i", + "klejnot Energii Serca Mara, albo nigdzie się nie wybierzemy!" ], "kei028": [ - "I still need those two artifacts or this pile of junk", - "won't move one city block, much less through the Rift", + "Nadal potrzebuję tych dwóch artefaktów albo ta kupa złomu", + "nie ruszy się ani przez jedną przecznicę, a co dopiero przez szczelinę.", "i wróć do naszych czasów!", "Musisz znaleźć Serce Mara i Mapę Czasu", "albo utkniemy!" @@ -4251,10 +4255,10 @@ "Stój!" ], "kg005": [ - "Get more cruisers in here!" + "Dawać tu więcej radiowozów!" ], "kg005a": [ - "Get more cruisers in here!" + "Dawać tu więcej radiowozów!" ], "kg006": [ "Poddaj się!" @@ -4263,10 +4267,10 @@ "Poddaj się!" ], "kg007": [ - "This is a no-hover zone!" + "To jest strefa bez szybowania!" ], "kg007a": [ - "This is a no-hover zone!" + "To jest strefa bez szybowania!" ], "kg008": [ "Zjedź na bok!" @@ -4296,7 +4300,7 @@ "Hej ty!" ], "kg014": [ - "You want some?!" + "Szukasz guza?!" ], "kg015": [ "Ten obszar jest niedostępny." @@ -4317,13 +4321,13 @@ "Zwolnij!" ], "kg021": [ - "Move over!" + "Przesuń się" ], "kg021a": [ - "Move over!" + "Przesuń się" ], "kg022": [ - "Call in more Hellcats!" + "Wezwać więcej Hellcatów!" ], "kg023": [ "Prosimy o wsparcie!" @@ -4425,16 +4429,16 @@ "Wyjdź z pojazdu!" ], "kg040": [ - "Call in more Hellcats!" + "Wezwać więcej Hellcatów!" ], "kg040a": [ - "Call in more Hellcats!" + "Wezwać więcej Hellcatów!" ], "kg041": [ - "The area is secure." + "Teren jest zabezpieczony." ], "kg041a": [ - "The area is secure." + "Teren jest zabezpieczony." ], "kg042": [ "Nie ma nic do zgłoszenia." @@ -4479,28 +4483,28 @@ "Stracono kontakt wzrokowy." ], "kg049": [ - "He just ducked out." + "Po prostu się wymknął." ], "kg049a": [ - "He just ducked out." + "Po prostu się wymknął." ], "kg050": [ - "He's out of sight." + "Jest poza zasięgiem wzroku." ], "kg050a": [ - "He's out of sight." + "Jest poza zasięgiem wzroku." ], "kg051": [ - "We're losing him!" + "Gubimy go!" ], "kg051a": [ - "We're losing him!" + "Gubimy go!" ], "kg052": [ - "Continuing our sweep." + "Kontynuujemy nasze przeszukiwanie." ], "kg052a": [ - "Continuing our sweep." + "Kontynuujemy nasze przeszukiwanie." ], "kg053": [ "Przeszukiwanie sektora czwartego." @@ -4521,16 +4525,16 @@ "Przeszukiwanie sektora trzeciego." ], "kg056": [ - "Keep looking." + "Szukaj dalej." ], "kg056a": [ - "Keep looking." + "Szukaj dalej." ], "kg057": [ - "He's got to be here somewhere." + "Musi gdzieś tu być." ], "kg057a": [ - "He's got to be here somewhere." + "Musi gdzieś tu być." ], "kg058": [ "Nie mogę go znaleźć." @@ -4539,7 +4543,7 @@ "Nie mogę go znaleźć." ], "kg059": [ - "No sign of the subject." + "Nie ma śladu po poszukiwanym." ], "kg059a": [ "Nie ma śladu po podejrzanych." @@ -4593,10 +4597,10 @@ "Uciekł." ], "kg068": [ - "He shook us." + "On potrząsnął nami." ], "kg068a": [ - "He shook us." + "On potrząsnął nami." ], "kg069": [ "Wygląda na to że zwiał." @@ -4617,16 +4621,16 @@ "Tam jest!" ], "kg072": [ - "Be advised, target in sight." + "Uwaga, cel w zasięgu wzroku." ], "kg072a": [ - "Be advised, target in sight!" + "Uwaga, cel w zasięgu wzroku!" ], "kg073": [ - "We have a positive ID." + "Mamy zgodną tożsamość." ], "kg073a": [ - "We have a positive ID." + "Mamy zgodną tożsamość." ], "kg074": [ "Widzę go!" @@ -4653,16 +4657,16 @@ "Namierzyłem ponownie cel!" ], "kg078": [ - "I'm closing in." + "Otaczam." ], "kg078a": [ - "I'm closing in!" + "Otaczam!" ], "kg079": [ - "I'm on him!" + "Jestem na nim!" ], "kg079a": [ - "I'm on him!" + "Jestem na nim!" ], "kg080": [ "Jestem w pościgu!" @@ -4695,10 +4699,10 @@ "Za nim!" ], "kg085": [ - "I have a visual!" + "Mam kontakt!" ], "kg085a": [ - "I have a visual!" + "Mam kontakt!" ], "kg086": [ "Widzimy go!" @@ -4713,10 +4717,10 @@ "Zatrzymaj się!" ], "kg088": [ - "I have a bead on him!" + "Mam cel na muszce!" ], "kg088a": [ - "I have a bead on him!" + "Mam cel na muszce!" ], "kg089": [ "Zostałem trafiony!" @@ -4773,52 +4777,52 @@ "Więzień jest na poziomie drugim!" ], "kg098": [ - "Prisoner moving to sub-level B!" + "Więzień przemieszcza się na poziom B!" ], "kg098a": [ - "Prisoner moving to sub-level B!" + "Więzień przemieszcza się na poziom B!" ], "kg099": [ - "We think he's in the pipes!" + "Uważamy, że jest w rurach!" ], "kg099a": [ - "We think he's in the pipes!" + "Uważamy, że jest w rurach!" ], "kg100": [ "Zaczynamy nasze poszukiwania." ], "kg100a": [ - "We're beginning our sweep." + "Zaczynamy nasze poszukiwania." ], "kg101": [ - "We have prisoner in sight, move in!" + "Mamy więźnia w zasięgu wzroku, wkraczajcie!" ], "kg101a": [ - "We have prisoner in sight, move in!" + "Mamy więźnia w zasięgu wzroku, wkraczajcie!" ], "kg102": [ - "We have movement on level one!" + "Mamy ruch na poziomie pierwszym!" ], "kg102a": [ - "We have movement on level one!" + "Mamy ruch na poziomie pierwszym!" ], "kg103": [ - "Close in!" + "Otoczyć!" ], "kg103a": [ - "Close in!" + "Otoczyć!" ], "kg104": [ - "We're moving in!" + "Wchodzimy!" ], "kg104a": [ - "We're moving in!" + "Wchodzimy!" ], "kg105": [ - "Secure the cell block!" + "Zabezpieczyć blok więzienny!" ], "kg105a": [ - "Secure the cell block!" + "Zabezpieczyć blok więzienny!" ], "kg106": [ "Nie brać więźniów!" @@ -4827,22 +4831,22 @@ "Nie brać więźniów!" ], "kg107": [ - "Prisoner sighted, we got him!" + "Widziano więźnia, mamy go!" ], "kg107a": [ - "Prisoner sighted, we got him!" + "Widziano więźnia, mamy go!" ], "kg108": [ - "Prisoner is still on the loose!" + "Więzień jest nadal na wolności!" ], "kg108a": [ - "Prisoner is still on the loose!" + "Więzień jest nadal na wolności!" ], "kg109": [ - "We think he's going for an exit!" + "Myślimy, że zmierza do wyjścia!" ], "kg109a": [ - "We think he's going for an exit!" + "Myślimy, że zmierza do wyjścia!" ], "kg110": [ "Przeszukuje pomieszczenia." @@ -4851,28 +4855,28 @@ "Przeszukuje pomieszczenia." ], "kg111": [ - "Prisoner loose in complex." + "Wiezień jest na wolność w kompleksie." ], "kg111a": [ - "Prisoner loose in complex." + "Wiezień jest na wolność w kompleksie." ], "kg112": [ - "You are authorized to shoot to kill." + "Macie zezwolenie strzelać, aby zabić." ], "kg112a": [ - "You are authorized to shoot to kill." + "Macie zezwolenie strzelać, aby zabić." ], "kg113": [ - "Go, go, go! Sweep the area!" + "Ruchy, ruchy, ruchy! Przeszukać teren!" ], "kg113a": [ - "Go go go! Sweep the area!" + "Ruchy, ruchy, ruchy! Przeszukać teren!" ], "kg114": [ - "Searching the sub-basements." + "Przeszukujemy piwnice." ], "kg114a": [ - "Searching the sub-basements." + "Przeszukujemy piwnice." ], "kg115": [ "Blok cel jest czysty." @@ -4881,25 +4885,25 @@ "Blok cel jest czysty." ], "kg116": [ - "Tank room is clear." + "Magazyn z czołgami jest czysty." ], "kg116a": [ - "Tank room is clear." + "Magazyn z czołgami jest czysty." ], "kg117": [ - "Activate riot tanks." + "Aktywować czołgi do zamieszek." ], "kg117a": [ - "Activate riot tanks." + "Aktywować czołgi do zamieszek." ], "kg118": [ - "Riot tank has prisoner in sight." + "Czołg od zamieszek ma więźnia w zasięgu wzroku." ], "kg118a": [ - "Riot tank has prisoner in sight." + "Czołg od zamieszek ma więźnia w zasięgu wzroku." ], "kg119": [ - "Intruder alert." + "Alarm intruz" ], "kg119a": [ "Alarm intruz!" @@ -4911,10 +4915,10 @@ "Aktywacja zabezpieczeń ochrony." ], "kg121": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg121a": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg122": [ "Mamy cywili na widoku." @@ -4941,10 +4945,10 @@ "Jasne, sprawdzimy to." ], "kg126": [ - "Confirmed, Underground suspect neutralized." + "Potwierdzone, Agent Podziemia został zneutralizowany." ], "kg126a": [ - "Confirmed, Underground suspect neutralized." + "Potwierdzone, Agent Podziemia został zneutralizowany." ], "kg127": [ "Wszyscy są winni!" @@ -4977,16 +4981,16 @@ "Przyjąłem to, robimy przeszukanie." ], "kg132": [ - "I say shoot 'em all and sort 'em out later." + "Mówię, zastrzel ich wszystkich i uporządkuj ich później." ], "kg132a": [ - "I say shoot 'em all and sort 'em out later." + "Mówię, zastrzel ich wszystkich i uporządkuj ich później." ], "kg133": [ - "You have the right to die!" + "Masz prawo umrzeć!" ], "kg134": [ - "Lock and load!" + "Przygotować broń!" ], "kg135": [ "Otworzyć ogień!" @@ -5007,7 +5011,7 @@ "Flankuj ich!" ], "kg141": [ - "Move in!" + "Wchodzić!" ], "kg142": [ "Zdejmij ich!" @@ -5019,37 +5023,37 @@ "Aresztować go!" ], "kg145": [ - "Shoot 'em, shoot 'em!" + "Zastrzel ich, zastrzel ich!" ], "kg146": [ - "Die, outlaw!" + "Giń, wyrzutku!" ], "kg147": [ - "You're history!" + "Jesteś historią!" ], "kg148": [ "Żryj to!" ], "kg149": [ - "Get some!" + "Weź to!" ], "kg150": [ "Ognia, ognia!" ], "kg151": [ - "Here's one for the Guard!" + "A to punkt dla Strażnika!" ], "kg152": [ - "Give it up, outlaw!" + "Odpuść sobie, wyrzutku!" ], "kg153": [ - "Here's some pain!" + "Oto odrobina bólu!" ], "kg154": [ "Czas zemsty!" ], "kg155": [ - "Shoulda given up!" + "Powinieneś był się poddać!" ], "kg156": [ "Potrzebuję wsparcia ogniowego!" @@ -5067,34 +5071,34 @@ "Jesteś aresztowany!" ], "kg161": [ - "Riot in progress!" + "Trwają zamieszki!" ], "kg162": [ - "Send in the troops!" + "Wysłać żołnierzy!" ], "kg163": [ - "Give it up!" + "Odpuść sobie!" ], "kg164": [ - "Make 'em pay!" + "Niech zapłacą!" ], "kg165": [ - "Tag 'em and bag 'em!" + "Oznacz je i spakuj!" ], "kg165a": [ - "Tag 'em and bag 'em!" + "Oznacz je i spakuj!" ], "kg165b": [ - "Tag 'em and bag 'em!" + "Oznacz je i spakuj!" ], "kg166": [ - "Another notch for my gun." + "Kolejne nacięcie dla mojej broni." ], "kg166a": [ - "Another notch for my gun." + "Kolejne nacięcie dla mojej broni." ], "kg166b": [ - "Another notch for my gun." + "Kolejne nacięcie dla mojej broni." ], "kg167": [ "To było łatwe!" @@ -5115,73 +5119,73 @@ "Podejrzany zneutralizowany." ], "kg169": [ - "Didn't even work up a sweat." + "Nawet się nie spociłem." ], "kg169a": [ - "Didn't even work up a sweat." + "Nawet się nie spociłem." ], "kg169b": [ - "Didn't even work up a sweat." + "Nawet się nie spociłem." ], "kg170": [ - "Take him in for... questioning, hehehe..." + "Zabierz go na... przesłuchanie, hehehe..." ], "kg170a": [ - "Take him in for... questioning, hehehe..." + "Zabierz go na... przesłuchanie, hehehe..." ], "kg170b": [ - "Take him in for... questioning, hehehe..." + "Zabierz go na... przesłuchanie, hehehe..." ], "kg171": [ - "Another one bites the dust." + "Kolejny gryzie kurz." ], "kg171a": [ - "Another one bites the dust." + "Kolejny gryzie kurz." ], "kg171b": [ - "Another one bites the dust." + "Kolejny gryzie kurz." ], "kg172": [ - "That must have hurt." + "To musiało zaboleć." ], "kg172a": [ - "That must have hurt." + "To musiało zaboleć." ], "kg172b": [ - "That must have hurt." + "To musiało zaboleć." ], "kg173": [ - "There's plenty more where that came from." + "Tam, skąd to się wzięło, jest o wiele więcej." ], "kg173a": [ - "There's plenty more where that came from." + "Tam, skąd to się wzięło, jest o wiele więcej." ], "kg173b": [ - "There's plenty more where that came from." + "Tam, skąd to się wzięło, jest o wiele więcej." ], "kg174": [ - "Citizen scum." + "Szumowiny obywatelskie." ], "kg174a": [ - "Citizen scum." + "Szumowiny obywatelskie." ], "kg174b": [ - "Citizen scum." + "Szumowiny obywatelskie." ], "kg175": [ - "Don't fight the law, son." + "Nie walcz z prawem, synu." ], "kg175a": [ - "Don't fight the law, son." + "Nie walcz z prawem, synu." ], "kg175b": [ - "Don't fight the law, son." + "Nie walcz z prawem, synu." ], "kg176": [ - "You are under arrest!" + "Jesteś aresztowany!" ], "kg177": [ - "Get moving!" + "Naprzód!" ], "kg178a": [ "On zniknął!" @@ -5247,13 +5251,13 @@ "Nie mam wiary w nikogo." ], "kg186": [ - "Seen that new JX-7 racer? Sweet ride." + "Widziałeś tę nową wyścigówkę JX-7? Ładna fura." ], "kg186a": [ - "You seen that new JX-7 racer? Sweet ride." + "Czy widziałeś tę nową wyścigówkę JX-7? Ładna fura." ], "kg186b": [ - "Seen that new JX-7 racer? It's a sweet ride." + "Widziałeś tę nową wyścigówkę JX-7? To jest ładna fura." ], "kg187": [ "Widziałeś coś?" @@ -5274,22 +5278,22 @@ "Nah." ], "kg189": [ - "Keep your eyes peeled." + "Miejcie oczy szeroko otwarte." ], "kg189a": [ - "Keep your eyes peeled." + "Miejcie oczy szeroko otwarte." ], "kg189b": [ - "Keep your eyes peeled." + "Miejcie oczy szeroko otwarte." ], "kg190": [ - "I just got a radio alert, stay frosty." + "Właśnie dostałem ostrzeżenie przez radio, zachować czujność." ], "kg190a": [ - "I just got a radio alert, stay frosty." + "Właśnie dostałem ostrzeżenie przez radio, zachować czujność." ], "kg190b": [ - "I just got a radio alert, stay frosty." + "Właśnie dostałem ostrzeżenie przez radio, zachować czujność." ], "kg191": [ "Nigdy nie ufaj cywilowi." @@ -5319,22 +5323,22 @@ "Niech żyje KG!" ], "kg194": [ - "We ain't had a food riot since we brought in them tanks." + "Nie mieliśmy żadnych buntów o żywność, odkąd wprowadziliśmy czołgi." ], "kg194a": [ - "We ain't had a food riot since we brought in them tanks." + "Nie mieliśmy żadnych buntów o żywność, odkąd wprowadziliśmy czołgi." ], "kg194b": [ - "We ain't had a food riot since we brought in them tanks." + "Nie mieliśmy żadnych buntów o żywność, odkąd wprowadziliśmy czołgi." ], "kg195": [ - "I'm bored, I want to crunch heads." + "Znudzony jestem, Chce zmiażdżyć jakieś łby." ], "kg195a": [ - "I'm bored, I want to crunch heads." + "Znudzony jestem, Chce zmiażdżyć jakieś łby." ], "kg195b": [ - "I'm bored, I want to crunch heads." + "Znudzony jestem, Chce zmiażdżyć jakieś łby." ], "kg196": [ "Chce skopać komuś tyłek." @@ -5346,10 +5350,10 @@ "Chce skopać komuś tyłek." ], "kg197": [ - "Did you hear the Underground got our ammo at HQ?" + "Słyszałeś, że Podziemie dostało się do naszej amunicji z Kwatery głównej?" ], "kg197a": [ - "Did you hear the Underground got to", + "Słyszałeś, że Podziemie dostało się do", "naszej amunicji w kwaterze głównej?" ], "kg197b": [ @@ -5375,34 +5379,34 @@ "Zwierzęta!" ], "kg200": [ - "I hear the Shadow's been dead for years." + "Słyszałem, że Cień był martwy od lat." ], "kg200a": [ - "I hear the Shadow's been dead for years." + "Słyszałem, że Cień był martwy od lat." ], "kg200b": [ - "I hear the Shadow's been dead for years." + "Słyszałem, że Cień był martwy od lat." ], "kg201": [ - "Maybe, but the rest of them Underground scum", - "are still scurrying about." + "Może, ale reszta tych Podziemnych ścierw", + "wciąż się tu kręci." ], "kg201a": [ - "Maybe, but the rest of them Underground scum", - "are still scurrying about." + "Może, ale reszta tych Podziemnych ścierw", + "wciąż się tu kręci." ], "kg201b": [ - "Maybe, but the rest of them Underground scum", - "are still scurrying about." + "Może, ale reszta tych Podziemnych ścierw", + "wciąż się tu kręci." ], "kg202": [ - "Can I shoot someone now?" + "Czy mogę teraz kogoś zastrzelić?" ], "kg202a": [ - "Can I shoot someone now?" + "Czy mogę teraz kogoś zastrzelić?" ], "kg202b": [ - "Can I shoot someone now?" + "Czy mogę teraz kogoś zastrzelić?" ], "kg203": [ "Podoba mi się nowy pancerz." @@ -5423,31 +5427,31 @@ "Ta, mi też. Wygodniejszy w kroczu." ], "kg205": [ - "If something interesting doesn't happen soon,", - "I'm going to start shooting you." + "Jeśli wkrótce nie wydarzy się coś ciekawego,", + "Zacznę do ciebie strzelać." ], "kg205a": [ - "Next time, can I kill a civvy?" + "Czy następnym razem mogę zabić cywila?" ], "kg205b": [ - "Next time, can I kill a civvy?" + "Czy następnym razem mogę zabić cywila?" ], "kg206a": [ - "If something interesting doesn't happen soon,", - "I'm gonna shoot you." + "Jeśli wkrótce nie wydarzy się coś ciekawego,", + "Zastrzelę cię." ], "kg206b": [ - "If something interesting doesn't happen soon,", - "I'm gonna start shooting you." + "Jeśli wkrótce nie wydarzy się coś ciekawego,", + "Zacznę do ciebie strzelać." ], "kg207": [ - "Did you collect your bribes this week?" + "Czy odbierałeś łapówki w tym tygodniu?" ], "kg207a": [ - "You collect your bribes this week?" + "Odbierałeś łapówki w tym tygodniu?" ], "kg207b": [ - "You collect your bribes this week?" + "Odbierałeś łapówki w tym tygodniu?" ], "kg208": [ "Shhh..." @@ -5504,22 +5508,22 @@ "Hehe, ty biedaku. Którego komandora wkurzyłeś?" ], "kg214": [ - "I say death to the Underground." + "Mówię śmierć Podziemiu." ], "kg214a": [ - "I say death to the Underground." + "Mówię śmierć Podziemiu." ], "kg214b": [ - "I say death to the Underground." + "Mówię śmierć Podziemiu." ], "kg215": [ - "I wanna so kill that Shadow guy." + "Tak bardzo chcę zabić tego Cienia." ], "kg215a": [ - "I want to kill that Shadow guy!" + "Chcę zabić tego Cienia!" ], "kg215b": [ - "I want to kill that Shadow guy!" + "Chcę zabić tego Cienia!" ], "kg216": [ "I nie zapomnij o tym zdrajcy Tornie." @@ -5531,13 +5535,13 @@ "Nie zapomnij o tym zdrajcy Tornie." ], "kg217": [ - "Death's too good for him." + "Śmierć jest dla niego za dobra." ], "kg217a": [ - "Death's too good for him." + "Śmierć jest dla niego za dobra." ], "kg217b": [ - "Death's too good for him." + "Śmierć jest dla niego za dobra." ], "kg218": [ "Dlaczego my szukamy jakiegoś dzieciaka?" @@ -5585,13 +5589,13 @@ "Postawiłem duży zakład na następnych wyścigach miejskich." ], "kg223": [ - "Erol's my boy. He always wins." + "Erol to mój pewniak. On zawsze wygrywa." ], "kg223a": [ - "Erol's my boy. He always wins." + "Erol to mój pewniak. On zawsze wygrywa." ], "kg223b": [ - "Erol's my boy. He always wins." + "Erol to mój pewniak. On zawsze wygrywa." ], "kg224": [ "Czy idziesz tym razem na wyścigi miejskie ?" @@ -5600,7 +5604,7 @@ "Czy idziesz tym razem na wyścigi miejskie ?" ], "kg224b": [ - "You going to the city races this time?" + "Idziesz tym razem na wyścigi miejskie?" ], "kg225": [ "Będę tam." @@ -5612,40 +5616,40 @@ "Będę tam." ], "kg226": [ - "There've been some serious guard casualties this week." + "W tym tygodniu doszło do kilku poważnych strat wśród strażników." ], "kg226a": [ - "There've been some serious guard casualties this week." + "W tym tygodniu doszło do kilku poważnych strat wśród strażników." ], "kg226b": [ - "There've been some serious guard casualties this week." + "W tym tygodniu doszło do kilku poważnych strat wśród strażników." ], "kg227": [ - "Yeah, some rebel fighter is stirring up the pot good." + "No, paru bojowników rebelii naprawdę sprawia kłopot." ], "kg227a": [ - "Yeah, some rebel fighter is stirring the pot good." + "No, paru bojowników rebelii naprawdę sprawia kłopot." ], "kg227b": [ - "Some rebel fighter is stirring the pot good." + "Paru bojowników rebelii naprawdę sprawia kłopot." ], "kg228": [ - "I'd love to be the one to take him out." + "Chciałbym być tym, który go załatwi." ], "kg228a": [ - "I'd love to be the one to take him out." + "Chciałbym być tym, który go załatwi." ], "kg228b": [ - "Oh I'd love to be the one to take him out." + "Oh Chciałbym być tym, który go załatwi." ], "kg229": [ - "Let's get drinks later." + "Chodźmy po drinki później." ], "kg229a": [ - "Let's get drinks later." + "Chodźmy po drinki później." ], "kg229b": [ - "Let's get drinks later." + "Chodźmy po drinki później." ], "kg230": [ "Mam złe przeczucia co do tej wojny." @@ -5657,23 +5661,23 @@ "Mam złe przeczucia co do tej wojny." ], "kg231": [ - "I hear there are more Metal Head attacks", - "than HQ's admitting." + "Słyszałem, że jest więcej ataków Metalowych Łbów", + "niż Centrala przyznaje ." ], "kg231a": [ - "I hear there are more Metal Head attacks", - "than HQ's admitting." + "Słyszałem, że jest więcej ataków Metalowych Łbów", + "niż Centrala przyznaje ." ], "kg231b": [ - "Yeah, I hear there are more Metal Head attacks", - "than HQ's admitting." + "Tak, Słyszałem, że jest więcej ataków Metalowych Łbów", + "niż Centrala przyznaje ." ], "kg232": [ - "The reports I've seen aren't good.", - "I think the city's in trouble." + "Raporty, które widziałem, nie są dobre.", + "Myślę, że miasto ma kłopoty." ], "kg232a": [ - "The reports I've seen aren't good.", + "Raporty, które widziałem, nie są dobre.", "Myślę, że miasto ma kłopoty." ], "kg232b": [ @@ -5681,34 +5685,34 @@ "Myślę, że miasto ma kłopoty." ], "kg233": [ - "I'm worried about this new guy", - "fighting for the Underground." + "Martwię się o tego nowego kolesia", + "walczącego dla Podziemia." ], "kg233a": [ - "I'm worried about this new guy", - "fighting for the Underground." + "Martwię się o tego nowego kolesia", + "walczącego dla Podziemia." ], "kg233b": [ - "I'm worried about this new guy fighting for the Underground.", - "fighting for the Underground." + "I'm worried about this new guy", + "walczącego dla Podziemia." ], "kg234": [ - "Yeah, they say he can change into some kind of... monster." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ - "Yeah, they say he can change into some kind of monster." + "Tak, Mówią, że On może zmienić się w jakiegoś potwora." ], "kg234b": [ - "They say he can change into some kind of monster." + "Mówią, że On może zmienić się w jakiegoś potwora." ], "kg235": [ - "Don't worry, his head'll be on the tower wall soon enough." + "Nie martw się, jego głowa wkrótce będzie na ścianie wieży." ], "kg235a": [ - "Don't worry, his head'll be on the tower wall soon enough." + "Nie martw się, jego głowa wkrótce będzie na ścianie wieży." ], "kg235b": [ - "Don't worry, his head'll be on the tower wall soon enough." + "Nie martw się, jego głowa wkrótce będzie na ścianie wieży." ], "kg236": [ "Hehehe." @@ -5738,40 +5742,40 @@ "Hehehe..." ], "kg241a": [ - "Suspect in known Underground vehicle!" + "Podejrzany w znanym pojeździe Podziemia!" ], "kg242a": [ - "He's got a cargo, move in!" + "On ma ładunek, Wchodzić!" ], "kg243a": [ - "Stop that vehicle!" + "Zatrzymać ten pojazd!" ], "kg244a": [ - "You're under arrest, pull over!" + "Jesteś aresztowany, zatrzymaj się!" ], "kg245a": [ - "Surrender the vehicle!" + "Opuść pojazd!" ], "kg246a": [ - "We are in pursuit!" + "Jesteśmy w pościgu!" ], "kg247a": [ - "He's got a package!" + "On ma paczkę!" ], "kg248a": [ - "Suspect has suspicious cargo!" + "Podejrzany ma podejrzany ładunek!" ], "kg249a": [ - "We think it's an illegal shipment." + "Uważamy, że to jest nielegalna przesyłka." ], "kg250a": [ - "All units close in on vehicle!" + "Wszystkie jednostki mają się zbliżyć się do pojazdu!" ], "kg251a": [ - "Suspect moving at high speed!" + "Podejrzany porusza się z dużą prędkością!" ], "kg252a": [ - "We can't keep up!" + "Nie damy rady nadążyć!" ], "kg253a": [ "On jest w porcie!" @@ -5780,49 +5784,49 @@ "On się uciekł!" ], "kg255a": [ - "Suspect has taken out pursuit!" + "Ruszamy za podejrzanym w pościg!" ], "kg256a": [ - "Vehicle destroyed, we got him!" + "Pojazd zniszczony, mamy go!" ], "kg257a": [ - "Nice work boys, he's down." + "Dobra robota chłopaki, padł." ], "kg258a": [ "Świetny pościg." ], "kg259a": [ - "Guard transport under attack, requesting support!" + "Transport Straży jest atakowany, proszę o wsparcie!" ], "kg260a": [ - "We're takin' damage!" + "Odnosimy obrażenia!" ], "kg261a": [ - "He's after us!" + "Jest za nami!" ], "kg262a": [ - "He's trying to crash the transport!" + "Próbuje rozbić transport!" ], "kg263a": [ - "We've had a transport ambush, units respond!" + "Mamy zasadzkę na nasz transport, zgłoście się jednostki!" ], "kg264a": [ - "He's picking up a prisoner!" + "Zabiera więźnia!" ], "kg265a": [ - "We lost a Lurker prisoner." + "Straciliśmy więźnia Lurkera." ], "kg266a": [ - "He's got a Lurker prisoner with him!" + "Jest z nim więzień Lurker!" ], "kg267a": [ - "Take 'em all out!" + "Zdjąć ich wszystkich!" ], "kg268a": [ - "We think he's helping the Lurkers escape!" + "Myślimy, że pomaga Lurkerom uciec!" ], "kg269a": [ - "He's taken out two of our transports already!" + "Załatwił już dwa nasze transporty!" ], "kg270a": [ "On jest znowu sam." @@ -5831,55 +5835,55 @@ "Gdzie on kieruje?!" ], "kg272a": [ - "Terminate with extreme prejudice!" + "Skończ z ekstremalnymi uprzedzeniami!" ], "kg273a": [ - "He's attacking another transport!" + "Atakuje kolejny transport!" ], "kg274a": [ - "We're being chased, send in an escort!" + "Ścigają nas, wyślijcie eskortę!" ], "kg275a": [ - "We lost this passenger." + "Straciliśmy pasażera." ], "kg276a": [ "Tracimy go!" ], "kg277a": [ - "We got 'em!" + "Mamy ich!" ], "kg278a": [ - "We got 'em, teach ya to screw with the KG!" + "Mamy ich, nauczymy was, żeby nie zadzierać z KG!" ], "kg279a": [ - "Pull over, Lurker lover!" + "Zatrzymaj się, miłośniku Lurkerów!" ], "kg280a": [ - "There's a kid, check him out." + "Tam jest dzieciak, Sprawdźmy go." ], "kg281a": [ - "The Baron wants every kid in this city arrested." + "Baron chce aresztować wszystkie dzieci w mieście." ], "kg282a": [ - "Surrender the child!" + "Oddaj dzieciaka!" ], "kg283a": [ - "Give up the kid!" + "Daj dziecko!" ], "kg284a": [ - "If they won't surrender, kill them all!" + "Jeśli się nie poddadzą, zabijcie ich wszystkich!" ], "kg285a": [ - "Don't kill the kid." + "Nie zabijaj Dzieciaka." ], "kg286a": [ - "The Baron wants the kid alive!" + "Baron chce tego dzieciaka żywego!" ], "kg287a": [ - "Find the boy!" + "Znajdź chłopca!" ], "kg288a": [ - "That could be the kid the Baron wants." + "To może być dzieciak, którego chce Baron." ], "kg289a": [ "Za nimi!" @@ -5888,34 +5892,34 @@ "Nie ruszaj się, chłopcze!" ], "kg291a": [ - "Take out that mutt!" + "Pozbądź się tego kundla!" ], "kg292a": [ - "We should kill 'em all!" + "Powinniśmy zabić ich wszystkich!" ], "kg293a": [ - "They've taken a vehicle!" + "Zabrali pojazd!" ], "kg294a": [ - "If you get a clear shot, take it!" + "Jeśli masz szanse na czysty strzał, to strzelaj!" ], "kg295a": [ "Podejrzany ucieka pojazdem!" ], "kg296a": [ - "Suspect's vehicle moving through section seven." + "Pojazd podejrzanego przejeżdża przez sektor siódmy." ], "kg297a": [ - "We think the kid's with that Underground freak." + "Myślimy, że dzieciak jest z tym Dziwakiem Podziemia." ], "kg298a": [ - "Take 'em out, but keep the kid alive!" + "Pozbądźcie się ich, ale dzieciaka zostawcie przy życiu!" ], "kg299a": [ - "They're on foot again!" + "Znowu idą pieszo!" ], "kg300a": [ - "What is that thing?!" + "Co to jest?!" ], "kg301a": [ "Strzelajcie w to coś, strzelajcie!" @@ -5924,114 +5928,114 @@ "Co on robi?!" ], "kg303a": [ - "It's that monster!" + "To ten potwor!" ], "kg304a": [ - "The stories are true!" + "Historie są prawdziwe!" ], "kg305a": [ - "It's the dark monster!" + "To ten mroczny potwór!" ], "kg306a": [ - "It's him!" + "To on!" ], "kg307a": [ - "It's the dark eco freak!" + "To ten potwór mrocznego eco!" ], "kg308a": [ - "Kill it, kill it!" + "Zabij to, zabij to!" ], "kg309a": [ - "Suspect has transformed into", - "a creature of some kind." + "Podejrzany się przemienił w", + "w jakiegoś rodzaju stworzenie." ], "kg310a": [ - "Sure is ugly." + "Z pewnością jest paskudny." ], "kg311a": [ - "That's one ugly creature." + "Ależ to paskudne stworzenie." ], "kg312a": [ - "Look out!" + "Uważaj!" ], "kg313a": [ - "Fall back!" + "Wycofać się!" ], "kg314a": [ - "He's wasting everybody!" + "On nas wszystkich wykańcza!" ], "kg315a": [ "Nie możemy tego zabić!" ], "kg316a": [ - "Stand your ground men!" + "Utrzymać swoją pozycję panowie!" ], "kg317a": [ - "The Krimzon Guard do not run!" + "Straż Krimzonu nie ucieka!" ], "kg318a": [ - "Watch out for his claws!" + "Uważajcie na jego pazury!" ], "kg319a": [ - "Keep clear of his energy bolts!" + "Trzymajcie się z dala od jego pocisków energetycznych!" ], "kg320a": [ - "This is a raid, do not resist!" + "To jest nalot, nie stawiajcie oporu!" ], "kg321a": [ - "Move in!" + "Wchodzić!" ], "kg322a": [ - "By order of Baron Praxis,", - "everyone here is to be terminated!" + "Na rozkaz Barona Praxisa,", + "wszyscy tutaj mają zostać zabici!" ], "kg323a": [ - "Surrender and you will not suffer much." + "Poddajcie się, a nie będziecie zbyt wiele cierpieć." ], "kg324a": [ - "It's that Underground monster freak!" + "To ten potwór Podziemia!" ], "kg325a": [ - "Get him!" + "Dorwać go!" ], "kg326a": [ - "All units converge on Water Slums!" + "Wszystkie jednostki zebrać się w części Wodnej Slumsów!" ], "kg327a": [ - "We've got an Underground fighter!" + "Mamy wojownika z Podziemia!" ], "kg328a": [ - "Burn 'em down!" + "Zgnieść ich!" ], "kg329a": [ "Trzymać się razem!" ], "kg330a": [ - "We've got 'em cornered!" + "Udało nam się ich otoczyć!" ], "kg331a": [ - "Suspect cornered in section two." + "Podejrzany został zapędzony w kozi róg w sektorze drugim." ], "kg332a": [ - "There is no escape!" + "Nie ma ucieczki!" ], "kg333a": [ - "Resistance is futile!" + "Opór jest daremny!" ], "kg334a": [ - "Give up the artifact, eco freak!" + "Oddaj artefakt, dziwolągu eco!" ], "kg335a": [ - "We've cut 'em off!" + "Odcięliśmy ich!" ], "kg336a": [ "On jest uwięziony!" ], "kg337a": [ - "We got 'em!" + "Mamy ich!" ], "kg338a": [ - "We're taking heavy fire!" + "Bierzemy na siebie ciężki ostrzał!" ], "kg339a": [ "Mamy wiele strat, przyślijcie wsparcie!" @@ -6043,7 +6047,7 @@ "Utrzymujcie swoje pozycje!" ], "kg342a": [ - "Do not retreat!" + "Nie wycofywać się!" ], "kg343a": [ "Straciliśmy oddział Beta!" @@ -6052,127 +6056,127 @@ "Potrzebujemy więcej ludzi!" ], "kg345a": [ - "He's on the south path!" + "Jest na południowej drodze!" ], "kg346a": [ - "He's in the water!" + "On jest w wodzie!" ], "kg347a": [ - "He's near the east hut, all units converge!" + "Jest w pobliżu wschodniej chaty, wszystkie jednostki mają się zebrać!" ], "kg348a": [ - "We're gonna lose him!" + "Zaraz go zgubimy!" ], "kg349a": [ - "Intruder alert, sound the alarm!" + "Intruz alarm, ogłosić alarm!" ], "kg350a": [ - "The Fortress is under attack!" + "Forteca jest atakowana!" ], "kg351a": [ - "This is our house, boy!" + "To nasz dom, chłopcze!" ], "kg352a": [ - "You've got brass coming into our Fortress!" + "Macie jaja, że przyszliście do naszej Fortecy!" ], "kg353a": [ - "You won't get out of here alive!" + "Nie wyjdziecie stąd żywi!" ], "kg354a": [ - "Thanks for making this easy." + "Dzięki za ułatwienie tego." ], "kg355a": [ "Mamy wiele strat." ], "kg356a": [ - "He's getting in deep, stop him!" + "Wchodzi coraz głębiej, zatrzymać go!" ], "kg357a": [ - "Take this guy out, that's an order!" + "Załatwcie tego gościa, to jest rozkaz!" ], "kg358a": [ - "Send in the shock squad!" + "Wyślijcie oddział uderzeniowy!" ], "kg359a": [ - "Bring in the heavy firepower!" + "Przynieść ciężką artylerię!" ], "kg360a": [ - "Send in the shield guards!" + "Przyślijcie tarczowników!" ], "kg361a": [ - "I'm on him!" + "Jestem na nim!" ], "kg362a": [ - "Let me at 'em!" + "Puście mnie do nich!" ], "kg363a": [ - "I got 'em!" + "Mam ich!" ], "kg364a": [ "Wykończ go!" ], "kg365a": [ - "He's moving toward the ammo room!" + "Idzie w kierunku magazynu z amunicją!" ], "kg366a": [ - "Intercept the intruder before he gets in too far!" + "Przechwycić intruza, zanim zajdzie za daleko!" ], "kg367a": [ - "He's picking up a suspect." + "Zabiera podejrzanego." ], "kg368a": [ - "He's got an Underground agent with him!" + "Ma ze sobą agenta Podziemia!" ], "kg369a": [ - "Take 'em both out!" + "Zdejmij ich obu!" ], "kg370a": [ - "He's picked up another suspect." + "Złapał kolejnego podejrzanego." ], "kg371a": [ - "We lost the guy he dropped off!" + "Zgubiliśmy gościa, którego podrzucił!" ], "kg372a": [ "Ma pasażera." ], "kg373a": [ - "Driver is working with the Underground." + "Kierowca współpracuje z Podziemiem." ], "kg374a": [ - "Suspect vehicle taking damage, but still moving." + "Pojazd podejrzanego doznał uszkodzeń, ale nadal się poruszał." ], "kg375a": [ - "We need to cut 'em off!" + "Musimy ich odciąć!" ], "kg376a": [ - "He's got another agent!" + "Ma kolejnego agenta!" ], "kg377a": [ - "Suspect driving erratically!" + "Podejrzany jeździ chaotycznie!" ], "kg378a": [ - "Suspect still evading!" + "Podejrzany nadal ucieka!" ], "kg379a": [ - "We got 'em this time!" + "Tym razem ich mamy!" ], "kg380a": [ "Pojazd podejrzanego zniszczony!" ], "kg381a": [ - "He's going for another vehicle!" + "Idzie do kolejnego pojazdu!" ], "kg382a": [ - "We took 'em out!" + "Pozbyliśmy się ich!" ], "kg383a": [ - "He's toast!" + "Już po nim!" ], "kg384a": [ - "Another win for the KG, good shooting, men." + "Kolejne zwycięstwo dla KG, dobrze strzelaliście, panowie." ], "kg385a": [ - "Suspect has evaded capture." + "Podejrzany uniknął schwytania." ], "kg386a": [ "Ough!" @@ -6310,37 +6314,37 @@ "Otworzyć ogień!" ], "kgv003": [ - "Move in!" + "Wchodzić!" ], "kgv004": [ - "Take 'em out!" + "Zdjąć ich!" ], "kgv005": [ - "Take him down!" + "Zdejmijcie go!" ], "kgv006": [ - "Shoot 'em, shoot 'em!" + "Zastrzelić ich, zastrzelić ich!" ], "kgv007": [ - "Die, outlaw!" + "Giń, wyrzutku!" ], "kgv008": [ - "Eat this!" + "Żryj to!" ], "kgv009": [ "Ognia, ognia!" ], "kgv010": [ - "Give it up, outlaw!" + "Poddaj się, wyrzutku!" ], "kgv011": [ - "Seal off the area!" + "Odciąć teren!" ], "kgv012": [ "Wezwijcie posiłki!" ], "kgv013": [ - "Riot in progress!" + "Trwają zamieszki!" ], "kgv014": [ "Wezwać wsparcie!" @@ -6352,22 +6356,22 @@ "Jesteś aresztowany!" ], "kgv017": [ - "Pull over!" + "Zjedź na bok!" ], "kgv018": [ "Zwolnij!" ], "kgv019": [ - "Move over!" + "Zrób miejsce!" ], "kgv020": [ - "Get out of the vehicle!" + "Wyjdź z pojazdu!" ], "kgv021": [ - "Call in more Hellcats!" + "Wezwać więcej Hellcatów!" ], "kgv022": [ - "Requesting backup!" + "Prosimy o wsparcie!" ], "kgv023": [ "Szybki pościg w sektorze czwartym!" @@ -6379,116 +6383,116 @@ "Podejrzany ucieka do piątego sektora!" ], "kor001": [ - "I am so proud of you Jak, and you too, Daxter!", - "Together you have done real damage to the Baron.", + "Jestem z ciebie taki dumny Jak, i z ciebie też, Daxter!", + "Razem wyrządziliście poważne szkody Baronowi.", "Możemy jeszcze wygrać tę wojnę!" ], "kor002": [ - "Excellent work, you are proving to be quite an asset.", - "Without eco, the Baron will soon topple,", - "and the city's future will be in our hands." + "Świetna robota, okazujecie się, być niezłym nabytkiem.", + "Bez eco, Baron wkrótce upadnie,", + "a przyszłość miasta będzie w naszych rękach." ], "kor004": [ - "Another blow to the Baron, my good friends!", - "Very soon, our fortunes will change!" + "Kolejny zadany cios Baronowi, moi dobrzy przyjaciele!", + "Już niedługo nasze losy się odmienią!" ], "krew001": [ - "Jak, this is Krew. I just talked to my racing client", - "and she told me you were pretty good with that JET-Board", - "of hers. My sources say a shipment of Krimzon Guard", - "listening equipment just arrived in the Port.", - "None of us, including the Underground, want those devices", - "up and running. It's not good for business.", - "Ride the JET-Board out into the Port", - "and destroy every Krimzon Guard crate you find.", - "There's sure to be a defense perimeter,", - "so watch out, 'ey?" + "Jak, tu mówi Krew. Właśnie rozmawiałem z moim klientem od spraw wyścigów", + "i powiedziała mi, że całkiem nieźle radzisz sobie z tą", + "jej Deską Odrzutową. Moje źródła podają, że do portu właśnie przybyła dostawa", + "sprzętu podsłuchowego Straży Krimzonu.", + "Nikt z nas, łącznie z Podziemie, nie chce, aby", + "te urządzenia działały. To nie jest dobre dla biznesu.", + "Wybierz się na Desce Odrzutowej do Portu", + "i zniszcz każdą skrzynie Straży Krimzonu, jaką znajdziesz.", + "Na pewno będzie tam obwód obronny,", + "więc uważaj, jasne?" ], "krew002": [ - "Excellent work, Jak. Even I am impressed.", - "I should keep unscrupulous Krimzon Guards", - "out of our business.", - "What's the world coming to when you can't buy off", - "a few guards with bribes?" + "Świetna robota, Jak. Nawet jestem pod wrażeniem.", + "Powinienem trzymać pozbawionych skrupułów Strażników Krimzonu", + "z dala od naszych spraw.", + "Do czego zmierza świat, kiedy nie można przekupić", + "kilku strażników łapówkami?" ], "krew003": [ - "Ooooh... the bedtime stories were true!", - "The fabled Heart of Mar was hidden inside that ugly statue", - "of the old boy.", - "Nothing fractured, nothing gained! That's my motto. Hahaha...", - "For your loyalty, you'll find an excellent gun upgrade", - "stashed in a crate in the Port." + "Ooooh... a więc historie były prawdziwe!", + "Legendarne Serce Mara było ukryte w tym brzydkim posągu", + "starca", + "Kto nie ryzykuje, ten nie wygrywa! To moje motto. Hahahaha...", + "W zamian za twoją lojalność znajdziesz świetne ulepszenie broni", + "schowane w skrzyni w Porcie." ], "krew004": [ - "That's one turret down. Keep looking!" + "Jedna wieżyczka mniej. Szukaj dalej!" ], "krew005": [ - "Two turrets. Good work so far!" + "Dwie wieżyczki. Jak na razie dobra robota!" ], "krew006": [ - "Three turrets gone. Nice! Keep it up!" + "Trzy wieżyczki padły. Ładnie! Tak trzymaj!" ], "krew007": [ - "Four turrets trashed. Haha... Lovely, boys! Go get 'em!" + "Cztery wieżyczki zniszczone. Haha... Cudownie, chłopcy! Idź, weź je!" ], "krew008": [ - "Five turrets down the drain! Keep going." + "Pięć wieżyczek poszło w błoto! Tak trzymajcie." ], "krew009": [ - "Six turrets out of commission.", - "Hah, I like the way you work." + "Już sześć wieżyczek nieczynnych.", + "Hah, podoba mi się sposób, w jaki pracujesz." ], "krew010": [ - "Brass work, boys! You destroyed all the turrets, eh?", - "Now, come back to the Hip Hog." + "Solidna robota, chłopaki! Zniszczyliście wszystkie wieżyczki, co nie?", + "a teraz, wracajmy do Hip Hog." ], "kwbf001": [ - "You know I can't play fair!", - "I have a secret weapon: my duplicity field!", - "Say hello to my little friends...", - "Ah, multiple me! Hahahaha... How delightful." + "Wiesz, że nie potrafię grać fair!", + "Mam tajną broń: moją armię klonów!", + "Przywitajcie się z moimi małymi przyjaciółmi...", + "Ach, wielokrotność mnie! Hahahaha... Jakie to rozkoszne." ], "kwbf002": [ - "Let me introduce you to my... \"crew.\"" + "Pozwól, że przedstawię ci moją... \"załogę\"" ], "kwbf003": [ - "Let's dance!" + "Zatańczmy!" ], "kwbf004": [ "Zginiesz!" ], "kwbf005": [ - "Here we come!" + "Nadchodzimy!" ], "kwbf006": [ - "My, don't my twins look stunning?" + "Kurczę, czyż moje bliźniaki nie wyglądają oszałamiająco?" ], "kwbf007": [ - "You can't stop us all!" + "Nie możesz zatrzymać nas wszystkich!" ], "kwbf008": [ - "Surprise! More of me than you can handle." + "Niespodzianka! Więcej mnie, niż jesteś w stanie poradzić." ], "kwbf009": [ - "I've a few good men to help me." + "Mam kilku dobrych ludzi, którzy mi pomogą." ], "kwbf010": [ - "Get him!" + "Dorwijcie go!" ], "kwbf011": [ - "UARGH! Try stopping me now!" + "UARGH! Spróbuj mnie teraz powstrzymać!" ], "kwbf012": [ - "You're getting lucky so far, 'ey?" + "Jak na razie masz szczęście, co nie?" ], "kwbf013": [ - "I grow weary of this. We end it now." + "Zaczynam być tym zmęczony. Zakończmy to teraz." ], "kwbf014": [ - "Hm-hm, I move pretty fast for a big man, 'ey?" + "Hm-hm, Poruszam się całkiem szybko jak na dużego człowieka, prawda?" ], "kwbf015": [ - "I float like a butterfly and sting like a wumpbee!" + "Latam jak motyl i żądlę jak wumpbee!" ], "kwbf016": [ "Urghh!" @@ -6515,306 +6519,306 @@ "Nie możesz wygrać, Jak!" ], "kwbf024": [ - "Here's some pain!" + "Oto odrobina bólu!" ], "kwbf025": [ "Nie!" ], "kwbf026": [ - "You're trying my patience!" + "Wystawiasz na próbę moją cierpliwość!" ], "kwbf027": [ - "Stand still!" + "Stójże w miejscu!" ], "kwbf028": [ - "Haha, how did that feel?" + "Haha, jakie to było uczucie?" ], "kwbf029": [ - "You should have walked away when you had a chance." + "Powinniście byli odejść, kiedy mieliście szansę." ], "kwbf030": [ - "Pop this!" + "Przebij to!" ], "kwbf031": [ - "You can't stop the bomb, Jak!" + "Nie zatrzymasz bomby, Jak!" ], "kwbf032": [ - "Hahahaha, that felt good!" + "Hahahaha, to było dobre!" ], "kwbf033": [ - "I am the weapon master!" + "Jestem mistrzem broni!" ], "kwbf034": [ - "Had enough?" + "Masz dosyć?" ], "kwbf035": [ - "Here we come!" + "Nadchodzimy!" ], "kwbf036": [ - "Dance for me, Jak!" + "Zatańcz dla mnie, Jak!" ], "kwbf037": [ - "You can't get us all!" + "Wszystkich nas nie dopadniesz!" ], "kwbf038": [ - "Tag! You're it." + "Berek! Teraz ty." ], "kwbf039": [ - "Phew. This is a bit of a workout..." + "Uff. To taka mała rozgrzewka..." ], "kwbf040": [ - "Which is the real me, Jak?" + "Który to prawdziwy ja, Jak?" ], "kwbf041": [ - "Finally... I get to put you in your place!" + "Wreszcie... Postawie was, gdzie wasze miejsce!" ], "kwbf042": [ - "Arghh! You little...!" + "Arghh! Ty mały...!" ], "ora006": [ - "Bring me 200 more Metal Head Skull Gems", - "and I will show you another Dark Power." + "Przynieś mi 200 kolejnych czaszkowych klejnotów Metalowych Łbów", + "a pokaże ci kolejną Mroczną moc." ], "ora007": [ - "Bring me 200 more Skull Gems", - "and another power will be yours to control." + "Przynieś mi jeszcze 200 klejnotów czaszkowych", + "a kolejna moc będzie pod twoją kontrolą." ], "ora008": [ - "Bring me more Skull Gems to receive control", - "over a Dark Power." + "Przynieś mi więcej Klejnotów Czaszkowych, aby przejąć kontrolę", + "nad Mroczną Mocą." ], "ora009": [ - "You do not have enough Skull Gems.", - "Come back when you have collected more." + "Nie masz wystarczającej ilości Klejnotów Czaszkowych.", + "Wróć, gdy uzbierasz więcej." ], "ora010": [ - "I need more Skull Gems." + "Potrzebuje więcej Klejnotów Czaszkowych." ], "ora011": [ - "Trust not your reliance on weapons." + "Nie ufaj swojemu poleganiu na broni." ], "ora012": [ - "Use only your body and brain for this challenge." + "Do tego wyzwania używaj wyłącznie swojego ciała i mózgu." ], "ora013": [ - "Weapons are for the weak." + "Broń jest dla słabych." ], "ora014": [ - "You must not use weapons in this challenge." + "W tym wyzwaniu nie wolno używać broni." ], "pek001": [ - "Groark! I can't believe you actually did this thing!", - "Onin says she will search timelines for answers", - "about these sacred relics. I will find you then." + "Groark! Nie mogę uwierzyć, że naprawdę to zrobiłeś!", + "Onin mówi, że będzie przeszukiwać inne Linie czasowe w poszukiwaniu odpowiedzi", + "na temat tych świętych relikwii Znajdę cię wtedy." ], "pek002": [ - "Groark! Whoa... well I'll be a moncaw's uncle, the Light Tower", - "actually does exist! The beam of light is shining somewhere", - "in the city! The Tomb of Mar was right under our noses", - "all along. And thanks to me, you found it!" + "Groark! Łoo... cóż, będę wujkiem małpy, Wieża Światła", + "naprawdę istnieje! Promień światła świeci gdzieś", + "w mieście! Grobowiec Mar był pod naszymi nosami", + "przez ten cały czas. I dzięki mnie go znalazłeś!" ], "pek003": [ - "Wow! As I live and molt, one step closer to the Tomb.", - "I never thought we'd get this far!" + "Łoo! Jak ja żyję i linieję, jesteśmy o krok bliżej Grobu.", + "Nigdy nie myślałem, że zajdziemy tak daleko!" ], "pek010": [ - "This is Onin's magic bowl.", - "Onin will make symbols appear from her bowl.", - "When the symbols appear, you must pop them before they", - "reach the ground. You must pop them quickly, pop only", - "the symbols you see. If you try to pop a symbol that is", - "not there, Onin will give you a penalty! Miss any symbols", - "and you will penalized! Each round will get faster.", - "Let's see how far you get.", - "You must get a high enough score to win." + "To jest magiczna miska Onina.", + "Onin sprawi, że z jej miski pojawią się symbole.", + "Kiedy pojawią się symbole, musisz je rozbić, zanim", + "dotrą do ziemi. Musisz je szybko przebić, tylko przebijaj te", + "symbole, które widzisz. Jeśli spróbujesz przebić symbol, którego", + "tam nie ma, Onin da ci karę! Pomiń jakiekolwiek symbole,", + "a zostaniesz ukarany! Każda runda będzie coraz szybsza.", + "Zobaczmy, jak daleko zajdziesz.", + "Musisz uzyskać wystarczająco duży wynik, aby wygrać." ], "pek011": [ - "You are doing very well!" + "Radzisz sobie bardzo dobrze!" ], "pek012": [ - "Huh, not bad." + "Huh, nieźle." ], "pek013": [ - "Keep going, you can do it!" + "Tak trzymaj, dasz radę!" ], "pek014": [ - "Pop any more than the true number of each symbol,", - "and you will be penalized! Groark!" + "Przebij więcej niż faktyczna liczba każdego symbolu,", + "a zostaniesz ukarany! Groark!" ], "pek015": [ "Gotowy? Start!" ], "pek016": [ - "That symbol wasn't there, penalty!" + "Tego symbolu tam nie było, kara!" ], "pek017": [ - "Hah, Onin got you! Pop only symbols that you see." + "Ha, Onin cię przyłapał! Przebijaj tylko symbole, które widzisz." ], "pek018": [ - "Here comes another round!", - "Give him another burst, Onin girl!" + "Zaczyna się kolejna runda!", + "Daj mu kolejną serię, Dziewczyno!" ], "pek019": [ - "She got you again! What is your problem?" + "Znowu cię ma! Jaki masz problem?" ], "pek020": [ - "I can't believe you've made it this far!" + "Nie mogę uwierzyć, że dotarłeś tak daleko!" ], "pek021": [ - "Quickly! You are missing symbols!" + "Szybko! Gubisz symbole!" ], "pek022": [ - "You missed some!" + "Przegapiłeś niektóre !" ], "pek023": [ "Szybciej! Szybciej!" ], "pek024": [ - "Give it to him, Onin! More, Onin, more!", - "You go, girl, shake what your momma gave you!" + "Daj mu to, Onin! Więcej, Onin, więcej!", + "Dajesz dziewczyno, potrząśnij tym co dała ci mama!" ], "pek025": [ - "Rockin' in the club." + "Zabawa się zaczyna." ], "pek026": [ - "He can't do that many!" + "Nie możliwe, żeby zrobił aż tyle!" ], "pek027": [ - "What? He's still going?" + "Co? Ciągle daje rade?" ], "pek028": [ - "Let's see if he can handle it." + "Zobaczmy, czy on może sobie z tym poradzić." ], "pek029": [ - "Go! Come on!" + "Dalej! Dawaj!" ], "pek030": [ - "Okay, so you're good." + "Okej, więc jesteś dobry." ], "pek031": [ "Wow! Nieźle." ], "pek032": [ - "Well, I laid an egg." + "No cóż, Prawie zniosłem jajo." ], "pek033": [ - "Amazing! You actually won!", - "I am without words, and that is rare." + "Niesamowite! Rzeczywiście wygrałeś!", + "Brak mi słów, a to rzadkość." ], "pek034": [ - "You got enough points, congratulations!" + "Masz wystarczającą liczbę punktów, gratulacje!" ], "pek035": [ - "Last penalty! You lose, loser." + "Ostatnia kara! Przegrałeś, przegrywie." ], "pek036": [ - "You lost! Why am I not surprised?" + "Przegrałeś! Dlaczego mnie to nie dziwi?" ], "pek037": [ - "You lose! Would you like to try again?" + "Przegrałeś! Czy chcesz spróbować ponownie?" ], "pek038": [ - "Ahh, you laid an egg. Too bad, so sad." + "Ahh, złożyłeś jajko. Przykre, ale prawdziwe." ], "pek039": [ - "Oooh, so close... not! Hehehe..." + "Oooch, tak blisko... a jednak nie! Hehehe..." ], "pek040": [ - "You made a valiant effort, but you suck!" + "Dzielnie się postarałeś, ale jesteś do niczego!" ], "pek041": [ - "Game over, finito, done, se acabó!" + "Koniec gry, finito, stało, se acabó!" ], "prop002": [ - "As you all know, I was wounded during our last", - "glorious assault against the Metal Head Nest", - "many years ago. I have sacrificed everything", - "for this city and I demand only the same in return!", - "Loyalty will be rewarded,", - "death will await all others." + "Jak wszyscy wiecie, zostałem ranny podczas naszego ostatniego", + "chwalebnego ataku na Gniazdo Metalowych łbów", + "wiele lat temu. Poświęciłem wszystko", + "dla tego miasta i tego samego żądam w zamian!", + "Lojalność zostanie nagrodzona,", + "na pozostałych czeka śmierć." ], "prop003": [ "Mroczne Eco wewnątrz Ciebie ostatecznie cię zabije, Jak.", - "Its destructive effects cannot be stopped.", - "Once you are in its chaotic grip, it will not let you go", - "until you slide into insanity. Turn yourself in, and I will", - "kill you mercifully and painlessly,", - "it is your only way out." + "Nie da się zatrzymać jego destrukcyjnych skutków.", + "Kiedy już znajdziesz się w jego chaotycznym uścisku, nie wypuści cię", + "dopóki nie popadniesz w szaleństwo. Oddaj się, a ja", + "zabiję cię miłosiernie i bezboleśnie,", + "To twoje jedyne wyjście." ], "prop004": [ - "Don't try to make a fool out of me, Jak.", - "Just because I haven't killed you yet doesn't", - "mean I'm not onto you. The citizens of this city", - "worship me because I offer them safety.", - "All I ask in return is for their lives.", - "I'll find you, and when I do, you'll wish", - "you died in prison." + "Nie próbuj zrobić ze mnie głupca, Jak.", + "Tylko dlatego, że cię jeszcze nie zabiłem, nie", + "oznacza, ​​że mam cię na celowniku. Obywatele tego miasta", + "czczą mnie, bo zapewniam im bezpieczeństwo.", + "Jedyne, o co proszę w zamian, to o ich życie.", + "Znajdę cię, a kiedy to zrobię, będziesz żałować,", + "że nie umarłeś w więzieniu." ], "prop005": [ - "Attention, my loyal citizens! We are looking for a", - "rebel fugitive who has caused the city considerable", - "damage of late. This man is armed and extremely", - "dangerous and can somehow change into a monstrous", - "creature. We have reports he is working with the", - "Metal Heads to subvert your city and your safety.", - "Report all sightings immediately!" + "Proszę o uwagę, moi lojalni obywatele! Poszukujemy", + "zbiegłego rebelianta, który ostatnio wyrządził miastu znaczne", + "szkody. Ten człowiek jest uzbrojony i niezwykle", + "niebezpieczny i może w jakiś sposób zmienić się w potwora.", + "Mamy raporty, że współpracuje z", + "Metalowymi Łbami, aby zniszczyć wasze miasto i wasze bezpieczeństwo.", + "Zgłaszajcie natychmiast wszystkie obserwacje!" ], "prop006": [ - "Brave citizens, today is the anniversary of the great", - "battle that ruined our city section we now call", - "Dead Town. Remember those who died", - "that day and how much we owe the Metal Heads", - "for their treachery! Remember how bravely I fought", - "to save those poor souls of the overrun section", - "and reflect on how grateful you should all be that the", - "Krimzon Guard keeps you safe each day." + "Dzielni obywatele, dziś przypada rocznica wielkiej", + "bitwy, która zrujnowała naszą część miasta, którą teraz nazywamy", + "Martwym Miastem. Pamiętajcie o tych, którzy zginęli", + "tamtego dnia i jak wiele są nam winni Metalowe Łby", + "za ich zdradę! Pamiętajcie, jak dzielnie walczyłem", + "o ocalenie tych biednych dusz z przepełnionej sekcji", + "i zastanówcie się, jak wszyscy powinniście być wdzięczni, że", + "Straż Krimzon każdego dnia zapewnia wam bezpieczeństwo." ], "prop007": [ - "This is your Baron. The reports of a Metal Head", - "invasion of the city are vastly overblown.", - "I assure you this is but a small incursion and we will", - "defeat it shortly. Stay in your homes, do not panic,", - "or you will be punished!" + "Tu wasz Baron. Doniesienia o inwazji Metalowych Łbów", + "na miasto są mocno przesadzone.", + "Zapewniam cię, że to tylko niewielki najazd i", + "wkrótce go pokonamy. Pozostańcie w domach, nie panikujcie,", + "albo zostaniecie ukarani!" ], "prop008": [ - "Attention citizens, this is your Baron speaking.", - "There have been several unauthorized uses of the", - "city's old gate locks. Fortunately, these breaches", - "have not resulted in contamination, but we all know", - "how deadly the Wasteland is. No one is allowed", - "outside the city without authorization, let it be", - "known that any violators will be caught", - "and executed." + "Uwaga obywatele, mówi wasz baron.", + "Doszło do kilku nieautoryzowanych przypadków użycia", + "starych zamków do bram miejskich. Na szczęście te naruszenia", + "nie spowodowały skażenia, ale wszyscy wiemy", + "jak zabójcze jest Pustkowie. Nikomu nie wolno", + "opuszczać miasta bez zezwolenia, należy", + "poinformować, każdy sprawca naruszenia zostanie złapany", + "i stracony." ], "prop009": [ - "Serve your city." + "Służ swojemu miastu." ], "prop010": [ - "Sacrifice for your city, and all will prosper!" + "Poświęć się dla swojego miasta, a wszystko będzie prosperować!" ], "prop011": [ - "You are safe, because I care." + "Jesteś bezpieczny, bo mi zależy." ], "prop012": [ - "All Metal Heads must die!" + "Wszystkie Metalowe Łby muszą zginąć!" ], "prop013": [ - "Work hard, and be grateful." + "Pracuj ciężko, i bądź wdzięczny." ], "prop014": [ - "Report all wrongdoers." + "Zgłaszajcie wszystkich winowajców." ], "prop015": [ "Pamiętajcie, nawet twoi przyjaciele mogą być wrogami." ], "prop016": [ - "Turn in all who subvert." + "Donieście na wszystkich tych, którzy chcą obalić władze." ], "prop017": [ "Siła jest naszą jedyną opcją!" ], "prop018": [ - "Obey and be happy." + "Bądź posłuszny i bądź szczęśliwy." ], "prop019": [ "Poświęcenie to coś, co powinieneś zrobić", @@ -6827,86 +6831,86 @@ "Pamiętajcie, nawet przyjaciele mogą być wrogami." ], "prop022": [ - "The city needs your sacrifice." + "Miasto potrzebuje waszego poświęcenia." ], "prop023": [ - "It is better inside the walls!" + "Lepiej jest wewnątrz murów!" ], "prop024": [ - "The law will show no mercy." + "Prawo nie okaże litości." ], "prop025": [ - "Justice is swift." + "Sprawiedliwość jest szybka." ], "prop026": [ - "The Underground movement is dead!" + "Ruch Podziemia jest martwy!" ], "prop027": [ - "Join the Krimzon Guard and your family", - "will be allowed to stay." + "Dołącz do Straży Krimzon a twoja rodzina", + "będzie mogła zostać." ], "prop028": [ - "One way: My way." + "Jeden sposób: Mój sposób." ], "prop029": [ - "To lead is to control." + "Przewodzić oznacza kontrolowanie." ], "prop030": [ - "Give up your freedom and I will protect you." + "Oddaj swoją wolność, a ja cię ochronię." ], "prop031": [ - "Have faith in me and the Promised Land is yours." + "Zaufajcie mi, a Ziemia Obiecana będzie Wasza." ], "prop032": [ - "Your city needs a strong leader, not a childish fool." + "Twoje miasto potrzebuje silnego przywódcy, a nie dziecinnego głupca." ], "prop033": [ - "Welcome not the unknown face." + "Nie witaj nieznanej twarzy." ], "prop034": [ - "Shun those who would defy me!" + "Strzeż się tych, którzy sprzeciwiają mi się!" ], "prop035": [ "Jestem twarzą Miasta Haven." ], "prop036": [ - "Without my strength, there would be no city." + "Bez mojej siły nie byłoby miasta." ], "prop037": [ - "Follow me to a safer future!" + "Podążaj za mną ku bezpieczniejszej przyszłości!" ], "prop038": [ - "You are safe inside the walls with me." + "Ze mną będziesz bezpieczny w obrębie murów." ], "prop039": [ "Sprzeciw się... i zgiń." ], "prop040": [ "Witaj w Mieście Haven!", - "All laws are enforced for your safety.", - "Obey me and you will not be punished." + "Wszystkie przepisy są egzekwowane dla Twojego bezpieczeństwa.", + "Bądź mi posłuszny, a nie zostaniesz ukarany." ], "prop041": [ - "The city is safe. I will not allow harm", - "to befall you, trust me." + "Miasto jest bezpieczne. Nie pozwolę, żeby", + "spotkała cię krzywda, zaufaj mi." ], "prop042": [ - "Rest assured, I will destroy the Metal Heads.", - "One way or another." + "Bądźcie pewni, zniszczę Metalowe Łby.", + "Tak czy inaczej." ], "prop043": [ - "To all citizens, this puny Underground revolt", - "will be dealt with by all aggressive means.", - "We will crush these arrogant upstarts, they will not", - "be allowed to threaten me or this city's order!" + "Do wszystkich obywateli, ta marna rewolta Podziemia", + "zostanie rozwiązana wszelkimi agresywnymi środkami.", + "Zmiażdżymy tych aroganckich nowicjuszy, nie pozwolimy", + "im grozić mnie ani porządkowi tego miasta!" ], "prop044": [ "Do wszystkich mieszkańców tego wspaniałego miasta, gdzieś jest potwór", - "among you, masquerading as a man!", + "wśród was udających mężczyzn!", "On jest niebezpieczny i musi zostać zniszczony!", - "I offer a reward of eco for his capture, or, if you", - "have a loved one in prison, I will exchange them for", - "this renegade. I promise." + "Oferuję nagrodę w postaci eco za jego schwytanie lub, jeśli masz", + "kogoś bliskiego w więzieniu, wymienię go na", + "tego renegata. Obiecuję." ], "prop045": [ "Do wszystkich, którzy mi się sprzeciwiają! Obserwuję was,", @@ -6931,90 +6935,93 @@ "Bo jak nie!" ], "prop048": [ - "As your Baron, I am instituting a \"no hoverboard\" rule", - "in the city! Young delinquents with nothing better", - "to do than float around and do tricks! Huh!", - "I'll put all violators into the Guard and teach them", - "some discipline. No skating, it's the law!" + "Jako wasz Baron, Ustanawiam zasadę „zakazu\" latania na deskach odrzutowych", + "na terenie miasta! Młodzi przestępcy niemający nic lepszego", + "do roboty niż latanie i robienie sztuczek! Huh!", + "Wszystkich sprawców włączę do Straży i nauczę ich", + "trochę dyscypliny. Zakaz jazdy na desce, takie jest prawo!" ], "prop049": [ - "I am disappointed with this city's lack of", - "committment and sacrifice. Work harder! Eat less!", - "Drink only when I tell you! Sleep is optional.", - "We are at war with an outside threat,", - "don't make me declare war on you as well!" + "Jestem rozczarowany z miasta i jego brakiem", + "commitment and sacrifice. Work harder! Eat less!", + "Pij tylko wtedy, gdy ci powiem! Sen jest opcjonalny.", + "Jesteśmy w stanie wojny z zagrożeniem z zewnątrz,", + "nie zmuszaj mnie, żebym i tobie wypowiedziała wojnę!" ], "prop050": [ - "Greetings, people of this wonderful utopia. This year's", - "championship race will begin shortly. All citizens", - "not under house arrest are invited to come down to", - "the Stadium and watch your favorite son Erol", - "once again show how the Krimzon Guard are the elite", - "warriors of this city. Bring the whole family! The first", - "one thousand children will get a mandatory", - "Krimzon Guard recruitment package and be", - "\"asked\" to join the Guard for life, what a treat!" + "Witam, ludzi tej cudownej utopii. Tegoroczne", + "wyścig o mistrzostwo niedługo się rozpocznie. Wszyscy obywatele", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", + "po raz kolejny pokazuje, że Straż Krimzon to elitarni", + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ - "This is your Baron, I am still in control!", - "And I assure you, there's absolutely no Metal Heads", - "in the city. Anyone who contradicts this fact...", - "will be shot! The current situation is merely", - "an elaborate propaganda hoax, perpetrated by", - "the outlawed Underground militia trying to", - "subvert our laws and discredit those who protect you", - "while you sleep! Pay no attention to this foolish hoax,", - "there are no Metal Heads within 100 miles of this city!" + "Tu wasz Baron, Nadal mam kontrolę!", + "I zapewniam cię, że nie ma absolutnie żadnych Metalowych Łbów", + "w mieście. Kto zaprzecza temu faktowi...", + "zostanie zastrzelony! Obecna sytuacja jest po prostu", + "wyszukanym oszustwem propagandowym, popełnionym przez", + "nielegalną bojówkę Podziemia, która próbowała", + "obalić nasze prawa i zdyskredytować tych, którzy cię chronią", + "podczas snu! Nie zwracaj uwagi na tę głupią mistyfikację,", + "w promieniu 160 km od tego miasta nie ma Metalowych Łbów!" ], "prop052": [ - "This is Baron Praxis. We have taken back the city", - "and the Metal Heads are now fleeing before us!", - "Victory is at hand! Continue to fight for the freedom", - "I may some day give you. Continue to defy these", - "enemies of my law and order...", - "and continue to die for me." + "Tu mówi Baron Praxis. Odzyskaliśmy miasto", + "a Metalowe Łby uciekają teraz przed nami!", + "Zwycięstwo jest na wyciągnięcie ręki! Walczcie dalej o wolność", + "Którą pewnego dnia wam dam. Kontynuujcie przeciwstawienie się tym", + "wrogom mojego prawa i porządku...", + "i nadal umierajcie za mnie." ], "prop053": [ - "Fear not the men in red. Sure, there are occasional", - "complaints about their over-aggressive policing,", - "wanton destruction of people's property during raids,", - "mass-arrests, misplaced loved ones and whatnot.", - "Hey, we're only human! Running a city can be", - "tougher than it looks, imagine how much worse", - "it would be if the Metal Heads were in charge!" + "Nie bójcie się ludzi w czerwieni. Jasne, zdarzają się okazjonalne", + "skargi dotyczące ich nadmiernie agresywnych działań policyjnych,", + "bezmyślnego niszczenia mienia ludzi podczas nalotów,", + "masowych aresztowań, zagubienia bliskich i tak dalej.", + "Hej, jesteśmy tylko ludźmi! Zarządzanie miastem może być", + "trudniejsze, niż się wydaje, wyobraź sobie, o ile gorsze", + "byłoby, gdyby rządzili Metalowe Łby!" ], "prop054": [ - "We've had a few incidents with our lower class labor", - "force lately. If your Lurker is acting up, call Krimzon", - "Animal Control. Is your Lurker in a tree? Stuck in a", - "sewer grate? Foaming at the mouth? Call", - "the friendly officers of the K.A.C. and they will deal", - "with your furry slave. with all the love and care it", - "deserves... then haul it away for reconditioning.", + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", "Remember, Lurkers can be dangerous!" ], "prop055": [ - "Please give generously to the Baron eco fund.", - "Your munificent donation wil be used for a variety", - "of humanitarian needs: bombs, guns, armor, genetic", - "alteration research, all in the name of preserving this", + "Prosimy o hojne datki eco dla Barona.", + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", "wonderful city of ours. Give often, give freely...", "or it will be taken from you!" ], "prop056": [ - "It can be so lonely at the top and looking down from", - "up here I can see that this dirty city is in desperate", - "need of revitalization. So, to that end, we", - "will be bulldozing many sections of the city in the", - "coming weeks! All complaints against this", - "construction initiative can be brought,", - "in-person, to the Fortress Prison where they will be", - "\"reviewed.\" Condemned city sections are to", - "be evacuated before razing begins.", - "Anyone still in their homes will be ignored." + "Na szczycie może być tak samotnie, a patrząc w dół", + "z góry, Widzę, że to brudne miasto jest w rozpaczliwej", + "potrzebie rewitalizacji. W tym celu", + "będziemy zburzać wiele części miasta w", + "nadchodzących tygodniach! Wszelkie skargi dotyczące tej", + "inicjatywy budowlanej można składać,", + "osobiście do Więzienia Twierdzy, gdzie zostaną", + "„rozpatrzone”. Części miasta przeznaczone do rozbiórki należy", + "ewakuować przed rozpoczęciem wyburzania.", + "Każdy, kto pozostanie w swoich domach, zostanie zignorowany." ], "prop057": [ - "The Metal Head attack will not succeed!", + "Atak Metalowych Łbów się nie powiedzie!", "Twój Baron podjął pewne środki", "aby zagwarantować, że metalowe łby NIGDY nie będą utrzymywać", "te miasto przez długi czas. Zapewniam was, że zdobędę zwycięstwo", @@ -7043,20 +7050,20 @@ "posprzątaj moją chatę, kiedy tam będziesz!" ], "sam002": [ - "This is Samos. Now that you boys are here", - "I want you to get up to my old hut. There is something there", - "that we need! Good luck, and watch our for Metal Heads." + "Tu Samos. Teraz kiedy tu jesteście, chłopcy", + "Chcę, żebyście poszli do mojej starej chaty. Jest tam coś", + "czego potrzebujemy! Powodzenia i uważajcie na Metalowych Łbów." ], "sam003": [ - "This is Samos, Jak. the Metal Heads must have taken", - "the giant gate ring to their Nest in the Wasteland.", - "If they're ever going to use that ring to open a rift back", - "to our old village, we need to get into the Nest and find it." + "Tu Samos, Jak, Metalowe Łby musiały zabrać", + "gigantyczny pierścień bramy do swojego Gniazda na Pustkowiach.", + "Jeśli kiedykolwiek zamierzają użyć tego pierścienia, żeby otworzyć szczelinę", + "prowadzącą do naszej starej wioski, musimy dostać się do Gniazda i go znaleźć." ], "sam004": [ - "You did well, Jak. Luckily, the Precursor Stone wasn't in that", - "bomb when it went off or none of us would be here", - "right now. Come back to the race garage", + "Dobrze się spisałeś, Jak. Na szczęście nie było Kamienia Prekursora w tej", + "bombie, kiedy to wybuchło, w przeciwnym razie nikogo z nas by tu nie było", + "teraz. Wracajmy do garażu wyścigowego", "tak szybko jak tylko możesz." ], "sam005": [ @@ -7064,18 +7071,18 @@ "Znajdź młodego Samosa i daj mu Nasionko Życia." ], "sam006": [ - "Finally, you got here! Find the Lurker Totem", + "Wreszcie tu dotarłeś! Znajdź totem Lurkera", "i odzyskałem część pieczęci Mara z jej wierzchołka." ], "sam007": [ - "You've got to get the boy safely to the Power Station, Jak!" + "Musisz bezpiecznie zawieźć chłopca do elektrowni, Jak!" ], "sam008": [ "Dziękuję za ochranianie nas, Jak.", "Spotkamy się w Gnieździe." ], "sigc001": [ - "Hold on there, we need to teach you how to use this baby!" + "Zaczekajże, musimy cię nauczyć, jak korzystać z tego maleństwa!" ], "sigc002": [ "Broń rozpryskowa jest dobra na krótki dystans", @@ -7085,7 +7092,7 @@ "Aby wystrzelić, naciśnij spust." ], "sigc004": [ - "Good! Some kick, huh?" + "Dobrze! Trochę pokopałeś, huh?" ], "sigc005": [ "Nie jest to jednak najszybciej strzelająca broń na świecie." @@ -7115,142 +7122,142 @@ "Świetnie, teraz jesteś gotowy!" ], "sigc014": [ - "Want to try the Scatter Gun course?" + "Chcesz wypróbować kurs Broni Rozpryskowej?" ], "sigc015": [ - "The blaster is a good all-around choice", - "with a nice rate of fire." + "Blaster to dobry, wszechstronny wybór", + "z niezłą szybkostrzelnością." ], "sigc016": [ - "This weapon requires more aiming ability." + "Ta broń wymaga większej umiejętności celowania." ], "sigc017": [ - "You can switch weapon modes at anytime." + "Możesz zmienić tryb broni w dowolnym momencie." ], "sigc018": [ "Możesz znaleźć żółtą amunicję w skrzyniach." ], "sigc022": [ - "Would you like to test your skills on the gun course?" + "Czy chciałbyś przetestować swoje umiejętności na strzelnicy?" ], "sigc023": [ - "Which course do you want to play?" + "Na którym kursie chcesz zagrać?" ], "sigc024": [ - "Shoot every target. The faster you shoot each target", - "the more points you'll get." + "Strzelaj do każdego celu. Im szybciej strzelasz do każdego celu", + "tym więcej punktów otrzymasz." ], "sigc025": [ "Wstrzymaj ogień przed cywilami.", - "Hit a friendly target and points will be deducted." + "Traf w przyjazny cel, a punkty zostaną odjęte." ], "sigc026": [ "Powodzenia." ], "sigc027": [ - "Lock and load. Ready, go!" + "Załaduj broń. Gotowy, ruszaj!" ], "sigc028": [ - "Perfect! You can be my backup any day." + "Perfekcyjnie! Możesz być moim wsparciem każdego dnia." ], "sigc029": [ - "You did it, excellent shooting!" + "Udało Ci się, Doskonale strzelałeś!" ], "sigc030": [ "Nieźle strzelasz! Masz potencjał, młody!" ], "sigc031": [ - "Not bad, you'll do." + "Nieźle, dasz radę." ], "sigc032": [ - "Try again, rookie. You're still a bit rusty with that hardware." + "Spróbuj ponownie, nowicjuszu. Nadal jesteś trochę zardzewiały z tym sprzętem." ], "sigc033": [ - "Not bad, but not good. Try again?" + "Nieźle, ale też nie było za dobrze. Chcesz spróbować jeszcze raz?" ], "sigc034": [ - "Close, but in the thick, close won't cut it. Try again?" + "Blisko, ale w wirze walki, byś przegrał. Chcesz spróbować jeszcze raz?" ], "sigc035": [ - "Care to try again? Or is your momma calling?" + "Chcesz spróbować jeszcze raz? A może woła Twoja mama?" ], "sigc036": [ - "You're not up to speed yet, try again?" + "Nie jesteś wystarczająco szybki jeszcze. Chcesz spróbować jeszcze raz?" ], "sigc037": [ - "You gotta shoot those targets faster!" + "Musisz szybciej strzelać do tych celów!" ], "sigc038": [ - "Be the gun, baby!" + "Bądź bronią, młody!" ], "sigc039": [ - "It's all about reaction time." + "To wszystko zależy od czasu reakcji." ], "sigc040": [ - "Different gun modes come in handy against different targets." + "Różne tryby broni przydają się w walce z różnymi celami." ], "sigc041": [ - "Be cool and you'll rule." + "Bądź spokojny, a będziesz rządził." ], "sigc043": [ - "Try switching to the Scatter Gun." + "Spróbuj zmienić na Broń Rozpryskującą." ], "sigc053": [ - "Faster on the trigger, cherry." + "Szybciej naciskaj na spust, świeżaku." ], "sigc054": [ "To był cywil!" ], "sigc055": [ - "I said \"don't shoot civvies,\" itchy finger!" + "Powiedziałem „nie strzelaj do cywilów”, swędzący palec!" ], "sigc056": [ "Dobra robota!" ], "sigc057": [ - "Awesome round, I feel sorry for those Metal Heads already." + "Świetna runda, Już mi szkoda tych Metalowych Łbów." ], "sigc058": [ - "That was a sweet round, you make it look easy!" + "To była przyjemna runda, sprawiasz że to wygląda na łatwe!" ], "sigc059": [ - "You smoked that course!" + "Dałeś czadu na tym kursie!" ], "sigc060": [ - "The Metal Heads will eat you alive, rookie! Do it over!" + "Metalowe Łby zjedzą cię żywcem, świeży! Zrób to!" ], "sigc061": [ "Potrzebujesz trochę praktyki." ], "sigc062": [ - "I remember my rookie days, keep trying." + "Pamiętam dni, kiedy to ja zaczynałem, próbuj dalej." ], "sigc063": [ - "Perfect round! You are the man." + "Perfekcyjna runda! Jesteś człowiekiem." ], "sigc064": [ - "Perfect shooting! I'm impressed." + "Idealne strzelanie! Jestem pod wrażeniem." ], "sigc065": [ - "Whoa, rock and roll, baby! That was a perfect round." + "Łoo, rock and roll, dzieciaku! To była idealna runda." ], "sigc066": [ "Niezły strzał!" ], "sigc067": [ - "Wasted 'em!" + "Wykończyłeś ich!" ], "sigc068": [ - "Very nice! Reminds me of me." + "Bardzo dobrze! Przypomina mi mnie." ], "sigc069": [ - "Make 'em fear you." + "Spraw, żeby się ciebie bali." ], "sigc070": [ "Dobry kombinacja!" ], "sigc071": [ - "I love seeing you work!" + "Uwielbiam patrzeć, jak pracujesz!" ], "sigc072": [ "Teraz przełącz się z powrotem na Blaster." @@ -7270,117 +7277,117 @@ "Świetny ruch!" ], "sigc077": [ - "Not quite, try again. Kick then shoot, almost at the same time." + "Niezupełnie. Spróbuj ponownie. Kopnij, a następnie strzel, prawie w tym samym czasie." ], "sigc078": [ - "Make sure you shoot while you're kicking to get the combo." + "Pamiętaj, aby strzelać podczas kopania, aby uzyskać kombinację." ], "sigc079": [ "Spróbuj jeszcze raz." ], "sigc080": [ - "Now that's a Wastelander move!", + "To ruch godny mieszkańca Pustkowi!", "Nie będą wiedzieli skąd dostali!" ], "sigc081": [ - "Think you can handle the Blaster course?" + "Myślisz, że poradzisz sobie z kursem Blastera?" ], "sigf001": [ - "You wasted 'em all! I'm still not sure why combat Metal Heads", - "are scouting this close to the city. To be honest,", - "I wasn't sure you could handle this gig, nice work!" + "Załatwiłeś ich wszystkich. Nadal nie jestem pewien, dlaczego bojowe Metalowe Łby", + "prowadzą zwiad tak blisko miasta. Szczerze mówiąc,", + "Nie byłem pewien, czy poradzisz sobie z tą robotą, dobra robota!" ], "sigt003": [ - "Here we go!" + "No to zaczynamy!" ], "sigt004": [ "Za mną!" ], "sigt005": [ - "Get behind me while I toast that tank." + "Stań za mną, a ja wysadzę ten zbiornik." ], "sigt006": [ - "Hurry up kid, I don't have all day!" + "Pośpiesz się, dzieciaku, nie mam całego dnia!" ], "sigt007": [ "Tędy!" ], "sigt008": [ - "Toast those bad boys up ahead." + "Zajmij się tymi draniami przed nami." ], "sigt009": [ "Szybko! Opuść most!" ], "sigt010": [ - "Jump up and grab the bridge to bring it down." + "Podskocz i złap się mostu, aby go obniżyć." ], "sigt011": [ - "Let's get across the bridge before they come back." + "Przejdźmy przez most, zanim oni wrócą." ], "sigt012": [ - "There's our first target, keep the other creatures back", - "while I charge up the Peacemaker." + "Oto nasz pierwszy cel, trzymajcie inne stworzenia z daleka", + "podczas gdy ja ładuje Rozjemcę." ], "sigt013": [ - "That's one fried Metal Head." + "To jeden przysmażony Metalowy Łeb." ], "sigt014": [ - "Let's get to the next target." + "Chodźmy do następnego celu." ], "sigt015": [ - "With Metal Heads I say shoot first, ask questions later." + "W przypadku Metalowych Łbów mówię, najpierw strzelaj, później zadawaj pytania." ], "sigt017": [ - "Stay with me!" + "Trzymaj się mnie!" ], "sigt019": [ - "Waste the suckers!" + "Załatw frajerów!" ], "sigt020": [ - "Great, kid, great! Don't get cocky." + "Świetnie, chłopcze, świetnie! Tylko nie bądź zbytnio pewny siebie." ], "sigt021": [ - "There's the second scumbag, sittin' pretty." + "Jest drugi drań, siedzi sobie ładnie." ], "sigt022": [ "Osłaniaj mnie!" ], "sigt023": [ - "Boom, baby! One less Metal Head to think about." + "Bum, skarbie! Jeden Metalowy Łeb mniej do zamartwiania się." ], "sigt024": [ "Następny cel." ], "sigt025": [ - "Watch my six, while I toast this bad boy.", - "The trick is to not hit the pipes." + "Pilnuj mi plecy, gdy ja upiekę tego drania.", + "Sztuka polega na tym, aby nie uderzyć w rury." ], "sigt026": [ - "Now that's what I call blowing someone's mind." + "To właśnie nazywam zaskoczeniem." ], "sigt027": [ - "Gotta thread the needle this time." + "Muszę teraz naprawdę się skupić." ], "sigt028": [ - "Hahaha, Metal Head flambé." + "Hahaha, płonący Metalowy Łeb" ], "sigt029": [ - "Look out! We've got company!" + "Uwaga! Mamy towarzystwo!" ], "sigt030": [ - "Damn! My gun's jammed, take over!" + "Cholera! Moja broń się zacięła, przejmij kontrolę nad sytuacją!" ], "sigt031": [ - "Get 'em while I fix my gun!" + "Załatw ich, a ja naprawię moją broń!" ], "sigt032": [ - "Okay, the Peacemaker is back online. Let's move!" + "Okej, Rozjemca znów działa. Ruszajmy!" ], "sigt033": [ - "Last target, then we go home." + "Ostatni cel i wracamy do domu." ], "sigt036": [ - "Here comes trouble." + "Nadchodzą kłopoty." ], "sigt037": [ "Tęskniłeś za mną?" @@ -7392,37 +7399,37 @@ "Dzięki za osłanianie mojego tyłka to było blisko!" ], "sigt043": [ - "Stay with me!" + "Trzymaj się mnie!" ], "sigt044": [ - "Stay close or we'll both be dead!" + "Trzymaj się blisko albo oboje będziemy martwi!" ], "sigt045": [ "Podejdź, że tu i trzymaj się blisko!" ], "sigt046": [ - "You wanna play, huh?" + "Chcesz się pobawić, co?" ], "sigt047": [ - "Oh, you got games?" + "Oh, dobrze się bawisz?" ], "sigt049": [ - "You cherries can't handle this mission, we're through!" + "Świeżący nie poradzicie sobie z tą misją, Jesteśmy skończeni!" ], "sigt052": [ "Nie pracuję z amatorami!" ], "sigt053": [ - "You're more trouble than you're worth!" + "Sprawiacie więcej kłopotów, niż jesteście warci!" ], "sigt054": [ - "Come back when you're serious!" + "Wróćcie, kiedy zaczniecie się zachowywać poważnie!" ], "sigt056": [ - "You want some of this?!" + "Chcesz trochę z tego?!" ], "sigt057": [ - "Drop that lift-cap while I hold them off." + "Opuść ten podnośnik, a ja ich zatrzymam." ], "sigt058": [ "Zdejmij ich wszystkich!" @@ -7431,11 +7438,11 @@ "Świetnie, nie ma czasu na świętowanie." ], "sigt060": [ - "If I can't shoot it, it's someone else's problem.", - "You do something with those blocks." + "Jeśli nie mogę strzelać, to kogoś innego problem.", + "Zrób coś z tymi blokami." ], "sigt061": [ - "You gotta figure out the blocks, man." + "Musisz rozpracować bloki, stary." ], "sigt062": [ "Słyszałeś coś?" @@ -7444,25 +7451,25 @@ "To jest jeden wielki brzydki metalowy łeb." ], "sigt064": [ - "Shootin' this one's only going to get it mad, run!" + "Strzelanie do Tego tylko go wkurzy, uciekaj!" ], "sigt065": [ - "See ya on the flipside!" + "Do zobaczenia po drugiej stronie!" ], "sigt066": [ - "Gone with the wind." + "Przeminął z wiatrem." ], "sigt067": [ - "Later alligator." + "Nara." ], "sigt068": [ - "I think that's the last we'll see of him." + "Myślę, że to ostatni raz, kiedy go widzimy." ], "sigt069": [ - "You figure this out, I'll cover your butt." + "Rozgryź to, a ja będę osłaniał twój tyłek." ], "sigt070": [ - "This is your gig, baby. Solve it, so we can go home." + "To twój robota, młody. Rozwiąż to, abyśmy mogli wrócić do domu." ], "sigt071": [ "Świetnie, znowu ten drań. Ruchy!" @@ -7474,61 +7481,61 @@ "Jazda, jazda, jazda!" ], "sigt074": [ - "He's gaining!" + "Zaczyna doganiać!" ], "sigt075": [ - "Keep moving!" + "Idźmy dalej!" ], "sigt076": [ "Szybciej!" ], "sigt077": [ - "It's gonna be close!" + "To będzie bliskie!" ], "sigt078": [ "Ruszyć tyłki!" ], "sigt082": [ - "Buddy, you don't wanna piss me off." + "Kolego, nie chcesz mnie wkurzyć." ], "sigt083": [ - "You got a death wish?!" + "Masz życzenie śmierci?!" ], "sigt087": [ - "Have a little pain right back!" + "Przesyłka specjalna: Ból!" ], "sigt089": [ "Nigdy nie ufaj żółtodziobowi." ], "sigt090": [ - "We're finished until you guys get serious." + "To będzie nasz koniec, chyba że zaczniecie brać to na poważnie." ], "sigt091": [ - "This mission is obviously out of your league." + "Ta misja jest oczywiście poza twoją ligą." ], "sigt092": [ - "You're wasting my time, this mission is over." + "Marnujesz mój czas, ta misja jest skończona." ], "sigt093": [ "Uhh... ugh...." ], "sigt100": [ - "Rage before beauty, buddy." + "Furia przed pięknem, kolego." ], "sigt101": [ "Ruszajmy!" ], "sigt102": [ - "I love the smell of burning metal!" + "Uwielbiam zapach palonego metalu!" ], "sigt103": [ - "Just a walk in the park." + "Po prostu spacer po parku." ], "sigt104": [ "Za mną!" ], "sigt105": [ - "Let's go!" + "Jazda!" ], "sigt106": [ "Tędy!" @@ -7537,61 +7544,72 @@ "Tutaj!" ], "sigt108": [ - "Rollin' baby!" + "Rządzimy kotku!" ], "sigt109": [ - "Blow 'em a kiss of death." + "Sprezentowaliśmy im pocałunek śmierci." ], "sigt110": [ - "I love dead-heads!" + "Uwielbiam martwe łby!" ], "sigt111": [ - "Kiss your shiny butt goodbye!" + "Pocałuj swój błyszczący tyłek na do widzenia!" ], "sigt112": [ - "Born to kill baby!" + "Born to kill, baby!" ], "sigt113": [ - "Two to the chest, one to the head." + "Dwa w klatę, i jeden w głowę." ], "spot004": [ - "Come out and cheer for me as I destroy the competition once again on the track.", - "This year's racing final will be to die for, I guarantee more thrills and more spills.", - "This time I want blood!...Bring the kids." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ - "Hey, guys! This is Tess. Before Krew left, I saw him hide", - "something in the game machine here. Knowing Krew,", - "it's probably something valuable.", - "You might wanna come check it out." + "Cześć chłopaki! Tu Tess. Zanim Krew wyszedł, Widziałam jak on ukrywał", + "coś w maszynie do gier. Znając Krew,", + "to prawdopodobnie coś cennego.", + "Może zechcecie przyjść i to sprawdzić." ], "tor001": [ - "The operation was a success. All Underground members are safe.", - "Come back to the hideout, I have a new mission for you while we wait for this alert to blow over." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "That should take some heat off the streets. Good work, I couldn't have done it better myself." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "That's it, Jak, you're up! Try not to trigger any alarms, the garrison guards will be tough.", - "Get to the prison cell block and find the prisoners. Once there, we'll turn on the Warp Gate inside to get you all back out. Good luck." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "Ok, my old access codes should help Vin turn off the magnetic seal for the Fortress door." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Jak, this is Torn, the city is under Metal Head attack. There's a large force moving toward the city wall from the ocean.", - "We need people manning the tower gunpods to stop that assault. Meet me at the seaside ocean wall in the Port, hurry!", - "We need every man we can get!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ - "Jak, it's a guard roadblock, get out of there!" + "Jak, to blokada drogowa straży, wynoś się stamtąd!" ], "tor008": [ - "They've set up a roadblock, they're onto you!" + "Założyli blokadę drogową, Chcą cię dopaść!" ], "torn024": [ - "More coming in!" + "Więcej ich idzie!" ], "tswm001": [ "Możesz to zrobić, Daxter!" @@ -7600,40 +7618,40 @@ "Dawaj dalej, Daxter." ], "tswm003": [ - "Go, go, go!" + "Jazda, jazda, jazda!" ], "tswm004": [ "Wow! Co za zwierzę!" ], "tswm005": [ - "You got it!" + "Załapałeś to!" ], "tswm006": [ - "Nice slam!" + "Nieźle trzasnąłeś!" ], "tswm007": [ - "Ooh ho ho, baby!" + "Och ho ho, skarbie!" ], "tswm008": [ "Świetny strzał, Daxter!" ], "tswm009": [ - "You're almost there!" + "Już prawie jesteś!" ], "tswm010": [ - "You can win, baby!" + "Możesz wygrać, skarbie!" ], "tswm011": [ "Mój bohater!" ], "tswm012": [ - "Look at him go!" + "Spójrz, jak odchodzi!" ], "tswm013": [ "Jesteś Pomarańczową Błyskawicą!" ], "tswm014": [ - "Just a few more!" + "Jeszcze tylko kilka!" ], "tswm015": [ "Uderz go jeszcze raz!" @@ -7657,7 +7675,7 @@ "Ooh!" ], "tswm022": [ - "That took points away!" + "To zabrało punkty!" ], "tswm023": [ "Zrobiłeś to!" @@ -7666,13 +7684,13 @@ "Daxter, wygrałeś!" ], "tswm025": [ - "Yes! You're the man! I mean... the animal." + "Tak! Jesteś człowiekiem! Mam na myśli... zwierzęciem." ], "tswm026": [ "Ukończyłeś grę, Daxter!" ], "tswm027": [ - "Where'd you learn to pound like that?" + "Gdzie nauczyłeś się tak walić?" ], "tswm028": [ "To było niesamowite!" @@ -7714,7 +7732,7 @@ "Nie uderzaj w złe, Daxter." ], "tswm041": [ - "Uderzyłeś złego metalowego łba." + "Uderzyłeś w złego Metalowego Łba." ], "tswm042": [ "No nie, znowu!" @@ -7729,13 +7747,13 @@ "Dawaj dalej...!" ], "tswm046": [ - "Oh, Daxter... did you get your whiskers singed?" + "Och, Daxter... czy przypaliłeś sobie wąsy?" ], "tswm047": [ - "You're gonna score!" + "Zdobędziesz punkt!" ], "tswm048": [ - "Już prawie tam jesteś...!" + "Już prawie to masz...!" ], "tswm049": [ "Jeszcze kilka!" @@ -7744,13 +7762,13 @@ "Mamy zwycięzcę!" ], "tswm051": [ - "Oh! That was a bad one." + "Oo, To był ten zły." ], "tswm052": [ - "Don't hit the bad ones, Daxter." + "Nie uderzaj w złe, Daxter." ], "tswm053": [ - "Daxter, you hit a bad Metal Head!" + "Daxter, uderzyłeś w złego Metalowego Łba!" ], "tswm054": [ "Daxter, wygrałeś!!" @@ -7765,8 +7783,8 @@ "Wiedziałem, że możesz to zrobić" ], "vin002": [ - "Okay, the B-Zone Power Grid is back online.", - "Have fun being killed in the Palace." + "Dobra, Sieć energetyczna w strefie B znów działa.", + "Miłej zabawy w byciu zabijanym w Pałacu." ], "vin003": [ "Zniszczyłeś ostatnie z jaj Metalowych Łbów!", @@ -7774,18 +7792,18 @@ "Dobra robota!" ], "vin004": [ - "You still haven't gotten all the Metal Head eggs!", - "Make sure you get 'em all, or I'm gonna have", + "Nadal nie udało ci się zdobyć wszystkich jaj Metalowych Łbów!", + "Upewnij się, że zniszczysz je wszystkie, albo będę miał", "załamanie nerwowe!" ], "vin011": [ - "Thank goodness you blew up those wells.", - "I sure don't want any more Metal Heads coming around here.", + "Dzięki Bogu, że wysadziłeś te szyby.", + "Z pewnością nie chcę, żeby więcej Metalowych Łbów tu przychodziło.", "Dobra robota, chłopcy! Wiszę wam przysługę." ], "vin012": [ - "Good work, guys! The fewer Metal Head eggs", - "we allow to hatch, the fewer of those nasty monsters", + "Dobra robota, chłopaki! Im mniej jaj Metalowych Łbów", + "pozwalamy się wykluć, tym mniej paskudnych potworów", "będziemy musieli walczyć!" ], "vin013": [ @@ -7796,7 +7814,7 @@ "vin014": [ "Po raz kolejny uratowaliście mój tyłek!", "Może teraz dostanę podwyżkę. Albo dłuższy urlop.", - "God knows I could use one. Thanks for the help!" + "Bóg jeden wie, że przydałby mi się taki. Dziękuję za pomoc!" ], "vin015": [ "Tarcza muru padłą! Powtarzam - tarcza muru padła!", @@ -7807,8 +7825,8 @@ "Jest ich zbyt wiele!! Jak!! AHHHH!!!" ], "ys001": [ - "Świetna robota, chłopacy! Wracajcie do kryjówki, ", - "Mam dla ciebie kolejne zadanie." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Ładnie strzelasz, chłopcze!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_pt-BR.json b/game/assets/jak2/subtitle/subtitle_lines_pt-BR.json index abb7989c79..e1d9e82d39 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_pt-BR.json +++ b/game/assets/jak2/subtitle/subtitle_lines_pt-BR.json @@ -5,7 +5,7 @@ "Você parece zangado, Jak." ], "DSbop002": [ - "Você lembra como pular?" + "Você se lembra de como pular?" ], "DSbop003": [ "Pule nessa caixa para ultrapassar a barricada." @@ -713,7 +713,8 @@ ], "bb06int": [ "Jak, precisamos que você elimine outro grupo de Robôs-Bomba.", - "Essas armas móveis continuam aparecendo na cidade, temos que eliminá-las o mais rápido possível." + "Essas armas móveis continuam aparecendo na cidade,", + "Temos que retirá-los o mais rápido possível." ], "bb06win": [ "Outra pilha de sucata de robôs-bomba para a GK", @@ -724,20 +725,23 @@ "Você perdeu um agente! NADA bom, Jak! Missão fracassada!" ], "bb07int": [ - "Torn aqui, preciso que você saia e leve mais de nossos agentes para novos locais na cidade.", - "Os espiões da GK estão observando todos os nossos movimentos, portanto, fique atento a problemas. Boa sorte." + "Esmague aqui, eu preciso que você saia e mova mais de nossos Agentes", + "Para novos locais na cidade.", + "Espiões do KG estão observando todos os nossos movimentos,", + "então procure por problemas. Boa sorte." ], "bb07win": [ "Bom trabalho com o ônibus! Você está mantendo as pessoas vivas por aí." ], "bb08fail": [ - "Um de nossos melhores agentes foi preso. O Sombra NÃO ficará", + "Um de nossos melhores agentes foi preso. O Shadow NÃO ficará", "satisfeito! Você falhou." ], "bb08int": [ "Jak, alguns de nossos agentes foram comprometidos novamente.", "Encontre cada um deles e leve-os para esconderijos especiais na cidade.", - "As patrulhas estão em alerta máximo, portanto, essa será uma tarefa difícil. Mantenha sua cabeça baixa!" + "As patrulhas de guarda estão em alerta alto,", + "então isto vai ser difícil. Mantenha a cabeça baixa!" ], "bb08win": [ "Foi uma boa condução, Jak.", @@ -1432,9 +1436,9 @@ "Sinta isso!" ], "bru001": [ - "Great smelly breath of a goosesnake!", + "Grande bafo fedido de uma cobra-ganso!", "Vocês são heróis para o povo Lurker!", - "By now just see much happy thanks! Ruhuhuh.", + "Até agora, só vejo muita felicidade, obrigado! Huhuhuh.", "Agora vocês são membros honorários da tribo Lurker.", "Nós não esquecemos - se você precisar de nós, o ajudaremos!" ], @@ -1920,37 +1924,37 @@ "Você não removeu todo o Eco Sombrio a tempo." ], "cityv154": [ - "You removed the Dark Eco hazard in time.", + "Você removeu o Eco Escuro a tempo.", "A cidade é grata a você." ], "cityv155": [ - "Sensors indicate a cluster of Blue Eco in the city.", - "Collect all eco before it dissipates", - "and you will be rewarded." + "Sensores indicam um aglomerado de Eco Azul na cidade.", + "Colete todo o Eco antes que ele se dissipe.", + "E você será recompensado." ], "cityv156": [ - "You did not retrieve all of the eco." + "Você não recuperou todo o Eco." ], "cityv157": [ - "You successfully retrieved the eco.", + "Você recuperou com sucesso o Eco.", "Aqui está a sua recompensa." ], "cityv158": [ - "Emergency response needed.", - "Runaway bomb bots detected and headed for", - "populated areas. Neutralize all bomb bots", - "before it's too late." + "Resposta de emergência necessária.", + "Bots-bomba descontrolados detectados e se dirigindo para", + "áreas povoadas. Neutralize todos os bots-bomba.", + "antes que seja tarde demais." ], "cityv159": [ - "You failed to neutralize the runaway bomb bots." + "Você falhou em neutralizar os bots-bomba descontrolados." ], "cityv160": [ - "You destroyed the runaway bomb bots.", + "Você destruiu os bots-bomba descontrolados.", "A cidade lhe agradece." ], "cityv161": [ "Chegue a este ponto no jogo rapidamente", - "and you will receive a prize." + "e você receberá um prêmio." ], "cityv162": [ "Tente encontrar este lugar." @@ -1965,23 +1969,23 @@ "Encontre este local para ganhar um prêmio." ], "cityv166": [ - "Get to this spot for a prize." + "Vá para este local para receber um prêmio." ], "cityv167": [ - "Metal Heads have been detected in the gun course.", - "Neutralize them all immediately." + "Cabeças de Metal foram detectadas no campo de tiro.", + "Neutralize todos eles imediatamente." ], "cityv168": [ - "You did not kill them all." + "Você não os matou todos." ], "cityv169": [ - "Excellent shooting. Threat eliminated." + "Excelente tiro. A ameaça foi eliminada." ], "cityv170": [ - "Get a high score on the JET-Board and receive a prize." + "Obtenha uma pontuação alta no JET-Board e receba um prêmio." ], "cityv171": [ - "Try for a high score and receive a prize." + "Tente conseguir uma pontuação alta e receba um prêmio." ], "cityv172": [ "Você não obteve uma pontuação alta o suficiente." @@ -2072,13 +2076,13 @@ "Precisamos de algo para atravessar aquele portão!" ], "daxm003": [ - "Shoot the Metal Head when he moves his shield!" + "Atire no Cabeça metálica quando ele mover o escudo" ], "daxm004": [ "Acerte ele no estômago!" ], "daxm005": [ - "Whoa! That path dropped like uh... a rock!" + "Opa! Esse caminho caiu como an... uma pedra!" ], "daxm006": [ "Esmague a caixa, bebê!" @@ -2102,17 +2106,17 @@ "Jak, esses são Cabeças de Metal!" ], "ds006": [ - "Finally, now we get to see the Shadow!", - "What do ya gotta do around this place to get noticed?" + "Finalmente, agora vamos ver o Shadow!", + "O que você tem que fazer em torno desse lugar para ser visto?" ], "ds012": [ "Deve ser essa a Chave de Rubi para a cidade." ], "ds013": [ - "Statues are becoming an endangered species around here." + "As estátuas estão se tornando uma espécie em extinção por aqui." ], "ds014": [ - "So this is Mar's scary tomb, eh?", + "Então esta é a tumba assustador de Mar, hein?", "Não parece tão ruim." ], "ds016": [ @@ -2276,87 +2280,87 @@ "Atire na plataforma, Jak." ], "ds117": [ - "We need something to get through that gate." + "Precisamos de algo para atravessar aquele portão." ], "ds118": [ - "Shoot the Metal Head when he moves his shield." + "Atire no Cabeça metálica quando ele mover o escudo" ], "ds119": [ - "Hit him in his stomach." + "Acerte ele no estômago." ], "ds120": [ - "Whoa, that path dropped like a... a rock!" + "Uau, esse caminho caiu como uma.. uma pedra!" ], "ds121": [ - "Smack the box, baby!" + "Esmague a caixa, bebê!" ], "ds128": [ - "Good, we're through." + "Bom, nós já passamos." ], "ds129": [ - "Atire na arma, Jak!" + "Atire a arma, Jak!" ], "ds143": [ - "We're supposed to keep Krew's guys alive, Jak!" + "Temos que manter os caras do Krew vivos, Jak!" ], "ds144": [ - "Save 'em, Jak!" + "Salve-os, Jak!" ], "ds145": [ - "Don't like this, Jak..." + "Não estou gostando disso, Jak!" ], "ds146": [ - "Behind us, Jak!" + "Atrás de nós, Jak!" ], "ds147": [ - "Metal Heads! Everywhere!" + "Cabeças de Metal! Em todo lugar!" ], "ds148": [ - "Protect us, Jak! But first me." + "Proteja-nos, Jak! Mas primeiro eu." ], "ds150": [ - "Take a vehicle, Jak! It's faster." + "Pegue um veículo, Jak! É mais rápido." ], "ds151": [ - "Use your JET-Board!" + "Use seu JET-Board!" ], "ds152": [ - "We got company, Jak! Lots of guards!" + "Temos companhia, Jak! Muitos guardas!" ], "ds160": [ - "That's right, we're bad! The Precursor Stone is ours!" + "É isso mesmo, somos maus! A Pedra Precursora é nossa!" ], "ds161": [ - "There's Mar's gun, Jak! Let's go check it out." + "Ali está a arma de Mar, Jak! Vamos dar uma olhada nela." ], "ds162": [ - "These Precursor Orbs are worth a lot now.", - "We might find a few hidden around,", - "or get some doing difficult tasks.", - "We'll be able to buy stuff with 'em!" + "Essas orbes Precursor valem muito agora.", + "Podemos encontrar alguns escondidos, por aí,", + "ou fazer algumas tarefas difíceis", + "Poderemos comprar coisas com eles!" ], "ds163": [ - "Jak, now that we have the Palace Security Pass,", - "let's go have some fun in the big man's crib!" + "Jak, agora que temos o Passe de Segurança do Palácio,", + "vamos nos divertir no berço do chefão!" ], "ds164": [ - "Back up to get out of the mech." + "Recue para sair do mech." ], "ds165": [ "Estamos livres, Jak! Graças a mim.", - "Nice to breathe some fresh air, huh?", - "We'll get that Baron Praxis guy, alright!" + "Bom respirar um pouco de ar fresco, né?", + "Vamos pegar o Barão Praxis, certo!" ], "ds166": [ - "I'm not getting out of this pod", - "'till you kill all those crazy flyin' Metal Heads!" + "Não sairei desta cápsula", + "até você matar todos esses loucos Cabeças de Metal!" ], "ds167": [ - "I wonder why they wanted us to protect Samos' Hut.", - "Maybe now we'll get to meet the Shadow." + "Pergunto-me porquê eles queriam que nós protegêssemos a Cabana de Samos.", + "Talvez agora nós vamos encontrar o Shadow." ], "ds168": [ - "There's the Rift Ring!" + "Aqui está o Rift Ring!" ], "ds173": [ "Ahhh!" @@ -2383,31 +2387,31 @@ "Ah, garoto!" ], "ds181": [ - "Uooaaoh!" + "Oooaaaaaaaaaaaaau!" ], "ds182": [ "Uau, isso foi por pouco!" ], "ds183": [ - "Oh, boy!" + "Oh, garoto!" ], "ds184": [ "Sim!" ], "ds185": [ - "Yeah!" + "Isso!" ], "ds186": [ - "Hey, watch it!" + "Ei, vejam isso!" ], "ds187": [ - "All right!" + "Certo!" ], "ds188": [ - "Move over!" + "Saia da frente!" ], "ds189": [ - "Orange Lightning coming through!" + "Raio Laranja passando!" ], "ds190": [ "Curtindo com os camaradas!" @@ -2434,7 +2438,7 @@ "Saia da frente!" ], "ds198": [ - "Move it or lose it, buddy!" + "Mexa-se ou caia fora, amigo!" ], "ds199": [ "Mm... Tchauzinho!" @@ -2449,10 +2453,10 @@ "Vamos, vamos, vamos!" ], "ds203": [ - "Pedal to the metal!" + "Pedal para o metal!" ], "ds204": [ - "Ooooah, I gotta catch up!" + "Ooooah, eu tenho que alcançar!" ], "ds205": [ "Vire e queime, bebê!" @@ -2497,32 +2501,32 @@ "Wahoo!" ], "ds219": [ - "Hey, fang boy, hurry up and get in,", - "we'll take you to Brutter!" + "Ei, presas, corra e entre,", + "vamos levá-lo ao Brutter!" ], "ds220": [ - "Here's your boy, Brutter! We're off to get another animal!" + "Aqui está seu filho, Brutter! Estamos indo buscar outro animal!" ], "ds221": [ - "Yo, animal lover, get your furry butt in the vehicle!" + "Ei, amante dos animais, coloque seu traseiro peludo no veículo!" ], "ds222": [ - "Here's another beast of burden!" + "Aqui está outro animal de carga!" ], "ds223": [ - "In the vehicle, buddy, we can save you!" + "No veículo, amigo, podemos salvá-lo!" ], "ds224": [ - "Another Lurker freed." + "Outro Lurker libertado." ], "ds225": [ - "Let's move, eco breath! We gotta get you to Brutter." + "Vamos lá, bafo de eco! Temos que levá-lo ao Brutter." ], "ds226": [ - "Hey, Brutter! Look what the cat turkey dragged in." + "Ei, Brutter! Veja o que o gato peru trouxe para cá." ], "ds227": [ - "Lookie what we found!" + "Veja o que encontramos!" ], "ds228": [ "Você reconhece este monstro?" @@ -2531,106 +2535,106 @@ "Nós conseguimos! Nós salvamos todos eles!" ], "ds230": [ - "Catch the paddywagon, Jak!" + "" ], "ds231": [ - "Crash the paddywagon!" + "" ], "ds232": [ - "A little more damage and we got the sucker!" + "Um pouco mais de dano e pegamos o otário!" ], "ds233": [ - "He's smoking, Jak! Hit him again!" + "" ], "ds234": [ "Isso causou algum dano!" ], "ds235": [ - "One more like that and he's through!" + "Mais um desse e ele está acabado!" ], "ds236": [ "Encontre o próximo veículo!" ], "ds237": [ - "Yes, we took it out!" + "Sim, nós retiramos daqui!" ], "ds238": [ - "Hunt and destroy, baby!" + "Cace e destrua, bebê!" ], "ds239": [ - "Hit it, hit it!" + "Acerte, bate!" ], "ds240": [ - "Take it out!" + "Tire!" ], "ds241": [ - "Pick up the Lurker, Jak!" + "Pegue o Lurker, Jack!" ], "ds242": [ - "Get the Lurker!" + "Pegue o Lurker!" ], "ds243": [ - "We need to pick up that Lurker back there." + "Temos de pegar esse Lurker lá atrás." ], "ds244": [ - "Usually, I don't like to be this close to Lurkers." + "Normalmente, eu não gosto de estar tão perto dos Lurkers." ], "ds245": [ - "Ehehe, you seem like a nice, uh... animal." + "Ehehe, você parece um bom, uh... animal." ], "ds246": [ - "Easy, buddy. Don't bite me!" + "Devagar, amigo. Não me morda!" ], "ds247": [ - "Hey, stop slobbering on me!" + "Ei, pare de bestejar em mim!" ], "ds248": [ - "He's recharging!" + "Ele está recarregando!" ], "ds249": [ - "Ooh, we got him good that time!" + "Ah! Nós o pegamos em cheio desta vez!" ], "ds250": [ - "Yeah, now he's hurtin'!" + "Sim, agora ele está machucado!" ], "ds251": [ - "Good shot, Jak!" + "Boa jogada, Jack!" ], "ds252": [ - "Incoming!" + "Recebido!" ], "ds253": [ - "Yeah, we got him!" + "Boa, nós o pegamos!" ], "ds254": [ - "Jak, hide behind the pillars when he shoots!" + "Jack, esconde-se atrás dos pilares quando ele atira!" ], "ds255": [ - "He's got the Precursor Stone!" + "Ele tem a Pedra Precursor!" ], "ds256": [ - "Kick the bomb right at him, Jak!" + "Chute a bomba direto para ele, Jack!" ], "ds257": [ - "That one hit him!" + "Aquele bateu nele!" ], "ds258": [ - "Look out!" + "Cuidado!" ], "ds259": [ - "Jump the gap!" + "Pule o vão!" ], "ds260": [ "Boa, você acertou ele!" ], "ds261": [ - "As if there wasn't enough of Krew already." + "Como se já não houvesse bastante Krew." ], "ds262": [ - "Shoot 'em all, Jak! We'll sort 'em out later..." + "Atire em tudo, Jack! Nós vamos organizar tudo mais tarde..." ], "ds263": [ - "There's the real Krew! Shoot him!" + "" ], "ds264": [ "Você pegou ele!" @@ -2648,13 +2652,13 @@ "Bom tiro, Jak! O grandalhão está se doendo agora." ], "ds269": [ - "And the challenger is down for the count!" + "" ], "ds270": [ - "Keep movin', baby! He's gonna shoot!" + "Continue andando, bebê! Ele vai atirar!" ], "ds271": [ - "Wooh, here come some Metal Heads!" + "Uau, aqui vem algumas Cabeças de Metal!" ], "ds272": [ "Proteja a criança!" @@ -2669,22 +2673,22 @@ "Arranque as pernas de Kor com um tiro, Jak!" ], "ds276": [ - "He's down, Jak! Hit him in the head!" + "Ele está baixo, Jack! Acerte-o na cabeça!" ], "ds277": [ - "Boot to the head, boot to the head!" + "Flanqueie na cabeça, flanqueie na cabeça!" ], "ds278": [ "Acho que devemos nos esconder em algum lugar!" ], "ds279": [ - "Take cover before he blows!" + "Proteja-se antes que ele sopre!" ], "ds280": [ - "Yeah, you got him good that time!" + "Ah! Nós o pegamos em cheio desta vez!" ], "ds281": [ - "Oh, man, now he's angry!" + "Oh! Cara, agora ele está zangado!" ], "ds282": [ "Pegue ele, Jak!" @@ -2696,35 +2700,35 @@ "Belo golpe, parceiro!" ], "ds285": [ - "That had to hurt him." + "Aquilo teve de machucá-lo." ], "ds286": [ - "You messed with the wrong heroes, buddy!" + "Você mexeu com os heróis errados, companheiro!" ], "ds287": [ - "Shoot him again, Jak!" + "Atire nele de novo, Jack!" ], "ds288": [ - "Jak, we're taking a beating!" + "Estamos levando uma surra!" ], "ds289": [ - "Stay away from the Dark Eco!" + "Fique longe do Eco Negro!" ], "ds302": [ - "We've almost got him, Jak!" + "Nós quase o pegamos, Jack!" ], "ds303": [ - "That's it! You did it!" + "É isso! Você conseguiu!" ], "ds305": [ - "Shoot the switch to change the coveyor belt's", - "direction!" + "Atire no interruptor para mudar a esteira de coveiro", + "direção!" ], "ds306": [ "Você precisa atirar no interruptor, Jak!" ], "ds307": [ - "Find the switch to change the conveyor's direction!" + "" ], "ds321": [ "Destrua as torres!" @@ -2733,7 +2737,7 @@ "Acerte as torres, Jak!" ], "ds323": [ - "Doin' some damage!" + "Causando algum dano!" ], "ds324": [ "Entre no Titã!" @@ -2742,58 +2746,58 @@ "Atire naquela nave!" ], "ds326": [ - "Yeah, that ship's feelin' it now!" + "" ], "ds327": [ - "Ooh, direct hits." + "Ohh, ataques diretos." ], "ds328": [ - "I think you hurt it that time!" + "Eu acho que você o machucou dessa vez!" ], "ds329": [ - "The ship's goin' down! You did it, Jak!" + "O navio está afundando! Você conseguiu, Jak!" ], "ds353": [ "Esse deve ser o míssil que o Torn quer que explodamos!" ], "ds354": [ - "Break those tubes in the center, Jak!" + "Quebre esses tubos no centro, Jack!" ], "ds372": [ - "Gotta ride the JET-Board on this one, Jak!" + "Tem que montar no JET-Board para esse, Jak!" ], "ds375": [ - "Look out for the ray!" + "Cuidado com o raio!" ], "ds378": [ - "We gotta break all the support cables!" + "Temos que quebrar todos os cabos de suporte!" ], "ds379": [ - "Grind on the support bases to break the cables." + "Vincule as bases de suporte para quebrar os cabos." ], "ds394": [ - "Spider! Spider! Huff... huff... I hate spiders!" + "Aranha! Aranha! Eu odeio aranhas!" ], "ds395": [ - "Gotta run, gotta run!" + "" ], "ds398": [ - "The first beam!" + "O primeiro feixe!" ], "ds399": [ - "The second beam! The door's opening!" + "O segundo feixe! A porta está se abrindo!" ], "ds404": [ - "There's Sig!" + "Tem Placa!" ], "ds405": [ - "Get the blocks to go into the slots, Jak!" + "Pegue os blocos para entrar nos espaços, Jak!" ], "ds406": [ - "Shoot or kick the blocks!" + "Atire ou chute os blocos!" ], "ds407": [ - "You have to get the blocks in the slots faster!" + "Você tem que pegar os blocos nos espaços mais rápido!" ], "ds408": [ "Corre, Jak!" @@ -2802,303 +2806,303 @@ "Continue se mexendo!" ], "ds410": [ - "We gotta stay ahead of that thing!" + "Nós temos que ficar à frente disso!" ], "ds439": [ - "Shoot all the Metal Head eggs, Jak!" + "Atire em todos os ovos Cabeça de Metal, Jak!" ], "ds440": [ - "We didn't get all those nasty eggs!" + "Não conseguimos todos aqueles ovos desagradáveis!" ], "ds441": [ - "We missed some Metal Head eggs!" + "" ], "ds461": [ - "We gotta jump onto the crate dangling from the crane!" + "Temos que pular na caixa pendurados do guindaste!" ], "ds462": [ - "Use your hoverboard on this path!" + "Use seu painel neste caminho!" ], "ds463": [ - "You can grind to cross those pipes using your", + "Você pode mover-se para atravessar esses tubos usando seu", "hoverboard!" ], "ds464": [ - "Ride the half-pipe to the end!" + "Monte na meia tubulação até o fim!" ], "ds466": [ - "You gotta drop a bomb into each well, Jak!" + "Você tem que soltar uma bomba em cada poço, Jak!" ], "ds467": [ - "Use the ramp to get high enough to drop the bomb in!" + "Use a rampa para ficar alta o suficiente para soltar a bomba!" ], "ds468": [ - "Gotta jump higher!" + "Tem que pular mais alto!" ], "ds469": [ - "Only a minute before we're toast, Jak!" + "Apenas um minuto antes de virarmos torradas, Jack!" ], "ds470": [ - "30 seconds left, then we go BOOM!" + "Restam 30 segundos, então vamos BOOM!" ], "ds471": [ - "Ten seconds left, Jak!" + "Faltam dez segundos, Jack!" ], "ds472": [ - "That's one well down, five to go!" + "" ], "ds473": [ - "Two wells are history, four left!" + "Dois poços viraram histórias, quatro restantes!" ], "ds474": [ - "Three wells cut, only three to go!" + "Três poços eliminados, apenas três restando!" ], "ds475": [ - "That's the fourth well, two bad boys left!" + "Este é o quarto poço, dois malandrinhos restantes!" ], "ds476": [ - "You got the fifth well, only one to go!" + "Você conseguiu o quinto poço, só resta um!" ], "ds477": [ - "You got 'em all, Jak!" + "Você os pegou, Jack!" ], "ds478": [ - "The last well is up where we rescued Vin!" + "O último poço está onde salvamos Vin!" ], "ds479": [ - "Now he's vulnerable!" + "Agora ele está vulnerável!\n" ], "ds480": [ - "Take him out!" + "Tire ele!" ], "ds481": [ - "Get him while he's vulnerable!" + "Pegue ele enquanto ele está vulnerável!" ], "ds482": [ - "Here he comes..." + "Aí vêm eles..." ], "ds483": [ - "How's it feel to have your pants down, Baron?" + "Como se sente com suas calças abaixadas, Baron?" ], "ds484": [ - "Shoot him, shoot him!" + "Atire nele, atire nele!" ], "ds485": [ - "Look out!" + "Cuidado!" ], "ds487": [ - "Easy, Jak, we gotta get this guy to safety!" + "Cuidado, Jack, temos que levar esse cara para um local seguro!" ], "ds488": [ - "We're takin' a lotta damage, buddy!" + "" ], "ds489": [ - "We're gettin' our butts kicked!" + "Nós estamos levando uma surra!" ], "ds490": [ - "Maybe I should drive..." + "Talvez eu deva dirigir..." ], "ds491": [ - "Let's go, wondergoon,", - "we'll take you to a safe place in the city!" + "Vamos lá, bandido-maravilha,", + "Te levaremos a um lugar seguro na cidade!" ], "ds492": [ - "Okay, ride's over, out you go!" + "Tudo bem, a corrida acabou, lá fora!" ], "ds493": [ - "All aboard the Underground railroad!", - "Next stop: Your new safehouse!" + "Tudo a bordo da ferrovia subterrânea!", + "Próxima parada: Sua nova casa segura!" ], "ds494": [ - "I believe this is your stop!" + "Creio que esta é a sua parada!" ], "ds495": [ - "Daxter's Freedom Fighter Taxi Service!", - "Hurry up, buddy, we ain't got all day." + "", + "Apresse-se, companheiro, não temos o dia todo." ], "ds496": [ - "Home free, baby!", - "Don't forget to tell Torn how well we did!" + "Casa livre, bebê!", + "Não se esqueça de dizer a Torn o quão bem nós conseguimos!" ], "ds497": [ - "You looking for a lift, fighter boy?" + "Procurando por uma carona, lutador?" ], "ds498": [ - "Okay, this is where you get off. So... get off." + "Ok, é aqui que você vai embora. Então... sai." ], "ds499": [ - "We did it, Jak!", - "We got all the fighters to the new safehouses!" + "Nós o fizemos, Jak!", + "Levemos todos os lutadores para as novas casas de segurança!" ], "ds500": [ - "Statues are becoming an endangered species around here." + "Estátuas estão se tornando uma espécie perigosa por aqui." ], "ds501": [ - "I got us a talkbox.", - "The city people use these things to communicate", - "with each other." + "Consegui uma caixa de voz pra nós.", + "O povo da cidade usa essas coisas para se comunicar", + "Entre si." ], "ds502": [ - "Let's go see Onin and her crazy monkey bird." + "Vamos ver Onin e seu pássaro macaco maluco." ], "ds503": [ "Acho que precisamos voltar para a cidade, Jak." ], "dsek001": [ - "Kid! Stay with him, Jak!" + "Garoto! Fique com ele, Jak!" ], "dsek002": [ - "Catch up to them, Jak!" + "" ], "dsek003": [ - "Where'd they go?!" + "Para onde eles foram?!" ], "dsek004": [ - "There they go again!" + "Aí vão eles outra vez!" ], "dsek005": [ - "Uh oh, here comes trouble!" + "Uh oh, aqui vem problemas!" ], "dsek006": [ "Mais guardas!?" ], "dsek007": [ - "Kid, please! You're killin' me!" + "Criança, por favor! Você está matando!" ], "dsek008": [ - "Here, poochie, poochie..." + "Aqui, cãozinho, cãozinho..." ], "dsek009": [ - "There goes that crazy crocadog again...!" + "E lá vai aquele cãodilo maluco de novo...!" ], "dsek010": [ - "Chase after the Kid!" + "Vão atrás do garoto!" ], "dsek011": [ - "Keep up with the Kid!" + "Acompanhem o garoto!" ], "dsek012": [ - "Crocadog!" + "Cãodilo!" ], "dsek013": [ - "Phew, finally... let's get these two to Kor!" + "Ufa, finalmente... vamos levar aqueles dois para Kor!" ], "ero001": [ - "Out of my way!" + "Saia do meu caminho!" ], "ero002": [ - "I own this track!" + "Eu possuo esse caminho!" ], "ero003": [ - "Give it up, eco freak!" + "Desista, aberração ecológica!" ], "ero004": [ - "Payback time." + "Hora do retorno." ], "ero005": [ - "Let's make this interesting!" + "Vamos tornar isso interessante!" ], "ero006": [ - "Eat wall!" + "Coma parede!" ], "ero007": [ - "Time to die!" + "Hora de morrer!" ], "ero008": [ - "Move over!" + "Saia da frente!" ], "ero009": [ - "Catch me now, loser!" + "Pegue-me agora, perdedor!" ], "ero010": [ - "I'm too fast for you!" + "Eu sou muito rápido para você!" ], "ero011": [ - "Now you're racing with the big boys!" + "Agora você está correndo com os grandes!" ], "ero012": [ - "Here's one for the Baron." + "Aqui vai uma para Barão." ], "ero013": [ - "Take this!" + "Toma essa!" ], "ero014": [ - "You're making this too easy!" + "Você está tornando isto muito fácil!" ], "ero015": [ - "Hahaha, bye bye!" + "Hahaha, tchauzinho!" ], "ero016": [ - "You want some?" + "Você quer um pouco?" ], "ero017": [ - "Now you see why I never lose." + "Agora você vê por que eu nunca perco." ], "ero018": [ - "The crowd loves me!" + "A multidão me ama!" ], "ero019": [ "Ahh!" ], "ero020": [ - "Here's some pain!" + "Aqui está um pouco de dor!" ], "ero021": [ - "Try to erase these!" + "Tente apagar estes!" ], "ero022": [ - "How's your reflexes?" + "Como estão seus reflexos?" ], "ero023": [ - "Too much for you?!" + "Muito para você?" ], "ero024": [ - "Had enough?" + "Obteve o suficiente?" ], "ero025": [ - "Avoid this, smart-ass!" + "Evite isso, espertinho!" ], "ero026": [ - "Say goodnight, eco freak!" + "Diga boa noite, aberração ecológica!" ], "ero027": [ - "You can't beat me!" + "Você não pode me ferir!" ], "ero028": [ - "I'd die before I let you win!" + "Eu morreria antes de deixar você ganhar!" ], "ero029": [ - "This will be your last lap." + "Essa vai ser sua última volta." ], "ero030": [ - "Crash and burn!" + "Queime e se destrua!" ], "ero031": [ - "To the end!" + "Até o fim!" ], "ero032": [ - "Last lap to live!" + "Última volta para viver!" ], "ero033": [ - "Now we end this!" + "Agora acabamos com isso!" ], "ero034": [ - "You won't see the finish line!" + "Você não verá a linha de chegada!" ], "ero035": [ - "DIE!" + "Morra!" ], "ero036": [ - "Die!" + "Morra!" ], "ero037": [ "Hahahaha!" ], "ero038": [ - "YEAH!" + "Sim!" ], "ero039": [ - "HA!" + "AHÁ!" ], "ero040": [ "NÃO!" @@ -3113,10 +3117,10 @@ "E lá vamos nós." ], "ero044": [ - "See you later." + "Te vejo depois." ], "ero045": [ - "Fool! You cannot defeat me." + "Tolo! Você não pode me derrotar." ], "ero046": [ "Você perdeu uma argola." @@ -3137,13 +3141,13 @@ "Bela tentativa." ], "ero052": [ - "Move over!" + "Sai da frente!" ], "ero053": [ "Saia do meu caminho!" ], "ero054": [ - "Coming through!" + "Passando!" ], "ero055": [ "Tchauzinho!" @@ -3152,13 +3156,13 @@ "Aqui estou eu!" ], "ero057": [ - "Get used to watching my back!" + "Acostume-se a olhar pras minhas costas!" ], "ero058": [ - "This is my city, eco freak." + "Essa é minha cidade, aberração ecológica." ], "ero059": [ - "Looking sloppy, Jak." + "Meio desleixado, Jak." ], "ero060": [ "Desista!" @@ -3221,53 +3225,53 @@ "Oof!" ], "ero080": [ - "Beat it, freak!" + "Cai fora, aberração!" ], "ero081": [ - "Care to get back in the chair?" + "Se importa de voltar pra cadeira?" ], "ero082": [ - "This race was too easy." + "Essa corrida foi muito fácil." ], "ero083": [ - "It was easier than I thought to beat you." + "Te superar foi mais fácil do que pensei." ], "ero084": [ - "Not even close, Keira's betting on the wrong man." + "Nem um pouco perto, Keira está apostando no cara errado." ], "ero085": [ - "Loser! You disgust me!" + "Perdedor! Você me envergonha!" ], "ero086": [ - "You see Jak, I win, and I get what I want.", - "Someday I will be Baron, then the city will really pay!" + "Viu Jak, eu ganhei, e eu consigo o que eu quero.", + "Um dia serei o Barão, então a cidade vai realmente pagar" ], "ero087": [ - "I should have known you'd be no match." + "Eu deveria saber que você não seria pário." ], "ero088": [ - "I win, Keira's going to love me!" + "Eu ganho, Keira vai me amar!" ], "ero089": [ - "Maybe you should go back to wherever you came from." + "Talvez você devesse voltar para onde você viesse." ], "ero090": [ - "I'll get a victory kiss from Keira later." + "Eu vou receber um beijo vitorioso de Keira depois." ], "ero091": [ - "Again I prove my superiority." + "" ], "ero092": [ - "You see? You are no match for me." + "Consegue perceber? Você não é páreo para mim." ], "ero093": [ - "Too bad, I win!" + "Que pena, eu ganhei!" ], "ero094": [ - "Hahahaha, pathetic insect, I win!" + "Hahaha, inseto patético, eu ganhei!" ], "ero095": [ - "You can never defeat me!" + "Você nunca vai conseguir me derrotar!" ], "ero096": [ "Ahhh!...ahh." @@ -3288,7 +3292,7 @@ "AUGHH!" ], "ero102": [ - "OW!" + "AI!" ], "ero103": [ "DAHHH!" @@ -3297,322 +3301,322 @@ "DAUGHH!" ], "erol001": [ - "I'm looking for you, eco freak,", - "and when I find you, you'll wish you died in prison." + "Estou te procurando, aberração ecológica,", + "E quando eu te encontrar, você desejará ter morrido na prisão." ], "erol002": [ - "This is Erol. Looks like you're running out of friends.", - "We've arrested them all and thrown them into your", - "favorite prison. By the way, that blonde girl Tess", - "screamed so delightfully when she was arrested.", - "I can't wait for her turn in the chair.", + "Aqui é Erol. Parece que eu estou ficando sem amigos.", + "Nós os prendemos todos e os jogamos no seu", + "Prisão favorita. A propósito, aquela garota loira, Tess", + "Gritou com tanta alegria quando foi presa.", + "Mal posso esperar pela vez dela na cadeira.", "Hahahahaha...." ], "erol003": [ - "This is Erol. Just remember, the only reason I'm letting you", - "walk is so I can face you in the championship race!" + "Aqui é Erol. Apenas lembre-se, a única razão que estou te deixando", + "andar é para que eu consiga te encarar na corrida do campeonato!" ], "hal001": [ - "Quiet! Here comes pretty boy." + "Calada! Está chegando o garoto bonito." ], "hal002": [ - "'Bout time you showed up. Okay, let's do this." + "Já era hora de você aparecer. OK, vamos lá." ], "hal003": [ - "Krew said you'll protect us all the way to the statue." + "Krew disse que você iria nos proteger até a estátua." ], "hal004": [ - "We go down!" + "Nós vamos descer!" ], "hal006": [ - "This way!" + "Por aqui!" ], "hal007": [ - "AHH! It's a Metal Head! Shoot it, shoot it!" + "AHH! É uma Cabeça de Metal! Atira, atira!" ], "hal008": [ - "Stay with us!" + "Fique conosco!" ], "hal009": [ - "Man, Krew's gonna be pissed if you mess this up." + "Cara, Krew vai ficar irritado se você estragar isso." ], "hal010": [ - "Don't leave us to die!" + "Não nos deixe morrer!" ], "hal011": [ - "You ditch us and Krew's gonna mess you up!" + "Você nos abandonou e Krew vai acabar com você!" ], "hal012": [ - "We need to stay together." + "Nós precisamos ficar juntos." ], "hal013": [ - "I thought this guy was supposed to be protecting us!" + "Pensei que esse cara deveria estar nos protegendo!" ], "hal014": [ - "That's it! We're calling the mission off,", - "we don't go until you're serious." + "É isso! Estamos cancelando a missão,", + "nós não iremos até você estar sério." ], "hal015": [ - "I'm not getting killed because of this loser,", - "this mission is over." + "Não vou ser morto por causa desse perdedor,", + "a missão acabou." ], "hal019": [ - "Let's go back before we all get killed." + "Vamos voltar antes que todos nós morremos." ], "hal020": [ - "Ugh, this place stinks." + "Ugh, esse lugar fede." ], "hal021": [ - "I got a bad feeling about this place." + "Estou com um mau pressentimento sobre esse lugar." ], "hal022": [ "Uh oh, acho que me molhei." ], "hal023": [ - "No! Please!" + "Não! Por favor!" ], "hal024": [ - "I wanna go home." + "Eu quero ir para casa." ], "hal025": [ - "Uhh, I'm hearing things." + "Uh! Estou ouvindo coisas." ], "hal026": [ - "Let's go back." + "Vamos voltar." ], "hal027": [ - "Move your butts, or I'll move 'em for ya!" + "Mova sua bunda, ou eu vou movê-la para você!" ], "hal028": [ - "This job beats being a garbage man." + "Este trabalho supera ser um lixeiro." ], "hal029": [ - "Ain't the smell of sulphur grand?" + "Não é cheiro do enxofre?" ], "hal030": [ - "Cover your ears!" + "Cubra suas orelhas!" ], "hal031": [ - "I love this job." + "Eu amo este trabalho." ], "hal032": [ - "Great, now we're trapped in this slime pit!" + "Ótimo, agora estamos presos nessa gosma!" ], "hal033": [ - "Shoot, baby, shoot!" + "Atira, bebê, atira!" ], "hal034": [ - "Ahh! The ceiling's crawling!" + "Ahh! O teto está rastejando!" ], "hal035": [ - "I can't get away!" + "Não consigo escapar!" ], "hal036": [ - "There's one coming right at me!" + "Há um vindo bem em mim!" ], "hal037": [ - "It sees me!" + "" ], "hal038": [ - "Ahh! Stay away!" + "Ahh! Fique longe!" ], "hal039": [ - "It's hitting me!" + "Está me batendo!" ], "hal040": [ - "Gahh, I'm gonna die here!" + "Gahh, eu vou morrer aqui!" ], "hal041": [ - "I'm getting zapped!" + "Estou sumindo!" ], "hal042": [ - "This'll be the end of me!" + "Este será o meu fim!" ], "hal043": [ - "Help me! I've got eight kids to feed!" + "Me ajude! Tenho oito crianças para alimentar!" ], "hal044": [ - "Nice work, those were some nasty Metal Heads." + "Bom trabalho, essas foram algumas Cabeças de Metal desagradáveis." ], "hal045": [ - "There you are, why don't you make yourself useful?" + "Aí está você, por que não se faz útil?" ], "hal046": [ - "Keep moving!" + "Continue andando!" ], "hal047": [ - "On we go, we're not getting any younger." + "Aqui vamos nós, não estamos ficando mais novos." ], "hal048": [ - "Ahh! They're crawling down the walls!" + "Ah! Eles estão arrastando pelas paredes!" ], "hal049": [ - "Way to go, this is where I come in." + "" ], "hal050": [ - "You mean cover your ass! Fire in the hole!" + "Você quer dizer cubra seu furico! Fogo no buraco!" ], "hal051": [ - "You better keep your head down, sugar." + "É melhor manter a cabeça no chão, querido." ], "hal052": [ - "Your bad breath, let's move." + "Seu mau hálito, vamos continuar." ], "hal053": [ - "That straightened your hair, huh?", - "Hehe, next time you'll listen to me. Okay, let's move." + "Isso endireitou o seu cabelo, hein?", + "" ], "hal054": [ - "Oof, that had to hurt.", - "I told you to keep back, but no one ever listens to Jinx." + "Ui, essa tinha que machucar.", + "Eu te disse para ficar atrás, mas ninguém jamais escuta Jinx." ], "hal055": [ - "More of those monsters!" + "Mais desses monstros!" ], "hal056": [ - "So what, we got a dream team here. Do your stuff, Jak!" + "E daí? Conseguimos um time de sonhos aqui. Faça as suas coisas, Jack!" ], "hal057": [ - "Jak! Get your butt up here and do your thing." + "Jak! Venha aqui e faça seu trabalho." ], "hal058": [ - "Take 'em out, blue boy." + "Acabe com eles, garoto azul." ], "hal059": [ - "You're pretty handy with that iron, blondie." + "Você é bem habilidoso com esse ferro, loirinho." ], "hal060": [ - "Shut up, Mog." + "Calado, Mog." ], "hal061": [ - "Here they come again!" + "" ], "hal062": [ - "Get up here and earn your keep!" + "Venha aqui e ganhe o seu sustento!" ], "hal063": [ - "Krew was right about you. You got the magic, man." + "Krew estava certo sobre você. Você conseguiu a magia, cara." ], "hal064": [ - "Nice fighting, man, I'm beginning to like you." + "Bela briga, cara, estou começando a gostar de você." ], "hal065": [ - "Okay... that doesn't look good. Jak, you're up!" + "OK... isso não parece bom. Jak, agora é com você!" ], "hal066": [ - "Wow! Beams of death!", - "I'm staying right here 'til you do something about that." + "Uau! Feixes da morte!", + "Vou ficar aqui mesmo até você faz algo a respeito disso." ], "hal067": [ - "Uhhh, Jak. I think you're the man for this job." + "Uh! Jack. Acho que você é o homem para este trabalho." ], "hal068": [ - "Jump the beams, Jak." + "Pule os feixes, Jak." ], "hal069": [ - "Nice moves." + "Belos movimentos." ], "hal070": [ - "Yeah... you wish, tubby." + "" ], "hal071": [ - "We're staying put 'til you take out those Metal Heads." + "Ficaremos parados até você lidar com esses Cabeças de Metal." ], "hal072": [ - "Sweet as a ballerina, hehehehe..." + "Doce como uma bailarina, hehehehe..." ], "hal073": [ - "Knock 'em silly, Jak!" + "Dá cabo deles, Jak!" ], "hal074": [ - "This one's gonna be loud!" + "Essa vai ser alta!" ], "hal075": [ - "This is too easy." + "Isso é fácil demais." ], "hal080": [ - "We ain't moving, 'til you kill 'em all!" + "Não vamos nos mexer até você matar todos eles!" ], "hal081": [ - "OK, let's get out of here before more come back." + "OK, vamos sair daqui antes que voltem mais." ], "hal082": [ - "You're earning your dough today. Let's finish this!" + "Você ganhará sua massa hoje. Vamos terminar isso!" ], "hal083": [ "Estou impressionado, Jak. Vou dar uma boa palavra ao chefe." ], "hal084": [ - "Yeah, do it, Jinx." + "Sim. Termine, Jinx." ], "hal085": [ - "Man, Jinx, what'd you put in those boomsticks?" + "Cara. Jinx, o que você colocou nessas bengalas?" ], "hal086": [ - "Look at him go." + "" ], "hal087": [ - "I could jump like that." + "Eu poderia pular assim." ], "hal088": [ - "Get away from me, you crazy monster!" + "Sai de perto de mim, seu monstro louco!" ], "hal090": [ - "This is where I come in, cover your ears." + "É aqui que eu entro, tapem seus ouvidos." ], "hal091": [ - "Fire in the hole!" + "Fogo no buraco!" ], "hal092": [ - "And on we go." + "E lá vamos nós." ], "hal093": [ - "Please, allow me." + "Por favor, permita-me." ], "hal094": [ - "One unclogged sewer, comin' up." + "Um esgoto desentupido saindo." ], "hal095": [ - "This is my boomshtick!" + "Esse truque é meu!" ], "hal096": [ - "Boom, baby!" + "Boom, bebê!" ], "hal097": [ - "We're clear, let's move." + "Estamos limpos, vamos indo." ], "hal101": [ - "Ahh! That's gonna leave a mark." + "Ahh! Isso vai deixar uma marca." ], "hal102": [ - "Die! A little help would be good!" + "Morra! Uma ajudinha seria boa!" ], "hal103": [ - "Watch it, pretty boy, or I'll rearrange your face." + "Cuidado, gatinho, ou eu reorganizarei seu rosto." ], "hal104": [ - "You got an itchy trigger finger." + "Você pegou um dedo coçando no gatilho." ], "hal107": [ - "Piece of cake." + "Moleza." ], "hal108": [ - "Get over here, Jak!" + "Venha cá, Jak!" ], "hal109": [ - "Stay close, pretty boy!" + "Fique perto, gatinho!" ], "hal111": [ - "Keep with us, tough guy!" + "Fique conosco, casca-grossa!" ], "hal112": [ - "You're in the way, Jak, move!" + "Você está no caminho, Jak, mova-se!" ], "hal113": [ - "I wouldn't stand there if I were you!" + "Eu não ficaria ali se fosse você!" ], "hal114": [ - "This is gonna be loud." + "Essa vai ser alta." ], "hal115": [ "Oh!" @@ -3621,101 +3625,101 @@ "Oh!" ], "hal117": [ - "Hey!" + "Ei!" ], "hal118": [ - "It's a trap!" + "É uma armadilha!" ], "hal119": [ - "Yeah, why did we sign up for this?" + "É, por que nos inscrevemos para isso?" ], "hal120": [ - "I got 30 keys of high explosives strapped to my back...", - "Great..." + "Tenho 30 códigos de altos explosivos presas nas minhas costas...", + "Ótimo..." ], "hal121": [ - "Just shut your whiny traps and keep moving." + "Apenas parem de reclamar e continuem andando." ], "hal122": [ - "Uh, do we have to?" + "Um, nós precisamos?" ], "hal123": [ - "Uhh, did you hear that?" + "Uhh, você escutou?" ], "hal124": [ - "We are so dead, man." + "Estamos tão mortos, cara." ], "hal125": [ - "Shut up! I'll go ahead and check it out..." + "Calado! Vou na frente e conferir..." ], "hal126": [ - "Man, that thing's ugly." + "Cara, aquela coisa é feia." ], "hal127": [ - "Get him, man, before he gets us." + "Pega ele, cara, antes dele nos pegar." ], "hal128": [ - "They're coming up from behind, too!" + "Eles estão vindo por trás também!" ], "hal129": [ - "Jak's my hero." + "Jak é meu herói." ], "hal130": [ - "Sounds like I got gas." + "Parece que eu tenho energia." ], "hal131": [ - "I hate Krew." + "I odeio Krew." ], "hal132": [ - "I'm sure not going back that way!" + "Com certeza não volto pra aquele lugar!" ], "hal133": [ - "It's coming for me!" + "Está vindo por mim!" ], "hal134": [ - "I think it wants me!" + "Eu acho que me quer!" ], "hal135": [ - "Help me, Jak!" + "Me ajude, Jak!" ], "hal136": [ - "I'm gonna die!" + "Eu vou morrer!" ], "hal137": [ - "It got me!" + "Me pegou!" ], "hal138": [ - "Jak! Save me!" + "Jak! Me salve!" ], "hal139": [ - "Ughh! It got me!" + "Ughh! Me pegou!" ], "hal140": [ - "Oughh! That beam smarts." + "Oughh! Esse feixe é inteligente." ], "hal141": [ - "I've been shot!" + "Fui atirado!" ], "hal142": [ - "I'm hit!" + "Estou atingido!" ], "hal143": [ "Ughh!" ], "hal144": [ - "Ughh! Help me!" + "Ughh! Me ajude!" ], "hal145": [ - "Hey man, watch it!" + "Ei cara, cuidado!" ], "hal146": [ - "Ohh, hit me again and I'll pound you!" + "Ohh, me acerte de novo e eu te dou uma pancada!" ], "hal147": [ - "Nobody's my friend..." + "Ninguém é meu amigo..." ], "hal148": [ - "Oof!" + "Ufa!" ], "hal149": [ "Uh!" @@ -3724,28 +3728,28 @@ "Ahh!" ], "hal151": [ - "He's got me!" + "Ele me pegou!" ], "hal152": [ - "Gahh!! Not again!" + "Ahh!! De novo não!" ], "hal153": [ - "I'm dying!" + "Estou morrendo!" ], "hal154": [ - "Any more like that, then I'm history." + "Mais um daquele jeito e eu viro história." ], "hal155": [ - "I'm getting shot!" + "Estou levando tiro!" ], "hal156": [ - "Sure! Why don't you kill me too?" + "Claro! Por que você não me mata também?" ], "hal157": [ - "Check your targets, wimp boy!" + "Confira seus alvos, garoto fracote!" ], "hal158": [ - "Shoot the shine-heads, not me!" + "Atire nos cabeças-brilhantes, não em mim!" ], "hal159": [ "Ahh!" @@ -3763,76 +3767,76 @@ "Ah!" ], "hal165": [ - "Look out!" + "Cuidado!" ], "hal166": [ - "We're not doing this with a rookie, I'm calling this off!" + "Estamos fazendo isso com um novato, estou cancelando!" ], "hal167": [ - "That's it, we're done! Come back when you're serious." + "É isso, nós acabamos! Volte quando estiver a sério." ], "hal168": [ - "I'm cornered!" + "Estou encurralado!" ], "hal169": [ - "It's gonna shoot me!" + "Ele vai atirar em mim!" ], "hal170": [ - "Jak! Do something!" + "Bate! Faça alguma coisa!" ], "hal171": [ - "Ahh! It got me!" + "Ahh! Me pegou!" ], "hal172": [ - "No no no! Help!" + "Não não não! Socorro!" ], "hal173": [ - "They're getting too close, Jak!" + "Eles estão chegando muito perto, Jak!" ], "hal174": [ - "It's gonna get me!" + "Ele vai me pegar!" ], "hal175": [ - "I'm getting killed here!" + "Eu vou ser morto aqui!" ], "hal176": [ - "Jak! I'm about to be metal meat!" + "Jak! Eu estou prestes a ser carne de metal!" ], "hal177": [ - "Aghh! That beam burns!" + "Aghh! Esse feixe queima!" ], "hal178": [ - "It's shooting me!" + "Tá atirando em mim!" ], "hal179": [ - "Watch out for the beam!" + "Cuidado com o feixe!" ], "hal180": [ - "I'm shot!" + "Estou atingido!" ], "hal181": [ - "I'm trapped!" + "Estou preso!" ], "hal182": [ - "Get back... I'm gonna detonate this one remotely." + "Voltar... Eu vou detonar esse remotamente." ], "hal183": [ "He-hah!" ], "hal184": [ - "Alright!" + "Certo!" ], "hal185": [ - "Let's go!" + "Vamos lá!" ], "hal186": [ - "Move it!" + "Movam!" ], "hal187": [ - "That's a lot of Metal Heads." + "São muitas Cabeças de Metal." ], "hal188": [ - "Oof!" + "Ufa!" ], "hal189": [ "Daghh!" @@ -3841,94 +3845,94 @@ "Oughh..." ], "hal191": [ - "Krew's dead for getting me into this!" + "Krew está ferrado por me enfiar nisso!" ], "jak001": [ - "Alright!" + "Certo!" ], "jak002": [ - "Yeah!" + "Isso!" ], "jak003": [ "Wooo!" ], "jak004": [ - "Here we go!" + "E lá vamos nós!" ], "jak005": [ - "Nice!" + "Ótimo!" ], "jak006": [ "Rock 'n roll!" ], "jak007": [ - "Right on!" + "Certo!" ], "jak008": [ - "Cool!" + "Legal!" ], "jak009": [ - "Cool!" + "Legal!" ], "jak010": [ - "Oh, yeah!" + "Ahh, isso!" ], "jak011": [ - "Comin' through!" + "Passando!" ], "jak012": [ - "Look out!" + "Cuidado!" ], "jak013": [ - "Last lap!" + "Última volta!" ], "jak014": [ - "Watch out!" + "Preste atenção!" ], "jak015": [ - "Whoa!" + "Epa!" ], "jak016": [ - "Whoa!" + "Epa!" ], "jak017": [ - "Hold on, Dax!" + "Espera aí, Dax!" ], "jak018": [ - "Hang on, Dax!" + "Segura aí, Dax!" ], "jak020": [ - "Whoa... boy that was close." + "Uau... cara essa foi perto." ], "jak021": [ - "No!" + "Não!" ], "jak022": [ - "Not this time." + "Não desta vez." ], "jak023": [ "Huargh!" ], "jak024": [ - "Lean, baby, lean!" + "Curve-se, bebê, curve-se!" ], "jak025": [ - "Catch him on the inside!" + "Pegue-o por dentro!" ], "jak026": [ - "This is MY show!" + "Este é o MEU show!" ], "jak027": [ - "Haha, we got him!" + "Boa, nós o pegamos!" ], "jak028": [ - "Watch out!" + "Preste atenção!" ], "jak029": [ - "You're dead, Erol!" + "Você está morto, Erol!" ], "jak030": [ - "See ya!" + "Até mais!" ], "jak031": [ "Haha!" @@ -3937,218 +3941,218 @@ "Wooo!" ], "jak033": [ - "Last lap!" + "Última volta!" ], "jak034": [ - "Later." + "Mais tarde." ], "jak035": [ - "We gotta catch up!" + "Precisamos alcançar!" ], "jak036": [ - "There he is!" + "Aí está ele!" ], "jak037": [ - "Come on, baby, show me what you got!" + "Vamos, bebê, me mostre o que você tem!" ], "jak038": [ - "Here we go!" + "E lá vamos nós!" ], "jak039": [ "Urgh!" ], "jak040": [ - "I'll take this." + "Vou pegar isto." ], "jak041": [ - "I need to borrow this." + "Eu preciso pegar isso emprestado." ], "jak042": [ - "Move over, buddy!" + "Passa pra lá, amigão!" ], "jak044": [ - "Outta the vehicle!" + "Pare o veículo!" ], "jak045": [ - "Outta my way, buddy!" + "Fora meu caminho, amigão!" ], "jak046": [ - "Thanks for the lift." + "Obrigado pela carona." ], "jak047": [ - "Mind if I drive?" + "Se importa se eu dirigir?" ], "jak048": [ - "I like the color of this vehicle." + "Eu gosto da cor deste veículo." ], "jak049": [ - "Mine now." + "Minere agora." ], "jak050": [ - "'Scuse me, but I need this." + "Com licença, mas preciso disto." ], "jak051": [ - "Take a hike, buddy!" + "Faça uma caminhada, amigão!" ], "jak052": [ - "Try walking." + "Tente andar." ], "jak053": [ - "Sorry, but I'm in a hurry!" + "Desculpe, mas estou com pressa!" ], "jak054": [ - "Gotta go!" + "Tenho que ir!" ], "jak055": [ - "Get another vehicle!" + "Pegue outro veículo!" ], "jak056": [ - "Road hog!" + "Porco de estrada!" ], "jak057": [ - "Brake yourself!" + "Não se aproveite!" ], "jak059": [ - "Haha, you want some?" + "Haha, você quer um pouco?" ], "jak060": [ - "Get some!" + "Pegar alguns!" ], "jak061": [ - "Yeah, feel it!" + "Sim, sinta!" ], "jak062": [ - "Die!" + "Morra!" ], "jak063": [ - "Badass comin' through!" + "Bonzão passando!" ], "jak064": [ - "Be afraid. Be very afraid." + "Tenha medo. Tenha muito medo." ], "jak065": [ - "Oooh, that's gotta hurt." + "Oh! Isso deve doer." ], "jak066": [ - "This is payback." + "Isto é retorno." ], "jak067": [ - "DIE, Praxis!" + "MORRA, Praxis!" ], "jak068": [ - "You're finished, Kor!" + "Você está acabado, Kor!" ], "jak069": [ - "This is my town, Kor!" + "Essa é minha cidade, Kor!" ], "jak070": [ - "Surprise... you can't kill me in my dark form." + "Surpresa... você não pode me matar na minha forma escura." ], "jak071": [ - "Now you pay!" + "Agora você paga!" ], "jak072": [ - "Go back to the past, Kor! 'Cause you're history." + "Volte para o passado, Kor! Porque você é história." ], "jak073": [ - "I win." + "Eu ganho." ], "jak074": [ - "You should have killed me when you had the chance, Praxis." + "Você deveria ter me matado quando teve chance, Praxis." ], "jak075": [ - "Daxter, just shut up and watch my back." + "Daxter, só cala a boca e me cobre." ], "jak076": [ - "Whatever, Daxter." + "Tanto faz, Daxter." ], "jak077": [ - "Will you stop yappin'?" + "Você vai parar de tagarelar?" ], "jak078": [ - "When you got smaller, so did your brain." + "Quando você ficou menor, o mesmo aconteceu com seu cérebro." ], "jak079": [ - "You're on MY shoulder. YOU'RE the sidekick." + "Você está no MEU ombro. VOCÊ é o mascote." ], "jak080": [ - "As long as you're on MY shoulder, keep your mouth shut." + "Enquanto você esteja no MEU ombro, mantenha a boca fechada." ], "jd001": [ - "Hey, kid! Wait! Come back!", - "We gotta protect him!" + "Ei, criança! Espere! Volte!", + "Temos de protegê-lo!" ], "jk001": [ - "Wait, KID!" + "Espera, GAROTO!" ], "jk002": [ - "There he goes!" + "Aí está ele!" ], "jk003": [ - "Leave him alone!" + "Deixe ele em paz!" ], "jk004": [ - "KID!" + "GAROTO!" ], "jk005": [ - "Pick on someone your own size!" + "Escolha alguém do seu tamanho!" ], "jk006": [ - "Kid, look out!" + "Criança, cuidado!" ], "jk007": [ - "How do YOU like it when somebody fights back?" + "Você gosta quando alguém briga de volta?" ], "jk008": [ - "Leave the kid alone!" + "Deixe a criança em paz!" ], "jk009": [ - "He's just a kid!" + "Ele é apenas uma criança!" ], "jk010": [ - "Keep away from him!" + "Fique longe dele!" ], "jk011": [ - "Now you've pissed me off!" + "Agora vocês me irritaram!" ], "jk012": [ - "Eat this!" + "Coma isso!" ], "jk013": [ - "Back off!" + "Para trás!" ], "jk014": [ - "We gotta get in the vehicle with the Kid!" + "Temos que entrar no veículo com a criança!" ], "jk015": [ - "Hold on!" + "Espere aí!" ], "jk016": [ - "Keep your head down, Kid!" + "Mantenha a cabeça abaixada criança!" ], "jk017": [ - "Stick with me, Kid, and you'll be safe." + "Fique comigo, ciança, e você estará seguro." ], "jk018": [ - "Stay with me, Kid!" + "Fique comigo, criança!" ], "jk019": [ - "Get in the vehicle, Dax!" + "Entre no veículo, Dax!" ], "kei001": [ - "You can get on and off the JET-Board at any time." + "Você pode entrar e sair do JET-Board a qualquer momento." ], "kei002": [ - "You can jump on your JET-Board!" + "Você pode pular no seu JET-Board!" ], "kei003": [ "Pule naquela plataforma." ], "kei004": [ - "Try jumping up on that crate." + "Tente pular naquela rampa." ], "kei005": [ - "Jump over that obstacle." + "Pule sobre aquele obstáculo." ], "kei006": [ "Você saltar mais alto se agachar antes de pular!" @@ -4157,80 +4161,80 @@ "Tente fazer um salto agachado sobre aquele obstáculo." ], "kei008": [ - "Jump and jump again a little after you've landed", - "for an even bigger launch!" + "Pule e pule novamente um pouco depois que você aterrissou", + "para um lançamento ainda maior!" ], "kei009": [ "Tente subir naquela plataforma alta com um salto de impulso!" ], "kei010": [ - "You can spin in the air!" + "Você pode girar no ar!" ], "kei011": [ - "Land a perfect 360 for a speed boost!" + "Tente um 360 perfeito para um aumento de velocidade!" ], "kei012": [ - "Nice spin!" + "Belo giro!" ], "kei013": [ - "You can land on a rail and grind across it." + "Voce pode aterrissar num trilho e atravessá-lo." ], "kei014": [ - "Try grinding on that rail." + "Tente esmague naquele trilho." ], "kei016": [ - "You can do flips while you jump!" + "Você pode fazer giros enquanto pula!" ], "kei017": [ - "You can also do tricks for fun." + "Você também pode fazer truques por diversão." ], "kei018": [ - "Try to put a number of moves together to get points." + "Tente juntar uma série de movimentos para obter pontos." ], "kei019": [ - "Get enough points to win the challenge!" + "Obtenha pontos suficientes para vencer o desafio!" ], "kei020": [ - "Not enough points! Work on your moves." + "Pontos insuficientes! Trabalhe em seus movimentos." ], "kei021": [ - "Good job!" + "Bom trabalho!" ], "kei022": [ - "Close, but not quite there." + "Perto, mas não muito ali." ], "kei023": [ - "Try again." + "Tentar novamente." ], "kei024": [ - "A little more work and you just might win!" + "Um pouco mais de trabalho e você pode ganhar!" ], "kei025": [ - "No good! Not enough points." + "Nada bem! Não há pontos suficientes." ], "kei026": [ - "The Underground said you needed some help,", - "you won't be able to catch those Metal Heads in the", - "Forest on foot so I've left my JET-Board at the airlock", - "near the city exit. Since you're helping the Underground,", - "I'll even let you keep it!" + "O Subterrâneo disse que você precisava de alguma ajuda,", + "você não conseguirá pegar aquelas Cabeças de Metal na", + "Floresta a pé, então eu deixei o meu JET-Board no Airlock", + "Perto da saída da cidade. Como você está ajudando o Subterrâneo", + "Vou até deixar você ficar com isso!" ], "kei027": [ - "Jak, this is Keira. Don't forget - I still need two artifacts", - "to make the Rift Rider work! I need the Time Map and the", - "Heart of Mar Energy Gem, or we're not going anywhere!" + "Jack, isso é Keira. Não se esqueça - eu ainda preciso de dois artefatos", + "Para fazer o Cavaleiro da Fenda funcionar! Eu preciso do Mapa de Tempo e da", + "Gema Energética do Coração de Mar, ou não iremos a lugar algum!" ], "kei028": [ - "I still need those two artifacts or this pile of junk", - "won't move one city block, much less through the Rift", - "and back to our own time!", - "You've got to find the Heart of Mar and the Time Map", - "or we're stuck!" + "Eu ainda preciso desses dois artefatos ou esta pilha de lixo", + "Não moverá um bloco da cidade, muito menos pela Fenda", + "E voltemos ao nosso próprio tempo!", + "Você tem que encontrar o Coração do Mar e o Mapa de Tempo", + "ou nós estamos presos!" ], "kei029": [ - "This is Keira. Thanks for getting the artifacts, guys.", - "It's strange... the Time Map had a bunch of old coordinates", - "in it. Come see me at the Stadium." + "Aqui é Keira. Obrigada por pegarem os artefatos, galera.", + "É estranho... o mapa do tempo tinha várias coordenadas antigas", + "nele. Venham me ver no Estádio." ], "kg001": [ "Solicite reforços!" @@ -4251,10 +4255,10 @@ "Alto lá!" ], "kg005": [ - "Get more cruisers in here!" + "Adquira mais cruzeiros aqui!" ], "kg005a": [ - "Get more cruisers in here!" + "Adquira mais cruzeiros aqui!" ], "kg006": [ "Renda-se!" @@ -4263,10 +4267,10 @@ "Renda-se!" ], "kg007": [ - "This is a no-hover zone!" + "Esta é uma zona sem cobertura!" ], "kg007a": [ - "This is a no-hover zone!" + "Esta é uma zona sem cobertura!" ], "kg008": [ "Encosta!" @@ -4296,10 +4300,10 @@ "Você aí!" ], "kg014": [ - "You want some?!" + "Quer um pouco?!" ], "kg015": [ - "This area is off-limits." + "Essa área é sem limites." ], "kg016": [ "Pare!" @@ -4383,76 +4387,76 @@ "Indo para o próximo setor." ], "kg032a": [ - "Moving to next sector." + "Indo para o próximo setor." ], "kg033": [ - "I've got suspicious activity in this sector." + "Tenho atividades suspeitas neste setor." ], "kg033a": [ - "I've got suspicious activity in this sector." + "Tenho atividades suspeitas neste setor." ], "kg034": [ - "Sweeping for suspects." + "Varrendo por suspeitos." ], "kg034a": [ - "Sweeping for suspects." + "Varrendo por suspeitos." ], "kg035": [ - "Nothing so far." + "Até agora, nada." ], "kg035a": [ - "Nothing so far." + "Até agora, nada." ], "kg036": [ - "Roger that, still looking." + "Afirmativo, ainda procurando." ], "kg036a": [ - "Roger that, still looking." + "Afirmativo, ainda procurando." ], "kg037": [ - "Roger, we'll shoot on sight." + "Positivo, vamos atirar à vista." ], "kg037a": [ - "Roger, we'll shoot on sight." + "Positivo, vamos atirar à vista." ], "kg038": [ - "Please advise, suspect's description." + "Por favor, aconselhe, descrição do suspeito." ], "kg039": [ - "Get out of the vehicle!" + "Saia do veículo!" ], "kg039a": [ - "Get out of the vehicle!" + "Saia do veículo!" ], "kg040": [ - "Call in more Hellcats!" + "Chame mais Hellcats!" ], "kg040a": [ - "Call in more Hellcats!" + "Chame mais Hellcats!" ], "kg041": [ - "The area is secure." + "A área está segura." ], "kg041a": [ - "The area is secure." + "A área está segura." ], "kg042": [ - "Nothing to report." + "Nada para relatar." ], "kg042a": [ - "Nothing to report." + "Nada para relatar." ], "kg043": [ - "Proceeding as planned." + "Proseguindo como planejado." ], "kg043a": [ - "Proceeding as planned." + "Proseguindo como planejado." ], "kg044": [ - "I lost him." + "Nós o perdemos." ], "kg044a": [ - "I lost him." + "Nós o perdemos." ], "kg045": [ "Perdi o sujeito de vista." @@ -4461,58 +4465,58 @@ "Perdi o sujeito de vista." ], "kg046": [ - "He's gone." + "Ele se foi." ], "kg046a": [ - "He disappeared!" + "Ele desapareceu!" ], "kg047": [ - "Where'd he go?" + "Para onde eles foram?" ], "kg047a": [ - "Where'd he go?" + "Para onde eles foram?" ], "kg048": [ - "Lost visual contact." + "Contato visual perdido." ], "kg048a": [ - "Lost visual contact." + "Contato visual perdido." ], "kg049": [ - "He just ducked out." + "Ele apenas fugiu." ], "kg049a": [ - "He just ducked out." + "Ele apenas fugiu." ], "kg050": [ - "He's out of sight." + "Ele está fora de vista." ], "kg050a": [ - "He's out of sight." + "Ele está fora de vista." ], "kg051": [ - "We're losing him!" + "Estamos perdendo ele!" ], "kg051a": [ - "We're losing him!" + "Estamos perdendo ele!" ], "kg052": [ - "Continuing our sweep." + "Continuando nossa varredura." ], "kg052a": [ - "Continuing our sweep." + "Continuando nossa varredura." ], "kg053": [ - "Searching sector four." + "Procurando pelo setor quatro." ], "kg053a": [ - "Searching sector four." + "Procurando pelo setor quatro." ], "kg054": [ - "Searching sector seven." + "Procurando pelo setor sete." ], "kg054a": [ - "Searching sector seven." + "Procurando pelo setor sete." ], "kg055": [ "Procurando no setor três." @@ -4593,28 +4597,28 @@ "Ele escapou." ], "kg068": [ - "He shook us." + "Ele nos assustou." ], "kg068a": [ - "He shook us." + "Ele nos assustou." ], "kg069": [ - "Looks like he's gone." + "Parece que ele se foi." ], "kg069a": [ - "Looks like he's gone." + "Parece que ele se foi." ], "kg070": [ - "I found him!" + "Eu o encontrei!" ], "kg070a": [ - "I found him!" + "Eu o encontrei!" ], "kg071": [ - "There he is." + "Aí está ele." ], "kg071a": [ - "There he is!" + "Lá está ele!" ], "kg072": [ "Fique atento, alvo na mira." @@ -4623,148 +4627,148 @@ "Fique atento, alvo na mira." ], "kg073": [ - "We have a positive ID." + "Temos uma identidade positiva." ], "kg073a": [ - "We have a positive ID." + "Temos uma identidade positiva." ], "kg074": [ - "I see him!" + "Eu o vejo!" ], "kg074a": [ - "I see him!" + "Eu o vejo!" ], "kg075": [ - "He's over there, get him!" + "Ele está lá, pegue-o!" ], "kg075a": [ - "He's over here!" + "Ele está aqui!" ], "kg076": [ - "Get him!" + "Pegue ele!" ], "kg076a": [ - "Get him!" + "Pegue ele!" ], "kg077": [ - "I've reacquired the target!" + "Eu readquiri o alvo!" ], "kg077a": [ - "I've reacquired the target!" + "Eu reportei o alvo!" ], "kg078": [ - "I'm closing in." + "Estou fechando." ], "kg078a": [ - "I'm closing in!" + "Estou fechando!" ], "kg079": [ - "I'm on him!" + "Estou com ele!" ], "kg079a": [ - "I'm on him!" + "Estou nele!" ], "kg080": [ - "I'm in pursuit!" + "Estou em perseguição!" ], "kg080a": [ - "I'm in pursuit!" + "Estou em perseguição!" ], "kg081": [ - "Pursuing target." + "Perseguição ao alvo." ], "kg081a": [ - "Pursuing target!" + "Perseguindo o alvo!" ], "kg082": [ - "Don't let him get away!" + "Não o deixe escapar!" ], "kg082a": [ - "Don't let him get away!" + "Não o deixe escapar!" ], "kg083": [ - "Get him!" + "Pegue ele!" ], "kg083a": [ - "Get him!" + "Pegue ele!" ], "kg084": [ - "After him!" + "Depois dele!" ], "kg084a": [ - "After him!" + "Depois dele!" ], "kg085": [ - "I have a visual!" + "Eu tenho um visual!" ], "kg085a": [ - "I have a visual!" + "Eu tenho um visual!" ], "kg086": [ - "We see him!" + "Nós o vemos!" ], "kg086a": [ - "We see him!" + "Nós o vemos!" ], "kg087": [ - "Stop right there!" + "Pare aí mesmo!" ], "kg087a": [ - "Stop right there!" + "Pare aí mesmo!" ], "kg088": [ - "I have a bead on him!" + "Eu tenho ele na mira!" ], "kg088a": [ - "I have a bead on him!" + "Eu tenho ele na mira!" ], "kg089": [ - "I'm hit!" + "Estou atingido!" ], "kg089a": [ - "I'm hit!" + "Estou atingido!" ], "kg090": [ - "Man down!" + "Homem caído!" ], "kg090a": [ - "Man down!" + "Homem caído!" ], "kg091": [ - "I need backup!" + "Preciso de reforços!" ], "kg091a": [ - "I need backup!" + "Eu preciso de backup!" ], "kg092": [ - "Stop him!" + "Parem ele!" ], "kg092a": [ - "Stop him!" + "Parem-no!" ], "kg093": [ - "Look out!" + "Cuidado!" ], "kg093a": [ - "Look out!" + "Cuidado!" ], "kg094": [ - "There he is, shoot him!" + "Lá vai ele, atire!" ], "kg094a": [ - "There he is, shoot him!" + "Aí está ele, atire nele!" ], "kg095": [ - "Take him out!" + "Elimine-o!" ], "kg095a": [ - "Take him out!" + "Elimine-o!" ], "kg096": [ "Fuga de prisioneiro em andamento, soe o alarme!" ], "kg096a": [ - "Prison escape in progress, sound the alarm!" + "Fuga de prisioneiro em andamento, soe o alarme!" ], "kg097": [ "Prisioneiro no segundo andar!" @@ -4785,10 +4789,10 @@ "Achamos que ele está na tubulação!" ], "kg100": [ - "We're beginning our sweep." + "Estamos começando nossa varredura." ], "kg100a": [ - "We're beginning our sweep." + "Estamos começando nossa varredura." ], "kg101": [ "Temos o prisioneiro à vista, mexa-se!" @@ -4797,28 +4801,28 @@ "Temos o prisioneiro à vista, mexa-se!" ], "kg102": [ - "We have movement on level one!" + "Temos movimento no nível um!" ], "kg102a": [ - "We have movement on level one!" + "Temos movimentações no nível um!" ], "kg103": [ - "Close in!" + "Fechar!" ], "kg103a": [ - "Close in!" + "Fechar!" ], "kg104": [ - "We're moving in!" + "Estamos entrando!" ], "kg104a": [ - "We're moving in!" + "Estamos entrando!" ], "kg105": [ - "Secure the cell block!" + "Proteja o bloco de celas!" ], "kg105a": [ - "Secure the cell block!" + "Proteja o bloco de celas!" ], "kg106": [ "Não faça prisioneiros!" @@ -4845,10 +4849,10 @@ "Achamos que ele está indo para uma saída!" ], "kg110": [ - "Searching rooms." + "Procurando quartos." ], "kg110a": [ - "Searching rooms." + "Procurando quartos." ], "kg111": [ "Prisioneiro à solta no complexo." @@ -4857,40 +4861,40 @@ "Prisioneiro à solta no complexo." ], "kg112": [ - "You are authorized to shoot to kill." + "Você está autorizado a atirar para matar." ], "kg112a": [ - "You are authorized to shoot to kill." + "Você está autorizado a atirar para matar." ], "kg113": [ - "Go, go, go! Sweep the area!" + "Vai, vai, vai! Varrer a área!" ], "kg113a": [ - "Go go go! Sweep the area!" + "Vai, vai, vai! Varrer a área!" ], "kg114": [ - "Searching the sub-basements." + "Procurando nos sub-porões." ], "kg114a": [ - "Searching the sub-basements." + "Procurando nos sub-porões." ], "kg115": [ - "Cell block is clear." + "Bloco de celas limpo." ], "kg115a": [ - "Cell block is clear." + "Bloco de celas limpo." ], "kg116": [ - "Tank room is clear." + "Sala de tanque limpa." ], "kg116a": [ - "Tank room is clear." + "Sala de tanque limpa." ], "kg117": [ - "Activate riot tanks." + "Ativar tanques de choque." ], "kg117a": [ - "Activate riot tanks." + "Ativar tanques de choque." ], "kg118": [ "O Tanque de Choque está com o prisioneiro à vista." @@ -4899,22 +4903,22 @@ "O Tanque de Choque está com o prisioneiro à vista." ], "kg119": [ - "Intruder alert." + "Alerta de intruso." ], "kg119a": [ - "Intruder alert!" + "Alerta de intruso!" ], "kg120": [ - "Activating security defenses." + "Ativando defesas de segurança." ], "kg120a": [ - "Activating security defenses." + "Ativando defesas de segurança." ], "kg121": [ - "Please advise, subject's description." + "Por favor, avise, descrição do suspeito." ], "kg121a": [ - "Please advise, subject's description." + "Por favor, avise, descrição do suspeito." ], "kg122": [ "Tenho civis na mira." @@ -4929,516 +4933,516 @@ "Tenho suspeitos na mira." ], "kg124": [ - "I hate the smell of this part of the city." + "Eu odeio o cheiro desta parte da cidade." ], "kg124a": [ - "I hate the smell in this part of the city." + "Eu odeio o cheiro desta parte da cidade." ], "kg125": [ - "Right, we'll check it out." + "Certo, nós iremos conferir." ], "kg125a": [ - "Right, we'll check it out." + "Certo, nós vamos verificar." ], "kg126": [ - "Confirmed, Underground suspect neutralized." + "Confirmado, suspeito no Subsolo neutralizado." ], "kg126a": [ - "Confirmed, Underground suspect neutralized." + "Confirmado, suspeito no Subsolo neutralizado." ], "kg127": [ - "They're all guilty!" + "Eles são todos culpados!" ], "kg127a": [ - "They're all guilty!" + "Eles são todos culpados!" ], "kg128": [ - "This is Unit Alpha, we're en route." + "Este é o Unitário Alfa, estamos na direção." ], "kg128a": [ - "This is Unit Alpha, we're en route." + "Essa é a Unidade Alfa, nós estamos em rota." ], "kg129": [ - "Roger, continuing our sweep." + "Positivo, continuando nossa varredura." ], "kg129a": [ - "Roger, continuing our sweep." + "Positivo, continuando nossa varredura." ], "kg130": [ - "Unit Zulu, moving in." + "Unidade Zulu, entrando." ], "kg130a": [ - "Unit Zulu, moving in." + "Unidade Zulu, entrando." ], "kg131": [ - "Roger that, we're making our sweep." + "Afirmativo, estamos realizando nossa varredura." ], "kg131a": [ - "Roger that, we're making our sweep." + "Afirmativo, estamos realizando nossa varredura." ], "kg132": [ - "I say shoot 'em all and sort 'em out later." + "Eu digo que atirem tudo e acabem por sair mais tarde." ], "kg132a": [ - "I say shoot 'em all and sort 'em out later." + "Eu digo que atire em todos e os procurem depois." ], "kg133": [ - "You have the right to die!" + "Você tem o direito de morrer!" ], "kg134": [ - "Lock and load!" + "Bloquear e carregar!" ], "kg135": [ - "Open fire!" + "Abrir fogo!" ], "kg136": [ - "Alert, alert!" + "Atenção, alerta!" ], "kg137": [ - "Don't move!" + "Não se mova!" ], "kg138": [ - "Do it!" + "Faça-o!" ], "kg139": [ - "Go, go, go!" + "Vai, vai, vai!" ], "kg140": [ "Cerquem eles!" ], "kg141": [ - "Move in!" + "Entrar!" ], "kg142": [ - "Take 'em out!" + "Elimine-os!" ], "kg143": [ - "Bust some heads!" + "Explodam alguns miolos!" ], "kg144": [ - "Arrest him!" + "Prendam-no!" ], "kg145": [ - "Shoot 'em, shoot 'em!" + "Atire neles, atire neles!" ], "kg146": [ "Morra, marginal!" ], "kg147": [ - "You're history!" + "Você é história!" ], "kg148": [ - "Eat this!" + "Toma essa!" ], "kg149": [ - "Get some!" + "Pegue!" ], "kg150": [ - "Fire, fire!" + "Fogo, fogo!" ], "kg151": [ - "Here's one for the Guard!" + "Aqui vai uma para a Guarda!" ], "kg152": [ "Desista, marginal!" ], "kg153": [ - "Here's some pain!" + "Aqui vai um pouco de dor!" ], "kg154": [ - "Payback time!" + "Hora do troco!" ], "kg155": [ - "Shoulda given up!" + "Deveria ter desistido!" ], "kg156": [ - "I need cover fire!" + "Preciso de cobertura!" ], "kg157": [ - "Call in reinforcements!" + "Chame reforços!" ], "kg158": [ - "I'll shoot!" + "Eu atiro!" ], "kg159": [ - "Die!" + "Morra!" ], "kg160": [ - "You're busted!" + "Você está preso!" ], "kg161": [ - "Riot in progress!" + "Tumulto em progresso!" ], "kg162": [ - "Send in the troops!" + "Chamem as tropas!" ], "kg163": [ - "Give it up!" + "Desista!" ], "kg164": [ - "Make 'em pay!" + "Faça-os pagar!" ], "kg165": [ - "Tag 'em and bag 'em!" + "Etiquete-os e ensaque-os!" ], "kg165a": [ - "Tag 'em and bag 'em!" + "Etiquete-os e ensaque-os!" ], "kg165b": [ - "Tag 'em and bag 'em!" + "Etiquete-os e ensaque-os!" ], "kg166": [ - "Another notch for my gun." + "Outro entalhe para minha arma." ], "kg166a": [ - "Another notch for my gun." + "Outro entalhe para minha arma." ], "kg166b": [ - "Another notch for my gun." + "Outro entalhe para minha arma." ], "kg167": [ - "This one was easy!" + "Este foi fácil!" ], "kg167a": [ - "This one was easy!" + "Este foi fácil!" ], "kg167b": [ - "This one was easy!" + "Este foi fácil!" ], "kg168": [ - "Suspect neutralized." + "Suspeito neuutralizado." ], "kg168a": [ - "Suspect neutralized." + "Suspeito neuutralizado." ], "kg168b": [ - "Suspect neutralized." + "Suspeito neuutralizado." ], "kg169": [ - "Didn't even work up a sweat." + "Nem sequer suei." ], "kg169a": [ - "Didn't even work up a sweat." + "Nem sequer suei." ], "kg169b": [ - "Didn't even work up a sweat." + "Nem sequer suei." ], "kg170": [ - "Take him in for... questioning, hehehe..." + "Leve-o para... questionar, hehehe..." ], "kg170a": [ - "Take him in for... questioning, hehehe..." + "Leve-o para... questionar, hehehe..." ], "kg170b": [ - "Take him in for... questioning, hehehe..." + "Leve-o para... questionar, hehehe..." ], "kg171": [ - "Another one bites the dust." + "Mais um come poeira." ], "kg171a": [ - "Another one bites the dust." + "Outro come poeira." ], "kg171b": [ - "Another one bites the dust." + "Outro come poeira." ], "kg172": [ - "That must have hurt." + "Essa deve ter doído." ], "kg172a": [ - "That must have hurt." + "Isso deve ter doido." ], "kg172b": [ - "That must have hurt." + "Isso deve ter doido." ], "kg173": [ - "There's plenty more where that came from." + "Há muito mais de onde isso veio." ], "kg173a": [ - "There's plenty more where that came from." + "Há muito mais de onde isso veio." ], "kg173b": [ - "There's plenty more where that came from." + "Há muito mais de onde isso veio." ], "kg174": [ - "Citizen scum." + "Escória dos habitantes." ], "kg174a": [ - "Citizen scum." + "Escória dos habitantes." ], "kg174b": [ - "Citizen scum." + "Escória dos habitantes." ], "kg175": [ - "Don't fight the law, son." + "Não lute contra a lei, filho." ], "kg175a": [ - "Don't fight the law, son." + "Não lute contra a lei, filho." ], "kg175b": [ - "Don't fight the law, son." + "Não lute contra a lei, filho." ], "kg176": [ - "You are under arrest!" + "Você está preso!" ], "kg177": [ - "Get moving!" + "Continue andando!" ], "kg178a": [ - "He vanished!" + "Ele desapareceu!" ], "kg179": [ - "You guys hear about the latest Metal Head attacks?" + "Ficaram sabendo sobre o último ataque dos Cabeças de Metal?" ], "kg179b": [ - "Oh you guys hear about the latest Metal Head attacks?" + "Ah, ficaram sabendo sobre o último ataque dos Cabeças de Metal?" ], "kg180": [ - "We lost three squads last week." + "Perdemos três esquadrões na semana passada." ], "kg180a": [ - "We lost three squads last week." + "Perdemos três esquadrões na semana passada." ], "kg180b": [ - "We lost three squads last week." + "Perdemos três esquadrões na semana passada." ], "kg181": [ - "I hear the Underground are getting stronger." + "Fiquei sabendo que o Subterrâneo está ficando mais forte." ], "kg181a": [ - "I hear the Underground are getting stronger." + "Fiquei sabendo que o Subterrâneo está ficando mais forte." ], "kg181b": [ - "I hear the Underground are getting stronger." + "Ouvi dizer que o Subterrâneo está ficando mais forte." ], "kg182": [ - "Just rumors, private, keep your mouth shut." + "Apenas rumores, privados, mantenham a boca fechada." ], "kg182a": [ - "Just rumors, private, keep your mouth shut." + "Apenas rumores, privados, mantenham a boca fechada." ], "kg182b": [ - "Just rumors, private, keep your mouth shut." + "Apenas rumores, privados, mantenham a boca fechada." ], "kg183": [ - "It's us or them, there's no in-between." + "Somos nós ou eles, não há intermediário." ], "kg183a": [ - "It's us or them, there's no in-between." + "Somos nós ou eles, não há intermediário." ], "kg183b": [ - "It's us or them, there's no in-between." + "Somos nós ou eles, não há intermediário." ], "kg184": [ - "Don't worry, the Baron will save us." + "Não se preocupe, o Barão vai nos salvar." ], "kg184a": [ - "Don't worry, the Baron will save us." + "Não se preocupe, o Barão vai nos salvar." ], "kg184b": [ - "Don't worry, the Baron will save us." + "Não se preocupe, o Barão vai nos salvar." ], "kg185": [ - "I got no faith in nobody." + "Não tive fé em ninguém." ], "kg185a": [ - "I ain't got no faith in nobody." + "Não tenho fé em ninguém." ], "kg185b": [ - "I got no faith in nobody." + "Não tive fé em ninguém." ], "kg186": [ - "Seen that new JX-7 racer? Sweet ride." + "Viram aquele novo corredor JX-7? Boa corrida." ], "kg186a": [ - "You seen that new JX-7 racer? Sweet ride." + "Vocês viram aquele novo corredor JX-7? Boa corrida." ], "kg186b": [ - "Seen that new JX-7 racer? It's a sweet ride." + "Viram aquele novo corredor JX-7? É uma boa corrida." ], "kg187": [ - "You seen anything?" + "Você não viu nada?" ], "kg187a": [ - "You seen anything?" + "Você não viu nada?" ], "kg187b": [ - "You seen anything?" + "Você não viu nada?" ], "kg188": [ - "No." + "Não." ], "kg188a": [ - "No." + "Não." ], "kg188b": [ - "Nah." + "Não." ], "kg189": [ - "Keep your eyes peeled." + "Mantenha seus olhos bem abertos." ], "kg189a": [ - "Keep your eyes peeled." + "Mantenha seus olhos bem abertos." ], "kg189b": [ - "Keep your eyes peeled." + "Mantenha seus olhos bem abertos." ], "kg190": [ - "I just got a radio alert, stay frosty." + "Acabei de receber um alerta de rádio, permaneça parado." ], "kg190a": [ - "I just got a radio alert, stay frosty." + "Acabei de receber um alerta de rádio, permaneça parado." ], "kg190b": [ - "I just got a radio alert, stay frosty." + "Acabei de receber um alerta de rádio, permaneça parado." ], "kg191": [ - "Never trust a civilian." + "Nunca confie em um civil." ], "kg191a": [ - "Never trust a civilian." + "Nunca confie em um civil." ], "kg191b": [ - "Never trust a civilian." + "Nunca confie em um civil." ], "kg192": [ - "Never trust anyone." + "Nunca confie em ninguém." ], "kg192a": [ - "Never trust anyone." + "Nunca confie em ninguém." ], "kg192b": [ - "Never trust anyone." + "Nunca confie em ninguém." ], "kg193": [ - "Long live the KG!" + "Vida longa ao KG!" ], "kg193a": [ - "Long live the KG!" + "Vida longa ao KG!" ], "kg193b": [ - "Long live the KG!" + "Vida longa ao KG!" ], "kg194": [ - "We ain't had a food riot since we brought in them tanks." + "Nós não tivemos um motim de comida desde que trouxemos tanques para eles." ], "kg194a": [ - "We ain't had a food riot since we brought in them tanks." + "Nós não tivemos um motim de comida desde que trouxemos tanques para eles." ], "kg194b": [ - "We ain't had a food riot since we brought in them tanks." + "Nós não tivemos um motim de comida desde que trouxemos tanques para eles." ], "kg195": [ - "I'm bored, I want to crunch heads." + "Estou entediado, quero quebrar as cabeças." ], "kg195a": [ - "I'm bored, I want to crunch heads." + "Estou entediado, quero esmagar cabeças." ], "kg195b": [ - "I'm bored, I want to crunch heads." + "Estou entediado, quero esmagar cabeças." ], "kg196": [ - "I want to kick some ass." + "Quero chutar umas bundas." ], "kg196a": [ - "Ugh... I want to kick some butt." + "Ugh... Quero chutar umas bundas." ], "kg196b": [ - "I want to kick some butt." + "Quero chutar umas bundas." ], "kg197": [ - "Did you hear the Underground got our ammo at HQ?" + "Ficou sabendo que o Subterrâneo pegou nossa munição no QG?" ], "kg197a": [ - "Did you hear the Underground got to", - "our ammo at HQ?" + "Ficou sabendo que o Subterrâneo chegou", + "às nossas munições no QG?" ], "kg197b": [ - "Did you hear the Underground got to", - "our ammo at HQ?" + "Ficou sabendo que o Subterrâneo chegou", + "às nossas munições no QG?" ], "kg198": [ - "Payback's a bitch!" + "A vingança é plena!" ], "kg198a": [ - "Payback's a bitch!" + "A vingança é plena!" ], "kg198b": [ - "Payback's a bitch!" + "A vingança é plena!" ], "kg199": [ - "Animals!" + "Animais!" ], "kg199a": [ - "Animals!" + "Animais!" ], "kg199b": [ - "Animals!" + "Animais!" ], "kg200": [ - "I hear the Shadow's been dead for years." + "Fiquei sabendo que a Sombra está morta há anos." ], "kg200a": [ - "I hear the Shadow's been dead for years." + "Fiquei sabendo que a Sombra está morta há anos." ], "kg200b": [ - "I hear the Shadow's been dead for years." + "Fiquei sabendo que a Sombra está morta há anos." ], "kg201": [ - "Maybe, but the rest of them Underground scum", - "are still scurrying about." + "Talvez, mas o resto da escória do Subterrâneo", + "ainda estão correndo de um lado pro outro." ], "kg201a": [ - "Maybe, but the rest of them Underground scum", - "are still scurrying about." + "Talvez, mas o resto da escória do Subterrâneo", + "ainda estão correndo de um lado pro outro." ], "kg201b": [ - "Maybe, but the rest of them Underground scum", - "are still scurrying about." + "Talvez, mas o resto da escória do Subterrâneo", + "ainda estão correndo de um lado pro outro." ], "kg202": [ - "Can I shoot someone now?" + "Posso atirar em alguém agora?" ], "kg202a": [ - "Can I shoot someone now?" + "Posso atirar em alguém agora?" ], "kg202b": [ - "Can I shoot someone now?" + "Posso atirar em alguém agora?" ], "kg203": [ - "I like the new armor." + "Gosto da nova armadura." ], "kg203a": [ - "I like the new armor." + "Gosto da nova armadura." ], "kg203b": [ - "I like the new armor." + "Gosto da nova armadura." ], "kg204": [ - "Yeah, me too. More comfort in the crotch." + "É, eu também. Mais confortável na virilha." ], "kg204a": [ - "Yeah, me too. More comfort in the crotch." + "É, eu também. Mais confortável na virilha." ], "kg204b": [ - "Yeah, me too. More comfort in the crotch." + "É, eu também. Mais confortável na virilha." ], "kg205": [ - "If something interesting doesn't happen soon,", - "I'm going to start shooting you." + "Se algo interessante não acontecer logo,", + "eu começo a atirar em você." ], "kg205a": [ - "Next time, can I kill a civvy?" + "Na próxima, posso matar um civil?" ], "kg205b": [ - "Next time, can I kill a civvy?" + "Na próxima, posso matar um civil?" ], "kg206a": [ - "If something interesting doesn't happen soon,", - "I'm gonna shoot you." + "Se algo interessante não acontecer logo,", + "Eu vou atirar em você." ], "kg206b": [ - "If something interesting doesn't happen soon,", - "I'm gonna start shooting you." + "Se algo interessante não acontecer logo,", + "eu começo a atirar em você." ], "kg207": [ "Você cobrou suas propinas esta semana?" @@ -5465,250 +5469,250 @@ "Shh." ], "kg210": [ - "I hear someone's been using the old wall airlocks.", - "Pfft, crazy bastard." + "Fiquei sabendo que alguém está usando as câmaras de ar da parede velha.", + "Pfft, desgraçado maluco." ], "kg210a": [ - "I hear someone's been using the old wall airlocks.", - "Crazy bastard." + "Fiquei sabendo que alguém está usando as câmaras de ar da parede velha.", + "Desgraçado maluco." ], "kg210b": [ - "I hear someone's been using the old wall airlocks.", - "Crazy bastard." + "Fiquei sabendo que alguém está usando as câmaras de ar da parede velha.", + "Bastardo maluco." ], "kg211": [ - "I've been on duty for two days straight." + "Estou de dever por dois dias seguidos." ], "kg211a": [ - "I've been on duty for two days straight." + "Estou de dever por dois dias seguidos." ], "kg211b": [ - "I've been on duty for two days straight." + "Estou de dever por dois dias seguidos." ], "kg212": [ - "Pfft, don't complain. I've got sewer patrol next week." + "Pfft, não reclama. Fiquei com uma patrulha de esgoto na próxima semana." ], "kg212a": [ - "Don't complain, I got sewer patrol next week." + "Não reclama. Fiquei com uma patrulha de esgoto na próxima semana." ], "kg212b": [ - "Don't complain. I got sewer patrol next week." + "Não reclama. Fiquei com uma patrulha de esgoto na próxima semana." ], "kg213": [ - "Ahh, you poor bastard. Which commander did you piss off?" + "Ahh, seu pobre desgraçado. Qual comandante você irritou?" ], "kg213a": [ - "Ahh, you poor bastard. Which commander did you piss off?" + "Ahh, seu pobre desgraçado. Qual comandante você irritou?" ], "kg213b": [ - "Hehe, poor bastard. Which commander did you piss off?" + "Ahh, seu pobre desgraçado. Qual comandante você irritou?" ], "kg214": [ - "I say death to the Underground." + "Digo morte ao Subsolo." ], "kg214a": [ - "I say death to the Underground." + "Digo morte ao Subsolo." ], "kg214b": [ - "I say death to the Underground." + "Digo morte ao Subsolo." ], "kg215": [ - "I wanna so kill that Shadow guy." + "Eu quero tanto matar aquele Homem Sombrio." ], "kg215a": [ - "I want to kill that Shadow guy!" + "Eu quero matar aquele Homem Sombrio!" ], "kg215b": [ - "I want to kill that Shadow guy!" + "Eu quero matar aquele Homem Sombrio!" ], "kg216": [ - "And don't forget that traitor Torn." + "E não se esqueça daquele traidor Torn." ], "kg216a": [ - "And don't forget that traitor Torn." + "E não se esqueça daquele traidor Torn." ], "kg216b": [ - "Don't forget that traitor Torn!" + "Não se esqueça daquele traidor Torn!" ], "kg217": [ - "Death's too good for him." + "A morte é boa demais para ele." ], "kg217a": [ - "Death's too good for him." + "A morte é boa demais para ele." ], "kg217b": [ - "Death's too good for him." + "A morte é boa demais para ele." ], "kg218": [ - "Why are we looking for some kid?" + "Por que estamos procurando por um garoto?" ], "kg218a": [ - "Why are we looking for some kid?" + "Por que estamos procurando por um garoto?" ], "kg218b": [ - "Why are we looking for some kid?" + "Por que estamos procurando por um garoto?" ], "kg219": [ - "I don't know, Baron's orders." + "Eu não sei, ordens do Barão." ], "kg219a": [ - "I dunno, Baron's orders." + "Eu não sei, ordens do Barão." ], "kg219b": [ - "I dunno, Baron's orders." + "Não sei, ordens do Barão." ], "kg220": [ - "Hey, have they found Mar's Tomb yet?" + "Ei, eles já encontraram a Tumba de Mar?" ], "kg220a": [ - "Have they found Mar's Tomb yet?" + "Eles já encontraram a Tumba de Mar?" ], "kg220b": [ - "Have they found Mar's Tomb yet?" + "Eles já encontraram a Tumba de Mar?" ], "kg221": [ - "They wouldn't tell us if they did." + "Eles não nos diriam se tivessem." ], "kg221a": [ - "Nah, they wouldn't tell us if they did." + "Nah, eles não nos diriam se tivessem." ], "kg221b": [ - "Nah, they wouldn't tell us if they did." + "Nah, eles não nos diriam se tivessem." ], "kg222": [ - "I've got a big bet on the next city races." + "Eu tenho uma grande aposta nas próximas corridas da cidade." ], "kg222a": [ - "I got a big bet on the next city races." + "Tenho uma grande aposta nas próximas corridas da cidade." ], "kg222b": [ - "Got a big bet on the next city races." + "Tenho uma grande aposta nas próximas corridas da cidade." ], "kg223": [ - "Erol's my boy. He always wins." + "Erol é meu garoto. Ele sempre ganha." ], "kg223a": [ - "Erol's my boy. He always wins." + "Erol é meu garoto. Ele sempre ganha." ], "kg223b": [ - "Erol's my boy. He always wins." + "Erol é meu garoto. Ele sempre ganha." ], "kg224": [ - "You going to the city races this time?" + "Você vai às corridas da cidade dessa vez?" ], "kg224a": [ - "You going to the city races this time?" + "Você vai às corridas da cidade dessa vez?" ], "kg224b": [ - "You going to the city races this time?" + "Você vai às corridas da cidade dessa vez?" ], "kg225": [ - "I'll be there." + "Eu estarei lá." ], "kg225a": [ - "I'll be there." + "Eu estarei lá." ], "kg225b": [ - "I'll be there." + "Eu estarei lá." ], "kg226": [ - "There've been some serious guard casualties this week." + "Houve algumas baixas sérias de guardas essa semana." ], "kg226a": [ - "There've been some serious guard casualties this week." + "Houve algumas baixas sérias de guardas essa semana." ], "kg226b": [ - "There've been some serious guard casualties this week." + "Houve algumas baixas sérias de guardas essa semana." ], "kg227": [ - "Yeah, some rebel fighter is stirring up the pot good." + "Sim, um lutador rebelde está botando bastante lenha na fogueira." ], "kg227a": [ - "Yeah, some rebel fighter is stirring the pot good." + "Sim, um lutador rebelde está botando bastante lenha na fogueira." ], "kg227b": [ - "Some rebel fighter is stirring the pot good." + "Um lutador rebelde está botando bastante lenha na fogueira." ], "kg228": [ - "I'd love to be the one to take him out." + "Eu adoraria ser a pessoa a eliminá-lo." ], "kg228a": [ - "I'd love to be the one to take him out." + "Eu adoraria ser a pessoa a eliminá-lo." ], "kg228b": [ - "Oh I'd love to be the one to take him out." + "Oh, eu adoraria ser a pessoa a eliminá-lo." ], "kg229": [ - "Let's get drinks later." + "Vamos beber depois." ], "kg229a": [ - "Let's get drinks later." + "Vamos beber depois." ], "kg229b": [ - "Let's get drinks later." + "Vamos beber depois." ], "kg230": [ - "I got a bad feeling about this war." + "Tenho um mau pressentimento sobre essa guerra." ], "kg230a": [ - "I got a bad feeling about this war." + "Tenho um mau pressentimento sobre essa guerra." ], "kg230b": [ - "I got a bad feeling about this war." + "Tenho um mau pressentimento sobre essa guerra." ], "kg231": [ - "I hear there are more Metal Head attacks", - "than HQ's admitting." + "Ouvi dizer que há mais ataques dos Cabeças de Metal", + "que o QG está admitindo." ], "kg231a": [ - "I hear there are more Metal Head attacks", - "than HQ's admitting." + "Ouvi dizer que há mais ataques dos Cabeças de Metal", + "que o QG está admitindo." ], "kg231b": [ - "Yeah, I hear there are more Metal Head attacks", - "than HQ's admitting." + "Sim, ouvi dizer que há mais ataques dos Cabeças de Metal", + "que o QG está admitindo." ], "kg232": [ - "The reports I've seen aren't good.", - "I think the city's in trouble." + "Os relatórios que vi não são bons.", + "Acho que a cidade está com problemas." ], "kg232a": [ - "The reports I've seen aren't good.", - "I think the city's in trouble." + "Os relatórios que vi não são bons.", + "Acho que a cidade está com problemas." ], "kg232b": [ - "The reports I've seen aren't good.", - "I think the city's in trouble." + "Os relatórios que vi não são bons.", + "Acho que a cidade está com problemas." ], "kg233": [ - "I'm worried about this new guy", - "fighting for the Underground." + "Estou preocupado com este novo cara", + "lutando pelo Subterrâneo." ], "kg233a": [ - "I'm worried about this new guy", - "fighting for the Underground." + "Estou preocupado com este novo cara", + "lutando pelo Subterrâneo." ], "kg233b": [ - "I'm worried about this new guy fighting for the Underground.", - "fighting for the Underground." + "Eu estou preocupado com este cara novo", + "lutando pelo Subterrâneo." ], "kg234": [ - "Yeah, they say he can change into some kind of... monster." + "Sim, eles dizem que ele pode se transformar em algum tipo de monstro." ], "kg234a": [ - "Yeah, they say he can change into some kind of monster." + "Sim, eles dizem que ele pode mudar para uma espécie de monstro." ], "kg234b": [ - "They say he can change into some kind of monster." + "Eles dizem que ele pode mudar para uma espécie de monstro." ], "kg235": [ - "Don't worry, his head'll be on the tower wall soon enough." + "Não se preocupe, a cabeça dele estará na parede da torre logo mais." ], "kg235a": [ - "Don't worry, his head'll be on the tower wall soon enough." + "Não se preocupe, a cabeça dele estará na parede da torre logo mais." ], "kg235b": [ - "Don't worry, his head'll be on the tower wall soon enough." + "Não se preocupe, a cabeça dele estará na parede da torre logo mais." ], "kg236": [ "Hehehe." @@ -5732,79 +5736,79 @@ "Hah!" ], "kg239b": [ - "Hah!" + "Há!" ], "kg240a": [ "Hehehe..." ], "kg241a": [ - "Suspect in known Underground vehicle!" + "Suspeito em veículo Subterrâneo conhecido!" ], "kg242a": [ - "He's got a cargo, move in!" + "Ele tem uma carga, entre!" ], "kg243a": [ - "Stop that vehicle!" + "Pare aquele veículo!" ], "kg244a": [ - "You're under arrest, pull over!" + "Você está preso, encosta!" ], "kg245a": [ - "Surrender the vehicle!" + "Entregue o veículo!" ], "kg246a": [ - "We are in pursuit!" + "Estamos em perseguição!" ], "kg247a": [ - "He's got a package!" + "Ele tem um pacote!" ], "kg248a": [ - "Suspect has suspicious cargo!" + "Suspeito com cartão suspeito!" ], "kg249a": [ "Achamos que se trata de uma remessa ilegal." ], "kg250a": [ - "All units close in on vehicle!" + "Todas as unidades se aproximem do veículo!" ], "kg251a": [ - "Suspect moving at high speed!" + "Suspeita se movimento em alta velocidade!" ], "kg252a": [ - "We can't keep up!" + "Não conseguimos acompanhar!" ], "kg253a": [ - "He's in the port!" + "Ele está no porto!" ], "kg254a": [ - "He got away!" + "Ele fugiu!" ], "kg255a": [ - "Suspect has taken out pursuit!" + "Suspeito saiu em perseguição!" ], "kg256a": [ - "Vehicle destroyed, we got him!" + "Veículo destruído, nós o pegamos!" ], "kg257a": [ - "Nice work boys, he's down." + "Bom trabalho, garotos. Ele caiu." ], "kg258a": [ - "Excellent pursuit." + "Excelente perseguição." ], "kg259a": [ - "Guard transport under attack, requesting support!" + "Transporte de guarda sob ataque, solicitando apoio!" ], "kg260a": [ - "We're takin' damage!" + "Estamos recebendo dano!" ], "kg261a": [ - "He's after us!" + "Ele está atrás de nós!" ], "kg262a": [ - "He's trying to crash the transport!" + "Ele está tentando bater o transporte!" ], "kg263a": [ - "We've had a transport ambush, units respond!" + "Tivemos um transporte emboscado, unidades respondam!" ], "kg264a": [ "Ele está pegando um prisioneiro!" @@ -5816,363 +5820,363 @@ "Tem um prisioneiro Lurker com ele!" ], "kg267a": [ - "Take 'em all out!" + "Derrube todos eles!" ], "kg268a": [ "Achamos que ele está ajudando os Lurkers a escapar!" ], "kg269a": [ - "He's taken out two of our transports already!" + "Ele já levou dois dos nossos transportes!" ], "kg270a": [ - "He's alone again." + "Ele está sozinho novamente." ], "kg271a": [ - "Where's he heading?!" + "Para onde ele está indo?!" ], "kg272a": [ - "Terminate with extreme prejudice!" + "Extermine com extrema cautela!" ], "kg273a": [ - "He's attacking another transport!" + "Ele está atacando outro transporte!" ], "kg274a": [ - "We're being chased, send in an escort!" + "Estamos sendo perseguidos, envie uma escolta!" ], "kg275a": [ - "We lost this passenger." + "Perdemos este passageiro." ], "kg276a": [ - "We're losing him!" + "Estamos perdendo ele!" ], "kg277a": [ - "We got 'em!" + "Pegamos eles!" ], "kg278a": [ - "We got 'em, teach ya to screw with the KG!" + "Pegamos eles, ensine-os a não mexer com o KG!" ], "kg279a": [ - "Pull over, Lurker lover!" + "Encoste, amante de Perseguição!" ], "kg280a": [ - "There's a kid, check him out." + "Tem um menino, verifique-o." ], "kg281a": [ - "The Baron wants every kid in this city arrested." + "O Barão quer todos os meninos nesta cidade presos." ], "kg282a": [ - "Surrender the child!" + "Entregue a criança!" ], "kg283a": [ - "Give up the kid!" + "Entregue a criança!" ], "kg284a": [ - "If they won't surrender, kill them all!" + "Se não se renderem, matem todos!" ], "kg285a": [ - "Don't kill the kid." + "Não mate a criança." ], "kg286a": [ - "The Baron wants the kid alive!" + "O Barão quer a criança viva!" ], "kg287a": [ - "Find the boy!" + "Encontre o garoto!" ], "kg288a": [ - "That could be the kid the Baron wants." + "Aquela pode ser a criança que o Barão quer." ], "kg289a": [ - "After them!" + "Atrás deles!" ], "kg290a": [ - "Don't move, boy!" + "Não se mova, garoto!" ], "kg291a": [ - "Take out that mutt!" + "Acabe com aquele vira-lata!" ], "kg292a": [ - "We should kill 'em all!" + "Deveríamos matar todos eles!" ], "kg293a": [ - "They've taken a vehicle!" + "Eles pegaram um veículo!" ], "kg294a": [ - "If you get a clear shot, take it!" + "Se você tiver um tiro certeiro, pegue!" ], "kg295a": [ - "Suspect is fleeing in vehicle!" + "Suspeito está fugindo em um veículo!" ], "kg296a": [ - "Suspect's vehicle moving through section seven." + "O veículo do suspeito está movendo-se pela seção sete." ], "kg297a": [ "Achamos que o garoto está com aquele esquisitão do Subterrâneo." ], "kg298a": [ - "Take 'em out, but keep the kid alive!" + "Pegue-os, mas deixem a criança viva!" ], "kg299a": [ - "They're on foot again!" + "Eles estão a pé novamente!" ], "kg300a": [ - "What is that thing?!" + "O que é aquela coisa?!" ], "kg301a": [ - "Shoot that thing, shoot it!" + "Atire naquilo, atire!" ], "kg302a": [ - "What's he doing?!" + "O que ele está fazendo?!" ], "kg303a": [ - "It's that monster!" + "É aquele monstro!" ], "kg304a": [ - "The stories are true!" + "As histórias são reais!" ], "kg305a": [ - "It's the dark monster!" + "É o monstro sombrio!" ], "kg306a": [ - "It's him!" + "É ele!" ], "kg307a": [ - "It's the dark eco freak!" + "É a eco-aberração sombria!" ], "kg308a": [ - "Kill it, kill it!" + "Matem, matem!" ], "kg309a": [ - "Suspect has transformed into", - "a creature of some kind." + "Suspeito transformou-se", + "numa espécie de criatura." ], "kg310a": [ - "Sure is ugly." + "Com certeza é feia." ], "kg311a": [ - "That's one ugly creature." + "Isso sim é uma criatura feia." ], "kg312a": [ - "Look out!" + "Cuidado!" ], "kg313a": [ - "Fall back!" + "Recuar!" ], "kg314a": [ - "He's wasting everybody!" + "Ele está desperdiçando todo mundo!" ], "kg315a": [ - "We can't kill it!" + "Nós não podemos matá-lo!" ], "kg316a": [ - "Stand your ground men!" + "Mantenha-se firmes, homens!" ], "kg317a": [ - "The Krimzon Guard do not run!" + "Os Guardas Krimzon não correm!" ], "kg318a": [ - "Watch out for his claws!" + "Cuidado com suas garras!" ], "kg319a": [ - "Keep clear of his energy bolts!" + "Fiquem longe de seus raios energéticos!" ], "kg320a": [ - "This is a raid, do not resist!" + "Isto é uma invasão, não resista!" ], "kg321a": [ - "Move in!" + "Entrar!" ], "kg322a": [ - "By order of Baron Praxis,", - "everyone here is to be terminated!" + "Por ordem de Barão Praxis,", + "todo mundo aqui será exterminado!" ], "kg323a": [ - "Surrender and you will not suffer much." + "Rendam-se e não sofrerão muito." ], "kg324a": [ - "It's that Underground monster freak!" + "É aquele monstro horrendo do Subterrâneo!" ], "kg325a": [ - "Get him!" + "Pegue ele!" ], "kg326a": [ - "All units converge on Water Slums!" + "Todas as unidades convergir nas Favelas de Água!" ], "kg327a": [ - "We've got an Underground fighter!" + "Temos um lutador do Subterrâneo!" ], "kg328a": [ - "Burn 'em down!" + "Queime-os!" ], "kg329a": [ - "Stay together!" + "Fiquem juntos!" ], "kg330a": [ - "We've got 'em cornered!" + "Nós os encurralamos!" ], "kg331a": [ - "Suspect cornered in section two." + "Suspeito encurralado na seção dois." ], "kg332a": [ - "There is no escape!" + "Não há saída!" ], "kg333a": [ - "Resistance is futile!" + "Resistência é inútil!" ], "kg334a": [ - "Give up the artifact, eco freak!" + "Entregue o artefato, eco-aberração!" ], "kg335a": [ - "We've cut 'em off!" + "Nós os eliminamos!" ], "kg336a": [ - "He's trapped!" + "Ele está preso!" ], "kg337a": [ - "We got 'em!" + "Nós os pegamos!" ], "kg338a": [ - "We're taking heavy fire!" + "Estamos recebendo fogo pesado!" ], "kg339a": [ - "We're taking heavy casualties, send in backup!" + "Estamos com grandes baixas. Enviando reforços!" ], "kg340a": [ - "This guy knows how to fight!" + "Esse cara sabe como lutar!" ], "kg341a": [ - "Hold your ground!" + "Mantenham-se firmes!" ], "kg342a": [ - "Do not retreat!" + "Não recuem!" ], "kg343a": [ - "We lost Beta squad!" + "Perdemos o esquadrão Beta!" ], "kg344a": [ - "We need more men!" + "Precisamos de mais homens!" ], "kg345a": [ - "He's on the south path!" + "Ele está no caminho sul!" ], "kg346a": [ - "He's in the water!" + "Ele está na água!" ], "kg347a": [ - "He's near the east hut, all units converge!" + "Ele está na cabana leste. Todas as unidades, convergir!" ], "kg348a": [ - "We're gonna lose him!" + "Nós vamos perdê-lo!" ], "kg349a": [ - "Intruder alert, sound the alarm!" + "Alerta intruso, acionar alarme!" ], "kg350a": [ - "The Fortress is under attack!" + "A Fortaleza está sob ataque!" ], "kg351a": [ - "This is our house, boy!" + "Esta é nossa casa, garoto!" ], "kg352a": [ - "You've got brass coming into our Fortress!" + "Você teve coragem de vim pra nossa Fortaleza!" ], "kg353a": [ - "You won't get out of here alive!" + "Você não sairá daqui vivo!" ], "kg354a": [ - "Thanks for making this easy." + "Obrigado por facilitar tudo." ], "kg355a": [ - "We're taking heavy casualties." + "Estamos tendi baixas pesadas." ], "kg356a": [ - "He's getting in deep, stop him!" + "Ele está indo a fundo, impeça-o!" ], "kg357a": [ - "Take this guy out, that's an order!" + "Finalize ele, isso é uma ordem!" ], "kg358a": [ - "Send in the shock squad!" + "Enviem o esquadrão de choque!" ], "kg359a": [ - "Bring in the heavy firepower!" + "Tragam o poder de fogo pesado!" ], "kg360a": [ - "Send in the shield guards!" + "Enviem os guardas de escudo!" ], "kg361a": [ - "I'm on him!" + "Eu estou nele!" ], "kg362a": [ - "Let me at 'em!" + "Deixe-me ir até eles!" ], "kg363a": [ - "I got 'em!" + "Eu os peguei!" ], "kg364a": [ - "Finish him off!" + "Finalize-o!" ], "kg365a": [ - "He's moving toward the ammo room!" + "Ele está indo em direção à sala de munições!" ], "kg366a": [ - "Intercept the intruder before he gets in too far!" + "Impeçam o intruso antes que ele vá longe demais!" ], "kg367a": [ - "He's picking up a suspect." + "Ele está pegando um suspeito." ], "kg368a": [ - "He's got an Underground agent with him!" + "Ele tem um agente Subterrâneo com ele!" ], "kg369a": [ - "Take 'em both out!" + "Acabe com os dois!" ], "kg370a": [ - "He's picked up another suspect." + "Ele pegou outro suspeito." ], "kg371a": [ - "We lost the guy he dropped off!" + "Perdemos o cara que ele desistiu!" ], "kg372a": [ - "He's got a passenger." + "Ele tem um passageiro." ], "kg373a": [ - "Driver is working with the Underground." + "O motorista está trabalhando com o Subterrâneo." ], "kg374a": [ - "Suspect vehicle taking damage, but still moving." + "Veículo suspeito levando dano, mas ainda segue." ], "kg375a": [ - "We need to cut 'em off!" + "Nós precisamos pará-los!" ], "kg376a": [ - "He's got another agent!" + "Ele tem outro agente!" ], "kg377a": [ - "Suspect driving erratically!" + "Suspeito dirigindo irregularmente!" ], "kg378a": [ - "Suspect still evading!" + "Suspeito ainda desviando!" ], "kg379a": [ - "We got 'em this time!" + "Pegamos eles dessa vez!" ], "kg380a": [ - "Suspect vehicle destroyed!" + "Veículo suspeito destruído!" ], "kg381a": [ - "He's going for another vehicle!" + "Ele está indo para outro veículo." ], "kg382a": [ - "We took 'em out!" + "Nós os pegamos!" ], "kg383a": [ - "He's toast!" + "Ele está frito!" ], "kg384a": [ - "Another win for the KG, good shooting, men." + "Outra vitória ao KG. Boa artilharia, homens." ], "kg385a": [ - "Suspect has evaded capture." + "Suspeito se safou da captura." ], "kg386a": [ "Ough!" @@ -6196,28 +6200,28 @@ "Haugh!" ], "kg393a": [ - "Oof!" + "Ufa!" ], "kg394a": [ - "Hah!" + "Há!" ], "kg395a": [ "Ugh!" ], "kg396a": [ - "Hah!" + "Há!" ], "kg397a": [ "Ugh!" ], "kg398a": [ - "Huff!" + "Ufa!" ], "kg399a": [ "Argh!" ], "kg400a": [ - "Hah!" + "Há!" ], "kg401a": [ "Huh!" @@ -6250,7 +6254,7 @@ "Nargh!" ], "kg411a": [ - "Hah!" + "Há!" ], "kg412a": [ "Ugh...!" @@ -6301,108 +6305,108 @@ "Ugh!" ], "kg428a": [ - "Oof!" + "Ufa!" ], "kgv001": [ - "Stop!" + "Pare!" ], "kgv002": [ - "Open fire!" + "Abrir fogo!" ], "kgv003": [ - "Move in!" + "Entrar!" ], "kgv004": [ - "Take 'em out!" + "Elimine-os!" ], "kgv005": [ - "Take him down!" + "Elimine-o!" ], "kgv006": [ - "Shoot 'em, shoot 'em!" + "Atire neles, atire neles!" ], "kgv007": [ "Morra, marginal!" ], "kgv008": [ - "Eat this!" + "Toma essa!" ], "kgv009": [ - "Fire, fire!" + "Fogo, fogo!" ], "kgv010": [ "Desista, marginal!" ], "kgv011": [ - "Seal off the area!" + "Isole a área!" ], "kgv012": [ - "Call in reinforcements!" + "Chame reforços!" ], "kgv013": [ - "Riot in progress!" + "Tumulto em progresso!" ], "kgv014": [ - "Call for backup!" + "Solicite reforços!" ], "kgv015": [ - "Stop the vehicle!" + "Pare o veículo!" ], "kgv016": [ - "You are under arrest!" + "Você está preso!" ], "kgv017": [ - "Pull over!" + "Encosta!" ], "kgv018": [ - "Slow down!" + "Reduza a velocidade!" ], "kgv019": [ - "Move over!" + "Sai da frente!" ], "kgv020": [ - "Get out of the vehicle!" + "Saia do veículo!" ], "kgv021": [ - "Call in more Hellcats!" + "Chame mais Hellcats!" ], "kgv022": [ - "Requesting backup!" + "Solicitando reforços!" ], "kgv023": [ - "High speed chase in sector four!" + "Perseguição em alta velocidade no setor quatro!" ], "kgv024": [ - "Suspect in vehicle!" + "Suspeito no veículo!" ], "kgv025": [ - "Suspect fleeing into sector five." + "Suspeito fugindo para o setor cinco." ], "kor001": [ - "I am so proud of you Jak, and you too, Daxter!", - "Together you have done real damage to the Baron.", - "We may win this war yet!" + "Estou tão orgulhoso de você Jak, e você também, Daxter!", + "Juntos, vocês danificaram de verdade o Barão.", + "Nós ainda podemos vencer esta guerra!" ], "kor002": [ - "Excellent work, you are proving to be quite an asset.", - "Without eco, the Baron will soon topple,", - "and the city's future will be in our hands." + "Excelente trabalho, vocês estão provando ser um grande trunfo.", + "Sem o eco, Barão logo mais tombará,", + "e o futuro da cidade estará em nossas mãos." ], "kor004": [ - "Another blow to the Baron, my good friends!", - "Very soon, our fortunes will change!" + "Outro golpe para o Barão, meus bons amigos!", + "Em breve, nossas fortunas mudarão!" ], "krew001": [ - "Jak, this is Krew. I just talked to my racing client", - "and she told me you were pretty good with that JET-Board", - "of hers. My sources say a shipment of Krimzon Guard", - "listening equipment just arrived in the Port.", - "None of us, including the Underground, want those devices", - "up and running. It's not good for business.", - "Ride the JET-Board out into the Port", - "and destroy every Krimzon Guard crate you find.", - "There's sure to be a defense perimeter,", - "so watch out, 'ey?" + "Jac, esta é Krew. Acabei de falar com meu cliente de corrida", + "e ela me disse que você foi muito bem com aquele JET-Board", + "dela. Minhas fontes dizem que um envio de equipamento de escuta", + "da Guarda Krimzon acabou de chegar no Porto.", + "Nenhum de nós, incluindo o Subterrâneo, querem esses dispositivos", + "funcionando. Não é bom para os nossos negócios.", + "Dirija o JET-Board em direção ao Porto", + "e destrua todas caixas da Guarda Krimson que vocês encontrarem.", + "Com certeza há um perímetro de defesa,", + "então tomem cuidado, hein?" ], "krew002": [ "Excelente trabalho, Jak. Até eu estou impressionado.", @@ -6412,83 +6416,83 @@ "alguns guardas com propinas?" ], "krew003": [ - "Ooooh... the bedtime stories were true!", - "The fabled Heart of Mar was hidden inside that ugly statue", - "of the old boy.", - "Nothing fractured, nothing gained! That's my motto. Hahaha...", - "For your loyalty, you'll find an excellent gun upgrade", - "stashed in a crate in the Port." + "Ooooh... as histórias de dormir eram verdades!", + "O lendário Coração de Mar estava escondido dentro daquela estatueta feia", + "Do velho menino.", + "Nada fraturado, nada ganhou! Esse é o meu lema. Haha...", + "Por sua lealdade, encontrará uma melhoria excelente na arma", + "escondido em uma caixa na Porta." ], "krew004": [ - "That's one turret down. Keep looking!" + "Isso é uma torre para baixo. Continue procurando!" ], "krew005": [ - "Two turrets. Good work so far!" + "Duas torres. Muito bom trabalho até agora!" ], "krew006": [ - "Three turrets gone. Nice! Keep it up!" + "Três torres se foram. Ótimo! Continue assim!" ], "krew007": [ - "Four turrets trashed. Haha... Lovely, boys! Go get 'em!" + "Quatro torres para o lixo. Haha... logo... Deus, garotos! Vá pegar!" ], "krew008": [ - "Five turrets down the drain! Keep going." + "Cinco torres descem pelo cano! Continue." ], "krew009": [ - "Six turrets out of commission.", - "Hah, I like the way you work." + "Seis torres para nossa comissão.", + "Hah, eu gosto do jeito que você trabalha." ], "krew010": [ - "Brass work, boys! You destroyed all the turrets, eh?", - "Now, come back to the Hip Hog." + "Trabalho em latão, rapazes! Você destruiu todas as torres, hein?", + "Agora volte ao Hip Hog." ], "kwbf001": [ - "You know I can't play fair!", - "I have a secret weapon: my duplicity field!", - "Say hello to my little friends...", - "Ah, multiple me! Hahahaha... How delightful." + "Você sabe que eu não sei jogar limpo!", + "Eu tenho uma arma secreta: meu campo de duplicidade!", + "Diga olá aos meus amiguinhos...", + "Ah, vários eu! Hahahaha... Que prazer." ], "kwbf002": [ - "Let me introduce you to my... \"crew.\"" + "Deixe-me apresentá-lo a mim... \"CREW\"." ], "kwbf003": [ - "Let's dance!" + "Vamos dançar!" ], "kwbf004": [ - "You will die!" + "Você vai morrer!" ], "kwbf005": [ - "Here we come!" + "Lá vamos nós!" ], "kwbf006": [ - "My, don't my twins look stunning?" + "Meus clones não parecem deslumbrantes?" ], "kwbf007": [ - "You can't stop us all!" + "Você não pode nos impedir todos nós!" ], "kwbf008": [ - "Surprise! More of me than you can handle." + "Surpresa! Mais de mim do que você pode enfrentar." ], "kwbf009": [ - "I've a few good men to help me." + "Eu tenho alguns bons homens para me ajudar." ], "kwbf010": [ - "Get him!" + "Pegue!" ], "kwbf011": [ - "UARGH! Try stopping me now!" + "UARGH! Tente me parar agora." ], "kwbf012": [ - "You're getting lucky so far, 'ey?" + "Você está tendo sorte até agora, olhe?" ], "kwbf013": [ - "I grow weary of this. We end it now." + "Estou cansado disso. Nós terminamos agora." ], "kwbf014": [ "Hm-hm, eu me movo bem rápido para um grandalhão, né?" ], "kwbf015": [ - "I float like a butterfly and sting like a wumpbee!" + "Eu flutuo como uma mariposa e pico como uma vespa!" ], "kwbf016": [ "Urghh!" @@ -6506,240 +6510,240 @@ "Urgh, ow!" ], "kwbf021": [ - "Die!" + "Morra!" ], "kwbf022": [ - "Now I have you!" + "Agora eu tenho vocês!" ], "kwbf023": [ - "You cannot win, Jak!" + "Você não pode vencer, Jak!" ], "kwbf024": [ - "Here's some pain!" + "Sinta um pouco de dor!" ], "kwbf025": [ - "No!" + "Não'!" ], "kwbf026": [ - "You're trying my patience!" + "Você está acabando com minha paciência!" ], "kwbf027": [ - "Stand still!" + "Não se mexa!" ], "kwbf028": [ - "Haha, how did that feel?" + "Haha, que tal isso?" ], "kwbf029": [ - "You should have walked away when you had a chance." + "Você deveria ter ido embora quando teve a chance." ], "kwbf030": [ - "Pop this!" + "Ativar!" ], "kwbf031": [ - "You can't stop the bomb, Jak!" + "Você não pode parar a bomba, Jak!" ], "kwbf032": [ - "Hahahaha, that felt good!" + "Hahahaha, sinta bem isso!" ], "kwbf033": [ - "I am the weapon master!" + "Eu sou o senhor das armas!" ], "kwbf034": [ - "Had enough?" + "Já teve o bastante?" ], "kwbf035": [ - "Here we come!" + "Lá vamos nós!" ], "kwbf036": [ - "Dance for me, Jak!" + "Dance pra mim, Jak!" ], "kwbf037": [ - "You can't get us all!" + "Você não pode pegar todos nós!" ], "kwbf038": [ - "Tag! You're it." + "Marque! Você é ele." ], "kwbf039": [ - "Phew. This is a bit of a workout..." + "Ufa. Isso é um pouco trabalhoso..." ], "kwbf040": [ - "Which is the real me, Jak?" + "Qual é o eu real, Jak?" ], "kwbf041": [ - "Finally... I get to put you in your place!" + "Finalmente... Vou poder te colocar no seu lugar!" ], "kwbf042": [ - "Arghh! You little...!" + "Ora, seu...!" ], "ora006": [ - "Bring me 200 more Metal Head Skull Gems", - "and I will show you another Dark Power." + "Traga-me mais 200 Gemas de Crânio dos Cabeças de Metal", + "e eu lhe mostrarei outro Poder Sombrio." ], "ora007": [ - "Bring me 200 more Skull Gems", - "and another power will be yours to control." + "Traga-me mais 200 Gemas de Crânio", + "e outro poder será seu para controlar." ], "ora008": [ - "Bring me more Skull Gems to receive control", - "over a Dark Power." + "Traga-me mais Gemas de Crânio para receber controle", + "sobre um Poder Sombrio." ], "ora009": [ - "You do not have enough Skull Gems.", - "Come back when you have collected more." + "Você não possui Gemas de Crânio suficientes.", + "Volte quando tiver coletado mais." ], "ora010": [ - "I need more Skull Gems." + "Preciso de mais Gemas de Crânio." ], "ora011": [ - "Trust not your reliance on weapons." + "Não confie na sua dependência de armas." ], "ora012": [ - "Use only your body and brain for this challenge." + "Utilize apenas seu corpo e cérebro para esse desafio." ], "ora013": [ - "Weapons are for the weak." + "Armas são para os fracos." ], "ora014": [ - "You must not use weapons in this challenge." + "Você não deve utilizar armas nesse desafio." ], "pek001": [ - "Groark! I can't believe you actually did this thing!", - "Onin says she will search timelines for answers", - "about these sacred relics. I will find you then." + "Groark! Não acredito que você realmente fez isso!", + "Onin diz que ela irá procurar por linhas do tempo para respostas", + "sobre essas relíquias sagradas. Eu te encontrarei então." ], "pek002": [ - "Groark! Whoa... well I'll be a moncaw's uncle, the Light Tower", - "actually does exist! The beam of light is shining somewhere", - "in the city! The Tomb of Mar was right under our noses", - "all along. And thanks to me, you found it!" + "Groark! Uau... bom, eu serei um tio de um moncaw. A Torre da Luz", + "na verdade existe! O feixe de luz está brilhando em algum lugar", + "na cidade! A Tumba de Mar estava debaixo de nossos narizes", + "o tempo todo. E graças a mim, você encontrou!" ], "pek003": [ - "Wow! As I live and molt, one step closer to the Tomb.", - "I never thought we'd get this far!" + "Uau! Enquanto eu vivo e mudo, um passo mais próximo em direção à Tumba.", + "Nunca imaginei que chegaríamos tão longe!" ], "pek010": [ - "This is Onin's magic bowl.", - "Onin will make symbols appear from her bowl.", - "When the symbols appear, you must pop them before they", - "reach the ground. You must pop them quickly, pop only", - "the symbols you see. If you try to pop a symbol that is", - "not there, Onin will give you a penalty! Miss any symbols", - "and you will penalized! Each round will get faster.", - "Let's see how far you get.", - "You must get a high enough score to win." + "Essa é a tigela mágica de Onin.", + "Onin fará símbolos aparecer de sua tigela.", + "Quando os símbolos aparecerem, você precisa estourá-los antes deles", + "atingirem o chão. Você precisa estourá-los rapidamente, estoure apenas", + "os símbolos que enxergar. Se você tentar estourar um símbolo que", + "não estiver ali, Onin lhe dará uma punição! Falhar quaisquer símbolos", + "irão te penalizar! Cada rodada ficará mais rápido.", + "Vamos ver o quão longe você chega.", + "Você precisa atingir uma pontuação alta o suficiente para ganhar." ], "pek011": [ - "You are doing very well!" + "Você está indo muito bem!" ], "pek012": [ - "Huh, not bad." + "Huh, nada mal." ], "pek013": [ - "Keep going, you can do it!" + "Continue, você consegue!" ], "pek014": [ - "Pop any more than the true number of each symbol,", - "and you will be penalized! Groark!" + "Estoure mais do que o número verdadeiro de cada símbolo", + "e você será penalizado! Groark!" ], "pek015": [ - "Ready? Go!" + "Pronto? Vai!" ], "pek016": [ - "That symbol wasn't there, penalty!" + "Aquele símbolo não estava lá, penalize!" ], "pek017": [ - "Hah, Onin got you! Pop only symbols that you see." + "Há, Onin te pegou! Estoure apenas símbolos que enxergar." ], "pek018": [ - "Here comes another round!", - "Give him another burst, Onin girl!" + "E lá vem mais uma rodada!", + "Dê-lhe outra explosão, garota Onin!" ], "pek019": [ - "She got you again! What is your problem?" + "Ela te pegou de novo! Qual seu problema?" ], "pek020": [ - "I can't believe you've made it this far!" + "Não acredito que você chegou tão longe!" ], "pek021": [ - "Quickly! You are missing symbols!" + "Rápido! Você está perdendo símbolos!" ], "pek022": [ - "You missed some!" + "Você perdeu alguns!" ], "pek023": [ - "Faster! Faster!" + "Mais rápido! Mais rápido!" ], "pek024": [ - "Give it to him, Onin! More, Onin, more!", - "You go, girl, shake what your momma gave you!" + "Dê a ele, Onin! Mais, Onin, mais!", + "Isso aí, garota, balança o que sua mamãe te deu!" ], "pek025": [ - "Rockin' in the club." + "Arrasando no clube." ], "pek026": [ - "He can't do that many!" + "Ele não pode fazer tantos assim!" ], "pek027": [ - "What? He's still going?" + "O quê? Ele continua?" ], "pek028": [ - "Let's see if he can handle it." + "Vamos ver se ele aguenta." ], "pek029": [ - "Go! Come on!" + "Vai! Vamos lá!" ], "pek030": [ - "Okay, so you're good." + "OK, então você é bom." ], "pek031": [ - "Wow! Not bad." + "Uau! Nada mal." ], "pek032": [ - "Well, I laid an egg." + "Bom, eu fiz o que eu pude." ], "pek033": [ - "Amazing! You actually won!", - "I am without words, and that is rare." + "Incrível! Você realmente ganhou!", + "Estou sem palavras, e isso é raro." ], "pek034": [ - "You got enough points, congratulations!" + "Você conseguiu a pontuação suficiente, parabéns!" ], "pek035": [ - "Last penalty! You lose, loser." + "Última penalidade! Você perde, perdedor." ], "pek036": [ - "You lost! Why am I not surprised?" + "Você perdeu! Por que não estou surpreso?" ], "pek037": [ - "You lose! Would you like to try again?" + "Você perdeu! Gostaria de tentar novamente?" ], "pek038": [ - "Ahh, you laid an egg. Too bad, so sad." + "Ahh, você falhou. Tão triste, que chato." ], "pek039": [ - "Oooh, so close... not! Hehehe..." + "Oooh, tão perto... Não! Hehehe..." ], "pek040": [ - "You made a valiant effort, but you suck!" + "Você fez um valente esforço, mas você é péssimo!" ], "pek041": [ - "Game over, finito, done, se acabó!" + "Fim de jogo, finito, acabou, se acabó!" ], "prop002": [ - "As you all know, I was wounded during our last", - "glorious assault against the Metal Head Nest", - "many years ago. I have sacrificed everything", - "for this city and I demand only the same in return!", - "Loyalty will be rewarded,", - "death will await all others." + "Como todos sabem, eu estava machucado durante nosso último", + "glorioso ataque contra o ninho dos Cabeças de Metal", + "muitos anos atrás. Eu sacrifiquei tudo", + "por essa cidade e eu exijo o mesmo de volta!", + "Lealdade será recompensada,", + "morte estará esperando todos os outros." ], "prop003": [ - "The Dark Eco inside you will eventually kill you, Jak.", - "Its destructive effects cannot be stopped.", - "Once you are in its chaotic grip, it will not let you go", - "until you slide into insanity. Turn yourself in, and I will", - "kill you mercifully and painlessly,", - "it is your only way out." + "O Eco Sombrio dentro de você eventualmente te matará, Jak.", + "Seus efeitos destrutivos não podem ser impedidos.", + "Assim que você estiver em seu punho caótico, não deixará você ir", + "ate que chegue à loucura. Entregue-se e eu vou", + "te matar indolor e misericordiosamente,", + "é a sua única saída." ], "prop004": [ "Não tente me fazer de bobo, Jak.", @@ -6751,1107 +6755,1121 @@ "ter morrido na prisão." ], "prop005": [ - "Attention, my loyal citizens! We are looking for a", - "rebel fugitive who has caused the city considerable", - "damage of late. This man is armed and extremely", - "dangerous and can somehow change into a monstrous", - "creature. We have reports he is working with the", - "Metal Heads to subvert your city and your safety.", + "Atenção, meus cidadãos leais! Estamos procurando por um", + "fugitivo rebelde que causou, na cidade, consideráveis", + "danos tardios. Esse homem está armado e é extremamente", + "perigoso e pode, de alguma forma, mudar para uma monstruosa", + "criatura. Temos relatórios que ele está trabalhando com os", + "Cabeças de Metal para desvirtuar sua cidade e segurança.", "Relate todos os avistamentos imediatamente!" ], "prop006": [ - "Brave citizens, today is the anniversary of the great", - "battle that ruined our city section we now call", - "Dead Town. Remember those who died", - "that day and how much we owe the Metal Heads", - "for their treachery! Remember how bravely I fought", - "to save those poor souls of the overrun section", - "and reflect on how grateful you should all be that the", - "Krimzon Guard keeps you safe each day." + "Bravos cidadãos, hoje é aniversário da grande", + "batalha que arruinou nossa seção de cidades que agora chamamos de", + "Cidade Morta. Lembrem-se daqueles que morreram", + "naquele dia e quanto nós devemos aos Cabeças de Metal", + "por suas façanhas! Lembrem-se de como lutei bravamente", + "para salvar aquelas pobres almas da sessão ultrapassada", + "e reflitam no quão gratos vocês deveriam estar que os", + "Guardas Krimzon os mantém a salvo cada dia." ], "prop007": [ - "This is your Baron. The reports of a Metal Head", - "invasion of the city are vastly overblown.", - "I assure you this is but a small incursion and we will", - "defeat it shortly. Stay in your homes, do not panic,", - "or you will be punished!" + "Aqui é seu Barão. Os relatórios de uma invasão", + "dos Cabeças de Metal na cidade são extremamente exageradas.", + "Eu lhes garanto que não é mais do que uma pequena incursão e nós iremos", + "derrotá-la em breve. Fique em suas casas, não entrem em pânico", + "ou serão punidos!" ], "prop008": [ - "Attention citizens, this is your Baron speaking.", - "There have been several unauthorized uses of the", - "city's old gate locks. Fortunately, these breaches", - "have not resulted in contamination, but we all know", - "how deadly the Wasteland is. No one is allowed", - "outside the city without authorization, let it be", - "known that any violators will be caught", - "and executed." + "Atenção aos cidadãos, este é seu Barão falando.", + "Estamos tendo várias utilizações não autorizadas das", + "travas do portão velho da cidade. Felizmente, essas brechas", + "não resultaram em contaminação, mas todos nós sabemos", + "o quão mortal é o Deserto. Ninguém é permitido", + "a sair da cidade sem autorização, esteja", + "avisado que quaisquer violadores serão pegos", + "e executados." ], "prop009": [ - "Serve your city." + "Sirvam sua cidade." ], "prop010": [ - "Sacrifice for your city, and all will prosper!" + "Sacrifiquem-se pela sua cidade e todos prosperarão!" ], "prop011": [ - "You are safe, because I care." + "Vocês estão seguros porque eu me importo." ], "prop012": [ - "All Metal Heads must die!" + "Todos os Cabeças de Metal devem morrer!" ], "prop013": [ - "Work hard, and be grateful." + "Trabalhem duro e sejam agradecidos." ], "prop014": [ - "Report all wrongdoers." + "Relatar todos os malfeitores." ], "prop015": [ - "Remember, even your friends could be enemies." + "Lembrem-se, até mesmo amigos podem ser inimigos." ], "prop016": [ - "Turn in all who subvert." + "Entreguem todos que se desvirtuarem." ], "prop017": [ - "Strength is our only option!" + "Força é nossa única opção!" ], "prop018": [ - "Obey and be happy." + "Obedeçam e sejam felizes." ], "prop019": [ - "Sacrifice is something you should do", - "for your city." + "Sacrifício é algo que vocês devem fazer", + "pela sua cidade." ], "prop020": [ - "Sacrifice for your city." + "Sacrifiquem-se pela sua cidade." ], "prop021": [ - "Remember, even friends might be enemies." + "Lembrem-se, até mesmo amigos podem ser inimigos." ], "prop022": [ - "The city needs your sacrifice." + "A cidade precisa de seu sacrifício." ], "prop023": [ - "It is better inside the walls!" + "É melhor dentro das paredes!" ], "prop024": [ - "The law will show no mercy." + "A lei não mostrará misericórdia." ], "prop025": [ - "Justice is swift." + "A justiça é rápida." ], "prop026": [ - "The Underground movement is dead!" + "O movimento do Subterrâneo está morto!" ], "prop027": [ - "Join the Krimzon Guard and your family", - "will be allowed to stay." + "Junte-se à Guarda Krimzon e sua família", + "poderá ficar." ], "prop028": [ - "One way: My way." + "Uma maneira: Minha maneira." ], "prop029": [ - "To lead is to control." + "Liderar é controlar." ], "prop030": [ - "Give up your freedom and I will protect you." + "Desistam de sua liberdade e eu os protegerei." ], "prop031": [ - "Have faith in me and the Promised Land is yours." + "Tenham fé em mim e a Terra Prometida é de vocês." ], "prop032": [ - "Your city needs a strong leader, not a childish fool." + "Sua cidade precisa de um líder forte, não um tolo infantil." ], "prop033": [ - "Welcome not the unknown face." + "Não deem boas-vindas ao rosto desconhecido." ], "prop034": [ - "Shun those who would defy me!" + "Corte aqueles que me desafiem!" ], "prop035": [ "Eu sou a cara da Cidade Bastião." ], "prop036": [ - "Without my strength, there would be no city." + "Sem minha força, não haverá cidade." ], "prop037": [ - "Follow me to a safer future!" + "Sigam-me para um futuro mais seguro!" ], "prop038": [ - "You are safe inside the walls with me." + "Vocês estão seguros dentro das muralhas comigo." ], "prop039": [ - "Defy... and die." + "Desafiem... e morram." ], "prop040": [ "Bem-vindo à Cidade Bastião!", - "All laws are enforced for your safety.", - "Obey me and you will not be punished." + "Todas as leis são aplicadas em sua segurança.", + "Obedeçam e não serão punidos." ], "prop041": [ - "The city is safe. I will not allow harm", - "to befall you, trust me." + "A cidade está segura. Não permitirei mal", + "caindo perante vocês, confiem em mim." ], "prop042": [ - "Rest assured, I will destroy the Metal Heads.", - "One way or another." + "Podem confiar que eu destruirei os Cabeças de Metal.", + "De uma maneira ou de outra." ], "prop043": [ - "To all citizens, this puny Underground revolt", - "will be dealt with by all aggressive means.", - "We will crush these arrogant upstarts, they will not", - "be allowed to threaten me or this city's order!" + "Para todos os cidadãos, essa insignificante revolta", + "Da resistencia sera esmagada.", + "Nós vamos esmagar estes arruaceiros, eles não irão", + " Eu sou a ordem desta cidade!" ], "prop044": [ - "To all citizens of this great city, there is a monster", - "among you, masquerading as a man!", - "He is dangerous and must be destroyed!", - "I offer a reward of eco for his capture, or, if you", - "have a loved one in prison, I will exchange them for", - "this renegade. I promise." + "Para todos os cidadãos desta grande cidade, há um monstro", + "Entre vocês, mascarando como homem!", + "Ele é perigoso e deve ser destruído!", + "Eu ofereço uma recompensa de eco para a captura dele, ou, se você", + "tem um ente querido na prisão, eu vou trocá-los por", + "Essa renegada. Eu prometo." ], "prop045": [ - "To all who defy me! I am watching you,", - "I am everywhere, I am this city!" + "Todos aqueles que me desafiam! Estou observando você,", + "Eu estou em todo lugar, eu sou esta cidade!" ], "prop046": [ - "This is your Baron. I have been informed by the", - "ministry of extreme labor that worker productivity is", - "down this month! That is unacceptable!", - "I give you safety and this is how you repay me?", - "You must work harder, not smarter!", - "Free the mind and the body will do as it's told,", - "forced labor will set you free!", - "And to help you in your spiritual motivation...", - "quotas are doubled next month!" + "Quem vos fala é seu Barão, fui informado pelo", + "Ministério do trabalho extremo que a produtividade dos trabalhadores", + "Este mês, é inaceitável!", + "Dou-lhe segurança e é assim que me retribuem?", + "Você deve trabalhar mais duro, não mais coerente!", + "Liberte a mente e o corpo fará o que for dito,", + "O trabalho forçado liberará você!", + "E para lhe ajudar na sua motivação espiritual...", + "As quotas duplicarão no mês que vem!" ], "prop047": [ - "Due to recent, uh... \"attrition\" difficulties,", - "this city needs fresh Krimzon Guard recruits!", - "Everyone is asked to volunteer members of their family!", - "Come down to your friendly Fortress facility.", - "Or else!" + "Devido a certos desgastes...", + "A cidade vai precisar de novos recrutas para a Guarda Krimzon!", + "Pedimos que todos se voluntariem!", + "Venha as instalações da fortaleza,", + "Ou senão!" ], "prop048": [ - "As your Baron, I am instituting a \"no hoverboard\" rule", - "in the city! Young delinquents with nothing better", - "to do than float around and do tricks! Huh!", - "I'll put all violators into the Guard and teach them", - "some discipline. No skating, it's the law!" + "Como Barão, criarei uma lei \"anti overboards\"", + "Na cidade! Há jovem delinquentes sem nada melhor", + "Para fazer do que flutuar e fazer truques! Hã!", + "Eu colocarei todos os violadores no Guarda Krimzon e os ensinarei", + "Um pouco de disciplina. Não patine, é a lei!" ], "prop049": [ - "I am disappointed with this city's lack of", - "committment and sacrifice. Work harder! Eat less!", - "Drink only when I tell you! Sleep is optional.", - "We are at war with an outside threat,", - "don't make me declare war on you as well!" + "Estou decepcionado com a falta de compromisso desta cidade ", + "Compromisso e sacrifício. Trabalhe mais! Coma menos!", + "Beba somente quando eu digo, dormir é opcional!", + "Estamos em guerra contra uma ameaça externa,", + "Não me faça declarar guerra com vocês também!" ], "prop050": [ - "Greetings, people of this wonderful utopia. This year's", - "championship race will begin shortly. All citizens", - "not under house arrest are invited to come down to", - "the Stadium and watch your favorite son Erol", - "once again show how the Krimzon Guard are the elite", - "warriors of this city. Bring the whole family! The first", - "one thousand children will get a mandatory", - "Krimzon Guard recruitment package and be", - "\"asked\" to join the Guard for life, what a treat!" + "Saudações, pessoas dessa utopia maravilhosa. Este ano", + "Em breve, terá início a corrida do campeao. Quem", + "Não está em prisão domiciliar são convidados a assistir", + "No Estádio e veja a sua lista de filhos favoritos", + "Mais uma vez mostre como a Guarda Krimzon são a elite", + "Guerreiros desta cidade. Tragam a família inteira!", + "As primeiros mil crianças vão receber", + "Um pacote de recrutamento Krimzon Guard obrigatório", + "Com um \"pedido\" para se juntar à Guarda para a vida toda!", + "Que deleite!" ], "prop051": [ - "This is your Baron, I am still in control!", - "And I assure you, there's absolutely no Metal Heads", - "in the city. Anyone who contradicts this fact...", - "will be shot! The current situation is merely", - "an elaborate propaganda hoax, perpetrated by", - "the outlawed Underground militia trying to", - "subvert our laws and discredit those who protect you", - "while you sleep! Pay no attention to this foolish hoax,", - "there are no Metal Heads within 100 miles of this city!" + "Este é seu Barão, eu ainda estou no controle!", + "E garanto-lhe que não há absolutamente nenhum cabeça de metal", + "na cidade. Qualquer um que contrarie este fato...", + "vai ser alvejado! A situação atual é apenas", + "uma propaganda falsa elaborada, cometido pela", + "milicia ilegal do Subterrâneo tentando", + "subverter nossas leis e discreditar aqueles que te protegem", + "enquanto você dorme! Não preste atenção a esse embuste tolo,", + "não ha Cabelas de Metal dentro de 100 milhas dessa cidade!" ], "prop052": [ - "This is Baron Praxis. We have taken back the city", - "and the Metal Heads are now fleeing before us!", - "Victory is at hand! Continue to fight for the freedom", - "I may some day give you. Continue to defy these", - "enemies of my law and order...", - "and continue to die for me." + "Aqui é Barão Praxis. Nós tomamos a cidade de volta", + "e os Cabeças de Metal agora estão fugindo perante nós!", + "A vitória é eminente! Continuem a lutar pela liberdade", + "que um dia eu possa dar a vocês. Continuem a desafiar esses", + "inimigos da minha lei e ordem...", + "e continuem a morrer por mim." ], "prop053": [ - "Fear not the men in red. Sure, there are occasional", - "complaints about their over-aggressive policing,", - "wanton destruction of people's property during raids,", - "mass-arrests, misplaced loved ones and whatnot.", - "Hey, we're only human! Running a city can be", - "tougher than it looks, imagine how much worse", - "it would be if the Metal Heads were in charge!" + "Não temam o homem de vermelho. Claro, existem ocasionais", + "reclamações sobre suas políticas super agressivas,", + "destruição gratuita das propriedades das pessoas durante os ataques,", + "detenções em massa, entes queridos despedidos e outros.", + "Nós somos só humanos! Dirigir uma cidade pode ser", + "mais difícil do que parece, imaginem o quanto pior", + "Seria se os Cabeças de Metal estivessem no comando!" ], "prop054": [ - "We've had a few incidents with our lower class labor", - "force lately. If your Lurker is acting up, call Krimzon", - "Animal Control. Is your Lurker in a tree? Stuck in a", - "sewer grate? Foaming at the mouth? Call", - "the friendly officers of the K.A.C. and they will deal", - "with your furry slave. with all the love and care it", - "deserves... then haul it away for reconditioning.", - "Remember, Lurkers can be dangerous!" + "Nós tivemos alguns incidentes com a nossa classe inferior", + "força de trabalho ultimamente. Se o seu pregador está agindo,", + "chamar Krimzon Animal Control. Seu Espreitador está em uma árvore?", + "Preso em um esgoto de agradecimento? Começa na boca?", + "Chame os oficiais amigáveis do K.A.C.", + "e eles vão lidar com seu escravo peludo", + "com todo o amor e cuidado que merecem...", + "em seguida, peguem-nos em seguida para se tornar recondicional.", + "Lembre-se, os preguiçosos podem ser perigosos!" ], "prop055": [ - "Please give generously to the Baron eco fund.", - "Your munificent donation wil be used for a variety", - "of humanitarian needs: bombs, guns, armor, genetic", - "alteration research, all in the name of preserving this", - "wonderful city of ours. Give often, give freely...", - "or it will be taken from you!" + "Por favor, dê generosamente ao fundo do Barão.", + "A sua doação será utilizada para", + "uma variedade de necessidades humanitárias,", + "bombas, armas, armaduras, pesquisas de modificação genética", + "tudo em nome de preservar esta", + "maravilhosa cidade nossa. Dê frequentemente, dê livre...", + "ou será tirado de você!" ], "prop056": [ - "It can be so lonely at the top and looking down from", - "up here I can see that this dirty city is in desperate", - "need of revitalization. So, to that end, we", - "will be bulldozing many sections of the city in the", - "coming weeks! All complaints against this", - "construction initiative can be brought,", - "in-person, to the Fortress Prison where they will be", - "\"reviewed.\" Condemned city sections are to", - "be evacuated before razing begins.", - "Anyone still in their homes will be ignored." + "Pode estar tão solitário no topo e olhando para baixo", + "aqui em cima, vejo que esta cidade suja está desesperada", + "Necessita de revitalização, portanto, para esse efeito, nós precisamos", + "Derrubar algumas partes dessa cidade nas", + "próximas semanas! Todas as reclamações contra essa", + "Iniciativa de construção pode ser feita,", + "pessoalmente, para a Prisão da Fortaleza onde eles estarão", + "evacuando os setores condenados", + "antes de começarem a destruir!", + "Qualquer pessoa que ainda se encontre nas suas casas será ignorada." ], "prop057": [ - "The Metal Head attack will not succeed!", - "Your Baron has taken certain measures", - "to guarantee that the Metal Heads will NEVER hold", - "this city for long. Rest assured, I will snatch victory", - "from the jaws of defeat, whatever the cost!", - "I vowed never to let this city fall, and I intend to keep", - "that promise. What must happen is for the good of all!", - "Remember, to die in victory is a glorious", - "badge of honor!" + "Os cabeça de metal não teão sucesso!", + "Seu Barão tomou certas medidas", + "para garantir que as Cabeças de Metal NUNCA irão segurar", + "esta cidade por muito tempo. Fique tranquilo, vou encontrar a vitória", + "nas mandíbulas da derrota, custe o que custar!", + "Eu juro nunca deixar esta cidade cair, e pretendo manter a", + "O que tem de acontecer para o bem de todas!", + "Lembre-se, morrer na vitória é uma glória", + "sinal de honra!" ], "prop058": [ - "This is Baron Praxis. As our city faces its worst threat", - "in three hundred years, I am faced with serious", - "decisions concerning our future. I regret that I have", - "few choices left. I command you all to return to your", - "homes and say goodbye to your families.", - "Be assured, we will not lose this fight, one way", - "or another! The time has come to show these creatures", - "what we're capable of when all hope is lost!", - "It has been a pleasure ruling over you", - "to the end." + "Este é o Barão Praxis, enquanto nossa cidade enfrenta sua pior ameaça", + "em trezentos anos, sou confrontado com sérios", + "decisões sobre o nosso futuro. Lamento ter tido", + "mais algumas escolhas. Eu respondo a todos para que retorne a", + "sa familia", + "Tenha certeza, nós não perderemos essa luta, de uma maneira", + "ou outra! Chegou a hora de mostrar estas criaturas", + "o que somos capazes de fazer quando se perde toda a esperança!", + "Foi um prazer governar sobre si", + "até o fim." ], "sam001": [ - "This is Samos. Jak, I need you to go out to the ruins", - "in Dead Town and visit my old hut. It's now time to retrieve", - "something I hid there long ago, good luck! And Daxter...", - "clean up my place while you're out there!" + "Aqui é Samos. Jak, preciso que você vá para as ruínas", + "na Cidade Morta e visite a minha antiga cabana. Agora é hora de recuperar", + "algo que eu escondi lá há muito tempo, boa sorte! E Daxter...", + "limpe a minha casa enquanto você está lá!" ], "sam002": [ - "This is Samos. Now that you boys are here", - "I want you to get up to my old hut. There is something there", - "that we need! Good luck, and watch our for Metal Heads." + "Aqui é o Samos. Agora que vocês estão aqui", + "Quero que você vá até a minha cabana velha. Tem alguma coisa lá", + "que precisamos! Boa sorte, e fique atento a os cabeças de metal." ], "sam003": [ - "This is Samos, Jak. the Metal Heads must have taken", - "the giant gate ring to their Nest in the Wasteland.", - "If they're ever going to use that ring to open a rift back", - "to our old village, we need to get into the Nest and find it." + "Aqui é o Samos, Jak. Os Cabeças de Metal devem ter tomado", + "Trouxe o grande anel do portal para seu Ninho na Estepe.", + "Se alguma vez eles vão usar esse anel para abrir uma fenda", + "para a nossa antiga aldeia, precisamos entrar no ninho e encontrá-la." ], "sam004": [ - "You did well, Jak. Luckily, the Precursor Stone wasn't in that", - "bomb when it went off or none of us would be here", - "right now. Come back to the race garage", - "as soon as you can." + "Você fez bem, Jak. Felizmente, a Pedra Precursor não estava naquela", + "bomba quando explodiu, se estivesse, nenhum de nós estaria aqui", + "Neste momento, volte para a garagem da corrida", + "Assim que puder." ], "sam005": [ - "Good work so far, boys!", - "Find Young Samos and give him the Life Seed." + "Bom trabalho até agora, rapazes!", + "Encontre o Jovem Samos e dê a ele a Semente da Vida." ], "sam006": [ - "Finally, you got here! Find the Lurker Totem", - "and retrieve a piece of the Seal of Mar on its top." + "Finalmente, você chegou aqui! Encontre o Totem do Lurker", + "e recupere um pedaço do selo de mar em seu topo." ], "sam007": [ - "You've got to get the boy safely to the Power Station, Jak!" + "Você tem que levar o garoto de forma segura até a estação de energia, Jak!" ], "sam008": [ - "Thank you for protecting us, Jak.", - "We'll meet you at the Nest." + "Obrigado por nos proteger, Jak.", + "Nós nos encontraremos com você no ninho." ], "sigc001": [ - "Hold on there, we need to teach you how to use this baby!" + "Espere lá, precisamos ensiná-lo a usar este bebê!" ], "sigc002": [ - "The Scatter Gun is a good short-range weapon", - "with a wide field of fire." + "A Arma Scatter é uma boa arma de curto alcance", + "com um amplo campo de fogo." ], "sigc003": [ "Para disparar a arma, pressione o gatilho." ], "sigc004": [ - "Good! Some kick, huh?" + "Ótimo! nada mal, né?" ], "sigc005": [ - "It's not the fastest firing weapon in the world, though." + "No entanto, não é a arma mais rápida do mundo." ], "sigc006": [ - "You can put your weapon away or pull it out at anytime." + "Você pode deixar sua arma fora ou saca-la a qualquer momento." ], "sigc007": [ - "Try putting the weapon away." + "Tente sacar a arma." ], "sigc008": [ - "Easy, huh?" + "Fácil, não é?" ], "sigc009": [ - "Now take the weapon back out." + "Agora guarde a arma de volta." ], "sigc010": [ - "Good!" + "Ótimo!" ], "sigc011": [ - "You can find red ammo inside Krimzon Guard crates." + "Você pode encontrar munição vermelha dentro de caixas da Guarda Krimzon." ], "sigc012": [ - "Shoot the crates." + "Atire nas caixas." ], "sigc013": [ - "Great, now you're ready!" + "Ótimo, agora você está pronto!" ], "sigc014": [ - "Want to try the Scatter Gun course?" + "Quer testar o curso de Scatter Gun?" ], "sigc015": [ - "The blaster is a good all-around choice", - "with a nice rate of fire." + "O blaster é uma boa escolha em todos os lugares", + "Com uma boa cadencia de tiro" ], "sigc016": [ - "This weapon requires more aiming ability." + "Esta arma requer mais habilidade de mira." ], "sigc017": [ - "You can switch weapon modes at anytime." + "Você pode mudar os modos de arma a qualquer momento." ], "sigc018": [ - "You can find yellow ammo in crates." + "Você pode encontrar munição amarela em caixas." ], "sigc022": [ - "Would you like to test your skills on the gun course?" + "Você gostaria de testar as suas habilidades no curso de arma?" ], "sigc023": [ - "Which course do you want to play?" + "Qual curso você gostaria de jogar?" ], "sigc024": [ - "Shoot every target. The faster you shoot each target", - "the more points you'll get." + "Atire em todos os alvos. Quanto mais rápido você atirar em cada alvo", + "mais pontos que você obterá." ], "sigc025": [ - "Hold your fire on civvies.", - "Hit a friendly target and points will be deducted." + "Nao atire nos cidadaos", + "Acerte um alvo amigável e os pontos serão deduzidos." ], "sigc026": [ - "Good luck." + "Boa sorte." ], "sigc027": [ - "Lock and load. Ready, go!" + "Travado e carregado, vamos lá!" ], "sigc028": [ - "Perfect! You can be my backup any day." + "Perfeito! Você pode voltar quando quiser." ], "sigc029": [ - "You did it, excellent shooting!" + "Você conseguiu, excelente tiro!" ], "sigc030": [ - "Nice shooting! You got potential, kid!" + "Belo tiro! Você tem potencial, rapaz!" ], "sigc031": [ - "Not bad, you'll do." + "Nada mal, isso serve!" ], "sigc032": [ - "Try again, rookie. You're still a bit rusty with that hardware." + "Tente novamente, recruta. Você ainda está um pouco enferrujado com esse hardware." ], "sigc033": [ - "Not bad, but not good. Try again?" + "Não foi ruim, mas não foi bom. Quer tentar de novo?" ], "sigc034": [ - "Close, but in the thick, close won't cut it. Try again?" + "Quase, mas so isso nao basta. Tentar novamente?" ], "sigc035": [ - "Care to try again? Or is your momma calling?" + "Deseja tentar de novo? Ou seu mamãe está ligando?" ], "sigc036": [ - "You're not up to speed yet, try again?" + "Você ainda não é veloz o suficiente, tentar de novo?" ], "sigc037": [ - "You gotta shoot those targets faster!" + "Você precisa atirar naqueles alvos mais rápido!" ], "sigc038": [ - "Be the gun, baby!" + "Seja um só com a arma, bebê!" ], "sigc039": [ - "It's all about reaction time." + "O tempo de reação é tudo." ], "sigc040": [ - "Different gun modes come in handy against different targets." + "Modos diferentes de disparo vêm a calhar contra alvos diferentes." ], "sigc041": [ - "Be cool and you'll rule." + "Seja calmo, e você vencerá" ], "sigc043": [ - "Try switching to the Scatter Gun." + "Tente mudar para a arma dispersora." ], "sigc053": [ - "Faster on the trigger, cherry." + "Mais rápido no gatilho, Querido!" ], "sigc054": [ - "That was a civilian!" + "Isso foi um civil!" ], "sigc055": [ - "I said \"don't shoot civvies,\" itchy finger!" + "Eu disse \"não atire em civis\", segure o dedo!" ], "sigc056": [ - "Great job!" + "Bom trabalho!" ], "sigc057": [ - "Awesome round, I feel sorry for those Metal Heads already." + "Excelente rodada, eu até sinto pena desses cabeças de Metal." ], "sigc058": [ - "That was a sweet round, you make it look easy!" + "Aquela foi uma rodada fácil, você a fez parecer fácil!" ], "sigc059": [ - "You smoked that course!" + "Você acabou com tudo!" ], "sigc060": [ - "The Metal Heads will eat you alive, rookie! Do it over!" + "Os cabeças de metal vão te comer vivo, novato! Acabe com isso!" ], "sigc061": [ - "You need some practice." + "Você precisa praticar mais." ], "sigc062": [ - "I remember my rookie days, keep trying." + "Eu lembro dos meus dias de recruta, continuem tentando." ], "sigc063": [ - "Perfect round! You are the man." + "Rodada perfeita! Você é o cara!" ], "sigc064": [ "Disparo perfeito! Estou impressionado." ], "sigc065": [ - "Whoa, rock and roll, baby! That was a perfect round." + "Uau, rock and roll, bebê! Essa foi uma rodada perfeita." ], "sigc066": [ - "Nice shot!" + "Belo tiro!" ], "sigc067": [ - "Wasted 'em!" + "Que bengala" ], "sigc068": [ - "Very nice! Reminds me of me." + "Muito bom! Me lembra a mim mesmo!" ], "sigc069": [ - "Make 'em fear you." + "Façam com que tenham medo de você." ], "sigc070": [ - "Good combo!" + "Belo combo!" ], "sigc071": [ - "I love seeing you work!" + "Eu adoro te ver trabalhar!" ], "sigc072": [ - "Now switch back to the Blaster." + "Agora, volte ao Blaster." ], "sigc073": [ - "You can combo your attacks by kicking,", - "then firing your weapon." + "Você pode combar seus ataques chutando,", + "então disparando a sua arma." ], "sigc074": [ - "Try a kick-shot combo." + "Tente um combo de chute-tiro" ], "sigc075": [ - "Kick the first target, then shoot while kicking", - "to automatically hit the second target." + "Chute o primeiro alvo, em seguida, atire enquanto chuta", + "para acertar automaticamente o segundo alvo." ], "sigc076": [ - "Great move!" + "Bela manobra!" ], "sigc077": [ - "Not quite, try again. Kick then shoot, almost at the same time." + "Não é assim, tente de novo, chute e atire, ao mesmo tempo" ], "sigc078": [ - "Make sure you shoot while you're kicking to get the combo." + "Certifique-se de atirar enquanto estiver chutando para obter o combo." ], "sigc079": [ - "Give it another shot." + "Tente outra vez." ], "sigc080": [ - "Now that's a Wastelander move!", - "They won't know what hit 'em!" + "É assim que nós, andarilhos, fazemos!", + "Vão cair como moscas!" ], "sigc081": [ - "Think you can handle the Blaster course?" + "Você acha que pode lidar com o Blaster?" ], "sigf001": [ - "You wasted 'em all! I'm still not sure why combat Metal Heads", - "are scouting this close to the city. To be honest,", - "I wasn't sure you could handle this gig, nice work!" + "Você acabou com todos! Ainda não sei o porquê de cabeças de metal", + "tão perto da cidade. Para ser honesto,", + "Não achei que você pudesse dar conta dessa tarefa. Bom trabalho!" ], "sigt003": [ - "Here we go!" + "Então vamos lá!" ], "sigt004": [ - "Follow me!" + "Me sigam!" ], "sigt005": [ - "Get behind me while I toast that tank." + "Fique atrás de mim enquanto eu explodo aquele tanque." ], "sigt006": [ - "Hurry up kid, I don't have all day!" + "Apressem-se rapazes, eu não tenho o dia inteiro!" ], "sigt007": [ - "This way!" + "Por aqui!" ], "sigt008": [ - "Toast those bad boys up ahead." + "Acabe com os inimigos a frente!" ], "sigt009": [ - "Quick! Drop the bridge!" + "Rápido, baixe a ponte!" ], "sigt010": [ - "Jump up and grab the bridge to bring it down." + "Pule e agarre a ponte para baixa-la" ], "sigt011": [ - "Let's get across the bridge before they come back." + "Vamos atravessar a ponte antes que eles voltem." ], "sigt012": [ - "There's our first target, keep the other creatures back", - "while I charge up the Peacemaker." + "Sua primeira missão, contenha as outras criaturas!", + "Enquanto eu carrego o Peacemaker." ], "sigt013": [ - "That's one fried Metal Head." + "Um cabeça de metal a menos" ], "sigt014": [ - "Let's get to the next target." + "Vamos para o próximo alvo." ], "sigt015": [ - "With Metal Heads I say shoot first, ask questions later." + "Com os cabeças de metal eu digo, primeiro atire e depois pergunte" ], "sigt017": [ - "Stay with me!" + "Fique comigo!" ], "sigt019": [ - "Waste the suckers!" + "Mate esses vermes!" ], "sigt020": [ - "Great, kid, great! Don't get cocky." + "Ótimo, criança, ótimo! Não fique se achando" ], "sigt021": [ - "There's the second scumbag, sittin' pretty." + "Aí está o segundo verme, tão calmo." ], "sigt022": [ - "Cover me!" + "Cubra-me!" ], "sigt023": [ - "Boom, baby! One less Metal Head to think about." + "Boom, bebê! menos um Cabeça de Metal para pensar." ], "sigt024": [ - "Next target." + "Próximo alvo." ], "sigt025": [ - "Watch my six, while I toast this bad boy.", - "The trick is to not hit the pipes." + "me cubra , enquanto eu me resolvo com ele.", + "O truque é não acertar os canos." ], "sigt026": [ - "Now that's what I call blowing someone's mind." + "Isso que eu chamo de perder a cabeça" ], "sigt027": [ - "Gotta thread the needle this time." + "Vamos dar corda essa vez" ], "sigt028": [ - "Hahaha, Metal Head flambé." + "Hahaha, Cabeça de Metal Incendiária." ], "sigt029": [ - "Look out! We've got company!" + "Olha lá! Nós temos companhia!" ], "sigt030": [ - "Damn! My gun's jammed, take over!" + "Droga! A minha arma está emperrada," ], "sigt031": [ - "Get 'em while I fix my gun!" + "Pegue enquanto eu conserto minha arma!" ], "sigt032": [ - "Okay, the Peacemaker is back online. Let's move!" + "Certo, o Pacificador está de volta online. Vamos nos mover!" ], "sigt033": [ - "Last target, then we go home." + "Último alvo, vamos ir embora." ], "sigt036": [ - "Here comes trouble." + "Aí vem o problema." ], "sigt037": [ - "Did ya miss me?" + "Sentiu minha falta?" ], "sigt038": [ - "Say \"good night,\" baby." + "Diga \"boa noite\" bebê." ], "sigt039": [ - "Thanks for covering my butt, that was close!" + "Obrigado por cobrir a minha coronha, foi por perto!" ], "sigt043": [ - "Stay with me!" + "Fique comigo!" ], "sigt044": [ - "Stay close or we'll both be dead!" + "Fique perto, ou ambos estaremos mortos!" ], "sigt045": [ - "Get over here and stay close!" + "Chegue aqui e continue perto!" ], "sigt046": [ - "You wanna play, huh?" + "Você quer brincar, né?" ], "sigt047": [ - "Oh, you got games?" + "Ah? voces gostam de brincar??" ], "sigt049": [ - "You cherries can't handle this mission, we're through!" + "Essas cerejinhas não podem lidar com essa missão, nós terminamos!" ], "sigt052": [ - "I don't work with amateurs!" + "Eu não trabalho com amadores!" ], "sigt053": [ - "You're more trouble than you're worth!" + "Você está mais incomodado do que o normal!" ], "sigt054": [ - "Come back when you're serious!" + "Volte quando você for levar a sério!" ], "sigt056": [ - "You want some of this?!" + "Você quer um pouco disso?!" ], "sigt057": [ - "Drop that lift-cap while I hold them off." + "Abaixe a ponte enquanto eu os mantenho afastados." ], "sigt058": [ - "Take 'em all out!" + "Acabe com eles!" ], "sigt059": [ - "Great, no time to celebrate." + "Ótimo, mas sem tempo para comemorar." ], "sigt060": [ - "If I can't shoot it, it's someone else's problem.", - "You do something with those blocks." + "Se eu não posso atirar nisso, é problema de outra pessoa.", + "Você faz alguma coisa com estes blocos." ], "sigt061": [ - "You gotta figure out the blocks, man." + "Você precisa descobrir a figura dos blocos, cara." ], "sigt062": [ - "Did you hear something?" + "Você ouviu algo?" ], "sigt063": [ - "That's one big ugly Metal Head." + "Essa é um grande e feioCabeça de metal." ], "sigt064": [ - "Shootin' this one's only going to get it mad, run!" + "Atirar só vai deixar ele bravo, corre!" ], "sigt065": [ - "See ya on the flipside!" + "Nos vemos do outro lado" ], "sigt066": [ - "Gone with the wind." + "Fui com o vento." ], "sigt067": [ - "Later alligator." + "Ligador mais tarde." ], "sigt068": [ "Acho que essa é a última vez que o veremos." ], "sigt069": [ - "You figure this out, I'll cover your butt." + "Você descobre isso, eu vou cobrir sua bunda." ], "sigt070": [ - "This is your gig, baby. Solve it, so we can go home." + "Este é o seu sorriso, bebê. Resolva-o, para que possamos ir para casa." ], "sigt071": [ - "Great, here comes that bad boy again. Move!" + "Ótimo, aqui vem aquele garoto ruim de novo. Mexa-se!" ], "sigt072": [ - "Run!" + "Corre!" ], "sigt073": [ - "Go, go, go!" + "Vai, vai, vai!" ], "sigt074": [ - "He's gaining!" + "Ele está ganhando." ], "sigt075": [ - "Keep moving!" + "Continue andando!" ], "sigt076": [ - "Faster!" + "Rápido!" ], "sigt077": [ - "It's gonna be close!" + "Oooh, vai ser por pouco!" ], "sigt078": [ - "Move your butts!" + "Mova o traseiro" ], "sigt082": [ - "Buddy, you don't wanna piss me off." + "Amigo, você não quer me irritar." ], "sigt083": [ - "You got a death wish?!" + "Você recebeu um cartaz de morte?\"" ], "sigt087": [ - "Have a little pain right back!" + "isso vai doer um pouco..." ], "sigt089": [ - "Never trust a rookie." + "Nunca confie em um iniciante." ], "sigt090": [ - "We're finished until you guys get serious." + "Nós terminamos até que vocês fiquem falando sério." ], "sigt091": [ - "This mission is obviously out of your league." + "Esta missão está obviamente fora da sua liga." ], "sigt092": [ - "You're wasting my time, this mission is over." + "Você está desperdiçando meu tempo, esta missão acabou." ], "sigt093": [ "Uhh... ugh...." ], "sigt100": [ - "Rage before beauty, buddy." + "Raiva antes da beleza, amigo." ], "sigt101": [ - "Let's move!" + "Andando!" ], "sigt102": [ - "I love the smell of burning metal!" + "Eu adoro o cheiro da queima de metal!" ], "sigt103": [ - "Just a walk in the park." + "Apenas uma caminhada no parque." ], "sigt104": [ - "Follow me!" + "Me sigam!" ], "sigt105": [ - "Let's go!" + "Vamos lá!" ], "sigt106": [ - "This way!" + "Por aqui!" ], "sigt107": [ - "Over here!" + "Está aqui!" ], "sigt108": [ - "Rollin' baby!" + "Vamos!" ], "sigt109": [ - "Blow 'em a kiss of death." + "Deem um beijo da morte." ], "sigt110": [ - "I love dead-heads!" + "Eu adoro cabeças mortas!" ], "sigt111": [ - "Kiss your shiny butt goodbye!" + "Beije sua brilhante bunda e adeus!" ], "sigt112": [ - "Born to kill baby!" + "Nascido para matar, bebê!" ], "sigt113": [ - "Two to the chest, one to the head." + "Dois para o peito, um para a cabeça." ], "spot004": [ - "Come out and cheer for me as I destroy the competition once again on the track.", - "This year's racing final will be to die for, I guarantee more thrills and more spills.", - "This time I want blood!...Bring the kids." + "Saia e torça por mim", + "A medida que destruo a concorrência, mais uma vez na pista.", + "O final de corrida deste ano será a morte", + "Eu garanto mais emoções e mais derramamentos.", + "Desta vez quero sangue! Traga as crianças." ], "tess001": [ - "Hey, guys! This is Tess. Before Krew left, I saw him hide", - "something in the game machine here. Knowing Krew,", - "it's probably something valuable.", - "You might wanna come check it out." + "Ei, pessoal! Este é um tônico. Antes de Krew sair, eu o vi escondendo", + "Algo na máquina de jogos aqui. Conhecendo Krew,", + "Provavelmente é algo valioso.", + "Você pode querer vir logo verificar." ], "tor001": [ - "The operation was a success. All Underground members are safe.", - "Come back to the hideout, I have a new mission for you while we wait for this alert to blow over." + "A operação foi um sucesso.", + "Todos os membros do subsolo estão seguros.", + "Volte para o esconderijo; tenho uma nova missão para você", + "Enquanto esperamos que este alerta pare." ], "tor002": [ - "That should take some heat off the streets. Good work, I couldn't have done it better myself." + "Isso deve tirar algum calor das ruas.", + "Bom trabalho, eu mesmo não poderia ter feito melhor." ], "tor003": [ - "That's it, Jak, you're up! Try not to trigger any alarms, the garrison guards will be tough.", - "Vá até o bloco de celas da prisão e encontre os prisioneiros. Quando chegar lá, ligaremos o Portal de Dobra para tirá-los de lá. Boa sorte." + "É isso, Jak, já está online! Tente não disparar nenhum alarme,", + "Os guardas da guarnição serão resistentes.", + "Chegue ao bloco das celas de prisão e encontre os prisioneiros.", + "Uma vez lá, vamos ligar o Portal de Warp de dentro", + "para que todos voltem para fora. Boa sorte." ], "tor004": [ - "Ok, my old access codes should help Vin turn off the magnetic seal for the Fortress door." + "Ok, meus códigos de acesso antigos devem ajudar Vin a desativar", + "o selo magnético para a porta da fortaleza." ], "tor005": [ - "Jak, this is Torn, the city is under Metal Head attack. There's a large force moving toward the city wall from the ocean.", - "We need people manning the tower gunpods to stop that assault. Meet me at the seaside ocean wall in the Port, hurry!", - "We need every man we can get!" + "Jak, aqui é o Torn, a cidade está sob ataque dos Cabeça de Metal!", + "Há uma grande força movendo-se em direção ao muro da cidade", + "do oceano. Precisamos de pessoas gerenciando os canhões da torre", + "para parar esse ataque. Encontre-me na parede oceânica do mar lateral", + "no Porto. Rápido, precisamos de todo homem que pudermos!" ], "tor007": [ - "Jak, it's a guard roadblock, get out of there!" + "Jak, os guardas bloquearam o caminho! saia dai!" ], "tor008": [ - "They've set up a roadblock, they're onto you!" + "Eles montaram um cerco, eles estão perto de você!" ], "torn024": [ - "More coming in!" + "Tem mais vindo!" ], "tswm001": [ - "You can do it, Daxter!" + "Você consegue, Daxter!" ], "tswm002": [ - "Keep going, Daxter." + "Continue assim, Daxter." ], "tswm003": [ - "Go, go, go!" + "Vai, vai, vai!" ], "tswm004": [ - "Wow! What an animal!" + "Uau! Que animal!" ], "tswm005": [ - "You got it!" + "Você pegou ele!" ], "tswm006": [ - "Nice slam!" + "Belo tiro!" ], "tswm007": [ - "Ooh ho ho, baby!" + "Ooh ho ho, bebê!" ], "tswm008": [ - "Great shot, Daxter!" + "Belo tiro, Daxter!" ], "tswm009": [ - "You're almost there!" + "Falta pouco" ], "tswm010": [ - "You can win, baby!" + "Você pode vencer, bebê!" ], "tswm011": [ - "My hero!" + "Meu herói!" ], "tswm012": [ - "Look at him go!" + "Olhe para la, agora!!" ], "tswm013": [ - "You ARE Orange Lightning!" + "Você é o Raio Laranja!" ], "tswm014": [ - "Just a few more!" + "Só mais alguns!" ], "tswm015": [ - "Hit him again!" + "Acerte ele outra vez!" ], "tswm016": [ - "Yes!" + "Isso!" ], "tswm017": [ - "That's my naughty ottsel!" + "Esse é o meu travesso" ], "tswm018": [ "Oh!" ], "tswm019": [ - "That wasn't good." + "Isso não é bom." ], "tswm020": [ - "Don't hit the red ones!" + "Não bata nos vermelhos!" ], "tswm021": [ "Ooh!" ], "tswm022": [ - "That took points away!" + "Isso joga pontos fora!" ], "tswm023": [ - "You did it!" + "Você conseguiu!" ], "tswm024": [ - "Daxter, you won!" + "Daxter, você ganhou!" ], "tswm025": [ - "Yes! You're the man! I mean... the animal." + "Sim! Você é o homem! Quero dizer... o animal." ], "tswm026": [ - "You beat the game, Daxter!" + "Você venceu o jogo, Daxter!" ], "tswm027": [ - "Where'd you learn to pound like that?" + "Onde você aprendeu a atacar assim?" ], "tswm028": [ - "That was amazing!" + "Aquilo foi incrível!" ], "tswm029": [ - "Pretty good for a little furball." + "Muito bom para um pouco de pelos" ], "tswm030": [ - "Ooh... Not enough points!" + "Ooh... Sem pontos suficientes!" ], "tswm031": [ - "No! You lost..." + "Não! Você perdeu..." ], "tswm032": [ - "Awww... You lost again!" + "Ah... Você perdeu de novo!" ], "tswm033": [ - "So close!" + "Tão perto!" ], "tswm034": [ - "One more time." + "Mais uma vez." ], "tswm035": [ - "You can do it!" + "Você consegue!" ], "tswm036": [ - "You have to try again!" + "Você precisa tentar de novo!" ], "tswm037": [ - "You have to beat the game, Daxter." + "É preciso vencer o jogo, Daxter." ], "tswm038": [ - "Try again!" + "Tenta de novo!" ], "tswm039": [ - "Ah! That was a bad one!" + "Ah! Isso foi ruim!" ], "tswm040": [ - "Don't hit the bad ones, Daxter." + "Não atinja os maus, Daxter." ], "tswm041": [ - "You hit a bad Metal Head." + "Você acertou o Cabeça de Metal." ], "tswm042": [ - "Not again!" + "De novo não!" ], "tswm043": [ - "Oh no!" + "Oh não!" ], "tswm044": [ - "Daxter..! You need more points!" + "Daxter..! Você precisa de mais pontos!" ], "tswm045": [ - "Keep going...!" + "Continue assim...!" ], "tswm046": [ - "Oh, Daxter... did you get your whiskers singed?" + "Ah, Daxter... você teve seus bigodes queimados?" ], "tswm047": [ - "You're gonna score!" + "Você vai marcar!" ], "tswm048": [ - "You're almost there...!" + "Está quase lá..." ], "tswm049": [ - "Just a few more!" + "Só mais alguns!" ], "tswm050": [ - "We have a winner!" + "E temos um campeão!" ], "tswm051": [ - "Oh! That was a bad one." + "Olha só! Foi mau." ], "tswm052": [ - "Don't hit the bad ones, Daxter." + "Não atinja os maus, Daxter." ], "tswm053": [ - "Daxter, you hit a bad Metal Head!" + "Você acertou o Cabeça de Metal!" ], "tswm054": [ - "Daxter, you won!!" + "Daxter, você ganhou!" ], "tswm055": [ - "You did it, fur boy!" + "Você consegue, garoto peludo!" ], "tswm056": [ - "Yes!! You beat the game!" + "Isso!! Você venceu o jogo!" ], "tswm057": [ - "I knew you could do it." + "Eu sabia que você poderia fazer isso." ], "vin002": [ - "Okay, the B-Zone Power Grid is back online.", - "Have fun being killed in the Palace." + "Ok, a Grade de Energia da Zona-B está de ativa de volta.", + "Divirta-se sendo morto no Palácio." ], "vin003": [ - "You destroyed the last of the Metal Head eggs!", - "That should give us a little more eco for the city.", - "Good work!" + "Você destruiu o últimos dos ovos dos cabeças de metal.", + "Isso deveria nos dar um pouco mais de eco para a cidade.", + "Bom trabalho!" ], "vin004": [ "Você ainda não pegou todos os ovos dos Cabeças de Metal!", - "Make sure you get 'em all, or I'm gonna have", - "a nervous breakdown!" + "Certifique-se de pegar todos, ou eu vou ter", + "Um colapso nervoso!" ], "vin011": [ - "Thank goodness you blew up those wells.", - "I sure don't want any more Metal Heads coming around here.", - "Good work, boys! I owe ya one." + "Ainda bem que fez explodir esses poços.", + "Eu tenho certeza que não quero mais cabeças de metal vindo aqui.", + "Bom trabalho, rapazes! Estou em divida com vocês!" ], "vin012": [ - "Good work, guys! The fewer Metal Head eggs", - "we allow to hatch, the fewer of those nasty monsters", - "we'll have to fight!" + "Bom trabalho, pessoal! Quanto menos ovos de cabeça de metal", + "Nós não permitirmos chocar, menos monstros desagradáveis", + "Teremos que matar!" ], "vin013": [ "Jak... Kor...", - "Construction... Site...", - "Ngh..." + "Construção... Site...", + "\"Ngh..." ], "vin014": [ - "Once again you guys have saved my butt!", - "Maybe now I'll get a raise. Or a long vacation.", - "God knows I could use one. Thanks for the help!" + "Mais uma vez, os senhores salvaram meu botão!", + "Talvez agora eu tenha um aumento, ou umas férias longas.", + "Deus sabe que eu poderia precisar. Obrigado pela ajuda!" ], "vin015": [ - "The shield wall is down! I repeat - the shield wall is down!", - "Sabotage! Kor did it!", - "I knew Metal Heads would be the end of me!", - "OH NO! Metal Heads are at the door!!", - "They're breaking through!!", - "Too many of them!! Jak!!! AHHHH!!!" + "A parede do escudo está abaixada! Repito - a parede do escudo está abaixada!", + "Sabotagem?! O Kor fez isso!", + "Eu sabia que os cabeças de Metal seriam o meu fim!", + "OH NÃO! Cabeças de metal estão na entrada!!", + "Eles estão quebrando!", + "Há muitos deles!! Jak!!! AHHHH!!!" ], "ys001": [ - "Excellent work, boys! Come on back to the Hideout,", - "I have another task for you." + "Excelente trabalho, rapazes! Voltem pra cá", + "Para se Esconder, eu tenho outra tarefa para você." ], "ys002": [ - "Nice shooting, my boy!", - "Good work, Jak!", - "We'll all sleep a little easier tonight." + "Belo tiro, garoto!", + "Bom trabalho, Jak!", + "Todos nós vamos dormir um pouco mais fácil hoje à noite." ] }, "speakers": { - "agent": "Agent", + "agent": "Agente", "ashelin": "Ashelin", - "baron": "Baron Praxis", + "baron": "Barão Práxis", "brutter": "Brutter", - "citizen-female": "Citizen", - "citizen-male": "Citizen", - "computer": "Computer", - "darkjak": "Dark Jak", + "citizen-female": "Cidadã", + "citizen-male": "Cidadão", + "computer": "Computador", + "darkjak": "Jak Escuro", "daxter": "Daxter", "errol": "Erol", "grim": "Grim", - "guard": "Krimzon Guard", - "guard-a": "Guard A", - "guard-b": "Guard B", - "jak": "Jak", + "guard": "Guarda krimzon", + "guard-a": "Guarda A", + "guard-b": "Guarda B", + "jak": "Guarda B", "jinx": "Jinx", "keira": "Keira", - "keira-before-class-3": "Mechanic", - "kid": "Kid", - "kor": "Kor", + "keira-before-class-3": "Mecânica ", + "kid": "Criança ", + "kor": "Velho Kor", "krew": "Krew", - "metalkor": "Metal Kor", - "metalkor-before-consite": "Metal Head Leader", + "metalkor": "Metal kor", + "metalkor-before-consite": "Líder dos cabeças de metal", "metalkor-intro": "???", "mog": "Mog", - "onin": "Onin", - "oracle": "Oracle", + "onin": "Opin", + "oracle": "Oráculo", "pecker": "Pecker", "precursor": "Precursor", "samos": "Samos", "sig": "Sig", - "tess": "Tess", + "tess": "Tess ", "torn": "Torn", "vin": "Vin", - "youngsamos": "Young Samos", + "youngsamos": "Jovem Samos", "youngsamos-before-rescue": "Samos" } } diff --git a/game/assets/jak2/subtitle/subtitle_lines_pt-PT.json b/game/assets/jak2/subtitle/subtitle_lines_pt-PT.json index ca518b0ff4..710dbc0f60 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_pt-PT.json +++ b/game/assets/jak2/subtitle/subtitle_lines_pt-PT.json @@ -713,7 +713,8 @@ ], "bb06int": [ "Jak, we need you to take out another group of Bomb Bots.", - "These mobile weapons keep showing up in the city, we gotta take them out as soon as possible." + "These mobile weapons keep showing up in the city,", + "we gotta take them out as soon as possible." ], "bb06win": [ "Another pile of bomb bot scrap metal for the KG", @@ -724,8 +725,10 @@ "You lost an agent! NOT good at all, Jak! Mission failed!" ], "bb07int": [ - "Torn here, I need you to go out and move more of our Agents to new locations in the city.", - "KG spies are watching our every move, so look out for trouble. Good luck." + "Torn here, I need you to go out and move more of our Agents", + "to new locations in the city.", + "KG spies are watching our every move,", + "so look out for trouble. Good luck." ], "bb07win": [ "Nice shuttle work! You're keepin' people alive out there." @@ -737,7 +740,8 @@ "bb08int": [ "Jak, some of our Agents have been compromised again.", "Find each one and take them to special hideouts in the city.", - "The guard patrols are on high alert, so this is going to be a tough one. Keep your head down!" + "The guard patrols are on high alert,", + "so this is going to be a tough one. Keep your head down!" ], "bb08win": [ "That was good driving, Jak.", @@ -4911,10 +4915,10 @@ "Activating security defenses." ], "kg121": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg121a": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg122": [ "I've got civvies in sight." @@ -5689,11 +5693,11 @@ "fighting for the Underground." ], "kg233b": [ - "I'm worried about this new guy fighting for the Underground.", + "I'm worried about this new guy", "fighting for the Underground." ], "kg234": [ - "Yeah, they say he can change into some kind of... monster." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ "Yeah, they say he can change into some kind of monster." @@ -6939,7 +6943,7 @@ ], "prop049": [ "I am disappointed with this city's lack of", - "committment and sacrifice. Work harder! Eat less!", + "commitment and sacrifice. Work harder! Eat less!", "Drink only when I tell you! Sleep is optional.", "We are at war with an outside threat,", "don't make me declare war on you as well!" @@ -6947,13 +6951,14 @@ "prop050": [ "Greetings, people of this wonderful utopia. This year's", "championship race will begin shortly. All citizens", - "not under house arrest are invited to come down to", - "the Stadium and watch your favorite son Erol", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", "once again show how the Krimzon Guard are the elite", - "warriors of this city. Bring the whole family! The first", - "one thousand children will get a mandatory", - "Krimzon Guard recruitment package and be", - "\"asked\" to join the Guard for life, what a treat!" + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ "This is your Baron, I am still in control!", @@ -6984,20 +6989,22 @@ "it would be if the Metal Heads were in charge!" ], "prop054": [ - "We've had a few incidents with our lower class labor", - "force lately. If your Lurker is acting up, call Krimzon", - "Animal Control. Is your Lurker in a tree? Stuck in a", - "sewer grate? Foaming at the mouth? Call", - "the friendly officers of the K.A.C. and they will deal", - "with your furry slave. with all the love and care it", - "deserves... then haul it away for reconditioning.", + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", "Remember, Lurkers can be dangerous!" ], "prop055": [ "Please give generously to the Baron eco fund.", - "Your munificent donation wil be used for a variety", - "of humanitarian needs: bombs, guns, armor, genetic", - "alteration research, all in the name of preserving this", + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", "wonderful city of ours. Give often, give freely...", "or it will be taken from you!" ], @@ -7549,15 +7556,17 @@ "Kiss your shiny butt goodbye!" ], "sigt112": [ - "Born to kill baby!" + "Born to kill, baby!" ], "sigt113": [ "Two to the chest, one to the head." ], "spot004": [ - "Come out and cheer for me as I destroy the competition once again on the track.", - "This year's racing final will be to die for, I guarantee more thrills and more spills.", - "This time I want blood!...Bring the kids." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ "Hey, guys! This is Tess. Before Krew left, I saw him hide", @@ -7566,23 +7575,32 @@ "You might wanna come check it out." ], "tor001": [ - "The operation was a success. All Underground members are safe.", - "Come back to the hideout, I have a new mission for you while we wait for this alert to blow over." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "That should take some heat off the streets. Good work, I couldn't have done it better myself." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "That's it, Jak, you're up! Try not to trigger any alarms, the garrison guards will be tough.", - "Get to the prison cell block and find the prisoners. Once there, we'll turn on the Warp Gate inside to get you all back out. Good luck." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "Ok, my old access codes should help Vin turn off the magnetic seal for the Fortress door." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Jak, this is Torn, the city is under Metal Head attack. There's a large force moving toward the city wall from the ocean.", - "We need people manning the tower gunpods to stop that assault. Meet me at the seaside ocean wall in the Port, hurry!", - "We need every man we can get!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ "Jak, it's a guard roadblock, get out of there!" @@ -7807,8 +7825,8 @@ "Too many of them!! Jak!!! AHHHH!!!" ], "ys001": [ - "Excellent work, boys! Come on back to the Hideout,", - "I have another task for you." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Nice shooting, my boy!", diff --git a/game/assets/jak2/subtitle/subtitle_lines_sv-SE.json b/game/assets/jak2/subtitle/subtitle_lines_sv-SE.json index afcaf059c6..6e2334c017 100644 --- a/game/assets/jak2/subtitle/subtitle_lines_sv-SE.json +++ b/game/assets/jak2/subtitle/subtitle_lines_sv-SE.json @@ -2,207 +2,207 @@ "cutscenes": {}, "other": { "DSbop001": [ - "You sure seem angry, Jak." + "Du verkar verkligen arg, Jak." ], "DSbop002": [ - "Do you remember how to jump?" + "Kommer du ihåg hur man hoppar?" ], "DSbop003": [ - "Jump onto that crate to get over the barricade." + "Hoppa upp på den där lådan för att komma över barrikaden." ], "DSbop004": [ - "Ooh, that's a high ledge!", - "Try jumping once, then jump again while in the air", - "to reach that one." + "Oj, det där är en hög avsats!", + "Försök att hoppa en gång, hoppa sedan igen medan du är i luften", + "för att nå den där." ], "DSbop005": [ - "Good job, see? You still got it!" + "Bra jobbat, se? Du har fortfarande det!" ], "DSbop006": [ - "I never found hide nor hair of Keira or Samos.", - "I don't know where they went." + "Jag såg aldrig skymten av Keira eller Samos.", + "Jag vet inte vart de gick." ], "DSbop007": [ - "I don't know where that crazy rift vehicle took us, but...", - "It's some kind of big city!" + "Jag vet inte var den där galna revbilen tog oss, men...", + "Det är någon slags storstad!" ], "DSbop008": [ - "It's a tough place, Jak. You DO remember", - "how to fight, right? Try breaking that crate with a kick." + "Det är en tuff plats, Jak. Du minns", + "hur man slåss, eller hur? Prova att förstöra den där lådan med en spark." ], "DSbop009": [ - "Looking good, partner! Nice spin kick!", - "Works out some of that anger, eh?" + "Ser bra ut, partner! Snygg snurrspark!", + "Får ut lite av den där ilskan, va?" ], "DSbop010": [ - "There are lots of Krimzon Guard crates lying around", - "for the taking. Break that crate!" + "Det finns massor av Krimzon Guard-lådor som ligger häromkring", + "för att ta. Förstör den där lådan!" ], "DSbop011": [ - "Good job! That crate had a health pack inside.", - "Pick it up, you'll wanna keep healthy, Jak, or uh heh...", - "who'll do the fighting?" + "Bra jobbat! Den lådan hade ett hälsopaket inuti.", + "Plocka upp det, du vill hålla frisk, Jak, eller eh heh...", + "Vem slåss?" ], "DSbop016": [ - "If you jump then dive, you'll crash down to the ground", - "hard enough to break lots of things.", - "Breaking stuff's fun, right?" + "Om du hoppar sedan dyker, kommer du krascha ner till marken", + "tillräckligt hårt för att bryta massor av saker.", + "Bryta sönder saker är roligt, eller hur?" ], "DSbop017": [ - "Guards, Jak! Do your, uh... stuff." + "Vakter, Jak! Gör din, eh... grej." ], "agnt001": [ - "Hey hey, drive carefully!" + "Hallå, kör försiktigt!" ], "agnt002": [ - "Look out!" + "Se upp!" ], "agnt003": [ - "Watch it!" + "Se upp!" ], "agnt004": [ "Whoa whoa whoa whoa!" ], "agnt005": [ - "Whoa!" + "Oj!" ], "agnt006": [ - "You're crazy!" + "Du är galen!" ], "agnt007": [ - "Are you out of your mind!?" + "Är du helt från vettet!?" ], "agnt008": [ - "Watch out!" + "Se upp!" ], "agnt009": [ - "That one hurt!" + "Den där gjorde ont!" ], "agnt010": [ - "Stay sharp, we've got a tough part of town coming up." + "Håll dig skarp, vi har en tuff del av staden framför oss." ], "agnt011": [ - "Now we're in for it!" + "Nu är vi i knipa!" ], "agnt012": [ - "You're wasting citizens!" + "Du dödar civila!" ], "agnt013": [ - "Don't hit the civvies, man!" + "Kör inte på dom civila, mannen!" ], "agnt014": [ - "Man, you are hitting people!" + "Mannen, du kör på folk!" ], "agnt015": [ - "Look where you're going!" + "Titta vart du är på väg!" ], "agnt016": [ - "Go man!" + "Kör mannen!" ], "agnt017": [ - "Keep your head down!" + "Håll huvudet nere!" ], "agnt018": [ - "They're shooting at us!" + "De skjuter på oss!" ], "agnt019": [ - "We are dead if you don't drive faster!" + "Vi är döda om du inte kör snabbare!" ], "agnt020": [ - "Keep going!" + "Fortsätt!" ], "agnt021": [ - "Do it, man, do it!" + "Gör det, mannen, gör det!" ], "agnt022": [ - "Hurry up, man!" + "Skynda dig, mannen!" ], "agnt023": [ - "I ain't riding on the back, pick up a two-seater!" + "Jag rider inte på ryggen, plocka upp en två-sitsare!" ], "agnt024": [ - "Get a bigger car!" + "Skaffa en större bil!" ], "agnt025": [ - "Get a bigger vehicle." + "Skaffa ett större fordon." ], "agnt026": [ - "Get one with two seats, will ya?" + "Skaffa en med två platser" ], "agnt027": [ - "Get another vehicle." + "Skaffa ett annat fordon." ], "agnt028": [ - "They're onto us." + "De är på oss." ], "agnt029": [ - "We're being followed." + "Vi blir förföljda." ], "agnt030": [ - "We're taking a beating!" + "Vi tar skada!" ], "agnt031": [ - "We can't take much more of that!" + "Vi kan inte ta så mycket mer av det!" ], "agnt032": [ - "Are you trying to die!?" + "Försöker du att dö!?" ], "agnt033": [ - "Where did Torn find you?" + "Var hittade Torn dig?" ], "agnt034": [ - "You sure you're on our side?" + "Du är säker på att du är på vår sida?" ], "agnt035": [ - "Turn, TURN!" + "Sväng, SVÄNG!" ], "agnt036": [ - "Good move." + "Bra drag." ], "agnt037": [ - "Death to the Baron!" + "Död till baronen!" ], "agnt038": [ - "Thank Mar you're here, Krimzon Guards are everywhere!" + "Tacka Mar att du är här, Krimzon-vakter är överallt!" ], "agnt039": [ - "It's about time, let's get out of here!" + "Det är på tiden, låt oss dra härifrån!" ], "agnt040": [ - "Good, good, just in time. GO, GO, GO!" + "Bra, bra, precis i tid. KÖR, KÖR, KÖR!" ], "agnt041": [ - "Finally, we need to move!" + "Äntligen, vi måste dra!" ], "agnt042": [ - "Man, I was beginning to think you wouldn't show up." + "Mannen, jag började tro att du inte skulle dyka upp." ], "agnt043": [ - "Not a moment too soon, let's fly!" + "Inte ett ögonblick för tidigt, låt oss flyga!" ], "agnt044": [ - "Get me to my new safehouse, quickly!" + "Ta mig till mitt nya safehouse, snabbt!" ], "agnt045": [ - "Thanks, good luck!" + "Tack, lycka till!" ], "agnt046": [ - "Good driving, go save the rest of our guys." + "Bra körning, dra och rädda resten av våra killar." ], "agnt047": [ - "OK, I'm out of here!" + "OK, jag drar!" ], "agnt048": [ - "See you at the next meeting." + "Ses vid nästa möte." ], "agnt049": [ - "Thanks, you're a life saver." + "Tack, du är en livräddare." ], "agnt050": [ - "This is where I get off." + "Det här är där jag kliver av." ], "agnt051": [ - "I'm glad you're on our side." + "Jag är glad att du är på vår sida." ], "agnt052": [ "Ugh!" @@ -217,160 +217,160 @@ "Ahhh!" ], "agnt056": [ - "Drive carefully!" + "Kör försiktigt!" ], "agnt057": [ - "Look out!" + "Se upp!" ], "agnt058": [ - "Watch it!" + "Se upp!" ], "agnt059": [ - "WHOA!" + "JISSES!" ], "agnt060": [ - "You're crazy!" + "Du är galen!" ], "agnt061": [ - "Are you out of your mind?!" + "Är du helt från vettet?!" ], "agnt062": [ - "Watch out!" + "Se upp!" ], "agnt063": [ - "That one hurt." + "Det där gjorde ont." ], "agnt064": [ - "Stay sharp, we got a tough part of our town coming up." + "Håll dig skarp, vi har en tuff del av staden framför oss." ], "agnt065": [ - "Now we're in for it." + "Nu är vi i knipa." ], "agnt066": [ - "You're wasting citizens!" + "Du dödar civila!" ], "agnt067": [ - "Don't hit the civvies, man!" + "Kör inte på dom civila, mannen!" ], "agnt068": [ - "Man, you're hitting the people!" + "Mannen, du kör på folk!" ], "agnt069": [ - "Look where you're going!" + "Titta vart du är på väg!" ], "agnt070": [ - "Go man, GO!" + "Kör mannen, KÖR!" ], "agnt071": [ - "Keep your head down!" + "Håll huvudet nere!" ], "agnt072": [ - "They're shooting at us!" + "De skjuter på oss!" ], "agnt073": [ - "We're dead if you don't drive faster!" + "Vi är döda om du inte kör snabbare!" ], "agnt074": [ - "Keep going!" + "Fortsätt!" ], "agnt075": [ - "Do it, man, do it!" + "Gör det, mannen, gör det!" ], "agnt076": [ - "Hurry up, man!" + "Skynda dig, mannen!" ], "agnt077": [ - "I ain't riding on the back, pick up a two-seater!" + "Jag rider inte på ryggen, plocka upp en två-sitsare!" ], "agnt078": [ - "Get a bigger vehicle." + "Skaffa ett större fordon." ], "agnt079": [ - "They're onto us!" + "De är efter oss!" ], "agnt080": [ - "We're being followed!" + "Vi blir förföljda!" ], "agnt081": [ - "We're taking a beating!" + "Vi tar skada!" ], "agnt082": [ - "We can't take much more of that." + "Vi kan inte ta så mycket mer av det." ], "agnt083": [ - "You trying to die?" + "Försöker du att dö?" ], "agnt084": [ - "Where'd Torn find you?" + "Var hittade Torn dig?" ], "agnt085": [ - "You sure you're on our side?" + "Du är säker på att du är på vår sida?" ], "agnt086": [ - "Turn, TURN!" + "Sväng, SVÄNG!" ], "agnt087": [ - "Good move!" + "Bra drag!" ], "agnt088": [ - "Death to the Baron!" + "Död till Baronen!" ], "agnt089": [ - "Thank Mar you're here, Krimzon Guards are everywhere!" + "Tacka Mar att du är här, Krimzon-vakter är överallt!" ], "agnt090": [ - "It's about time, let's get out of here!" + "Det är på tiden, låt oss dra härifrån!" ], "agnt091": [ - "Good, just in time, GO, GO, GO!" + "Bra, bra, precis i tid. KÖR, KÖR, KÖR!" ], "agnt092": [ - "Finally, we need to move!" + "Äntligen, vi måste dra!" ], "agnt093": [ - "Man, I was beginning to think you wouldn't show up." + "Mannen, jag började tro att du inte skulle dyka upp." ], "agnt094": [ - "Not a moment too soon, let's fly!" + "Inte ett ögonblick för tidigt, låt oss flyga!" ], "agnt095": [ - "Get me to my new safehouse, quickly!" + "Ta mig till mitt nya safehouse, snabbt!" ], "agnt096": [ - "Thanks, good luck!" + "Tack, lycka till!" ], "agnt097": [ - "Good driving, go save the rest of our guys." + "Bra körning, dra och rädda resten av våra killar." ], "agnt098": [ - "OK, I'm out of here!" + "OK, jag drar!" ], "agnt099": [ - "See ya at the next meeting!" + "Ses vid nästa möte!" ], "agnt100": [ - "Thanks, you're a life-saver." + "Tack, du är en livräddare." ], "agnt101": [ - "This is where I get off." + "Det här är där jag kliver av." ], "agnt102": [ - "I'm glad you're on our side." + "Jag är glad att du är på vår sida." ], "agnt103": [ - "Look out!" + "Se upp!" ], "agnt104": [ - "Hey!" + "Hallå!" ], "agnt105": [ "Augh!" ], "agnt106": [ - "Come on man, you trying to kill me!?" + "Kom igen mannen, försöker du döda mig!?" ], "agnt107": [ - "Take it easy!" + "Ta det försiktigt!" ], "agnt108": [ "Ughh!" @@ -394,89 +394,89 @@ "Oof!" ], "agnt115": [ - "Okay, buddy, move!" + "Okej, kompis, flytta på dig!" ], "agnt116": [ - "Look out!" + "Se upp!" ], "agnt117": [ - "Keep your eyes on the road!" + "Håll ögonen på vägen!" ], "agnt118": [ - "Watch it!" + "Se upp!" ], "agnt119": [ - "Thanks for the lift." + "Tack för liften." ], "agnt120": [ - "See ya at the next meeting." + "Ses vid nästa möte." ], "agnt121": [ - "Right, let's go!" + "Just det, låt oss gå!" ], "agnt122": [ - "Drive, man, drive!" + "Kör, mannen, kör!" ], "agnt123": [ - "That was close!" + "Det var nära!" ], "agnt124": [ - "You sure you know what you're doing?" + "Är du säker på att du vet vad du gör?" ], "agnt125": [ - "Ok, thanks, good luck." + "Okej, tack, lycka till." ], "agnt126": [ - "Great, let's go." + "Toppen! Låt oss gå." ], "agnt127": [ - "Drive, man, drive!" + "Kör, mannen, kör!" ], "agnt128": [ - "That was close!" + "Det var nära!" ], "agnt129": [ - "You sure you know what you're doing?" + "Är du säker på att du vet vad du gör?" ], "agnt130": [ - "OK, thanks, good luck!" + "Okej, tack, lycka till!" ], "agnt131": [ - "What took you so long?" + "Vad tog dig så lång tid?" ], "agnt132": [ - "Move like you got a purpose, man!" + "Kör som att du har ett syfte, mannen!" ], "agnt133": [ - "GO, GO, the KG are onto us!" + "KÖR, KÖR, KG är efter oss!" ], "agnt134": [ - "Stay sharp, we're almost there!" + "Håll dig skarp, vi är nästan där!" ], "agnt135": [ - "Good, you did well, I'll tell the Shadow we're safe!" + "Bra, du gjorde bra ifrån dig, jag ska berätta för skuggan att vi är säkra!" ], "asha001": [ "Payback's a bitch, and I'm it." ], "asha002": [ - "Watch your ass, I'm only woman on the outside." + "Passa dig, jag är bara kvinna på utsidan." ], "asha003": [ "Let me knock you down to size...", "Not that you have any." ], "asha004": [ - "Small guns don't get me going." + "Små pistoler får inte igång mig." ], "asha005": [ - "That's a tiny gun..." + "Det där är en liten pistol..." ], "asha006": [ - "You don't know who you're dealing with." + "Du vet inte vem du har att göra med." ], "asha007": [ - "I never said you could touch me there." + "Jag sa aldrig att du kunde röra mig där." ], "asha008": [ "Take that!" @@ -485,16 +485,16 @@ "Here's some." ], "asha010": [ - "Ready for another?" + "Redo för en annan?" ], "asha011": [ - "How's that feel?" + "Hur känns det där?" ], "asha012": [ - "Seems like it hurts." + "Verkar som att det gör ont." ], "asha013": [ - "Oh, that hurt." + "Aj, det där gjorde ont." ], "asha014": [ "Ugh!" @@ -509,55 +509,55 @@ "Agh!" ], "asha018": [ - "Hit me again and you'll lose something really valuable!" + "Slå mig igen och du kommer att förlora något riktigt värdefullt!" ], "asha019": [ - "Not smart!" + "Inte smart!" ], "asha020": [ - "Listen, buddy, whose side are you on?" + "Lyssna, kompis, vems sida är du på?" ], "asha021": [ - "Don't make me hurt you." + "Få mig inte att skada dig." ], "asha022": [ - "Do that again and I'll put you down." + "Gör det igen och jag slår ner dig." ], "asha023": [ - "Learn to control your gun, buddy." + "Lär dig att kontrollera din pistol, kompis." ], "asha024": [ - "Where'd you learn to fight?" + "Var har du lärt dig att slåss?" ], "asha025": [ - "Check your targets, mister." + "Sikta bättre, mister." ], "asha026": [ - "Don't do that again." + "Gör inte det där igen." ], "asha027": [ - "Maybe I should be behind you." + "Jag borde kanske stå bakom dig." ], "asha028": [ - "I won't take that!" + "Det där tar jag inte!" ], "asha029": [ - "Another one like that and you'll be singing soprano." + "En annan sådan och du kommer att sjunga sopran." ], "asha030": [ "Have some back." ], "asha031": [ - "Don't do that again!" + "Gör inte det där igen!" ], "asha032": [ - "Nice shooting." + "Bra skott." ], "asha033": [ "Good shooting, blue boy." ], "asha034": [ - "Good work." + "Bra jobbat." ], "asha035": [ "Take 'em all down!" @@ -566,58 +566,58 @@ "Let's get 'em!" ], "asha037": [ - "Here they come!" + "Här kommer de!" ], "asha038": [ - "I need some help!" + "Jag behöver lite hjälp!" ], "asha039": [ - "Man, there are a lot of 'em!" + "Mannen, det finns en hel del av dem!" ], "asha040": [ - "More coming." + "Fler kommer." ], "asha041": [ - "I got him." + "Jag fick honom." ], "asha042": [ - "More firepower!" + "Mer eldkraft!" ], "asha043": [ - "One more down!" + "Ytterligare en ner!" ], "asha044": [ - "Help me out!" + "Hjälp mig!" ], "asha045": [ - "They're out-flanking us!" + "De flankerar oss!" ], "asha046": [ - "We're surrounded!" + "Vi är omringade!" ], "asha047": [ - "Shoot! Shoot!" + "Skjut! Skjut!" ], "asha048": [ - "It's not looking good." + "Det ser inte bra ut." ], "asha049": [ - "Help me!" + "Hjälp mig!" ], "asha050": [ - "Here's one for my father!" + "Här är en för min far!" ], "asha051": [ - "Damn Metal Heads..." + "Jävla metallhuvuden..." ], "asha052": [ - "Bullseye." + "Fullträff." ], "asha053": [ - "There's some more of those things!" + "Det finns några fler av dem!" ], "asha054": [ - "Get 'em all!" + "Ta dom alla!" ], "asha055": [ "Ugh..." @@ -629,218 +629,222 @@ "Hah...agh..." ], "asht002": [ - "You were right, Jak. What my father's doing is wrong.", - "I need to help fix this. If you get to the Weapons Factory,", - "maybe we can stop him. I'll meet you there." + "Du hade rätt, Jak. Vad min far gör är fel.", + "Jag behöver hjälpa till att fixa detta. Om du tar dig till vapenfabriken,", + "kanske vi kan stoppa honom. Jag möter dig där." ], "asht006": [ - "I think now's the time to act.", - "The Metal Heads are so focused on attacking the city,", - "they may have left their nest vulnerable.", - "Jak, you've got to get out to the Wasteland", - "and breach the Nest barrier any way you can.", - "Maybe if you get inside and take out the Metal Head leader", - "the army will collapse. It's a long shot,", - "but it might be our only chance." + "Jag tror att det är dags att agera.", + "Metallhuvudena är så fokuserade på att attackera staden,", + "att de kan ha lämnat sitt bo sårbart.", + "Jak, du måste ta dig ut till Wasteland", + "och bryta dig igenom boets barriär på vilket sätt du än kan.", + "Kanske om du tar dig in och dödar metallhuvudets ledare", + "kommer armén att kollapsa. Det är en chansning", + "men det kan vara vår enda chans." ], "bar001": [ - "Pay no attention to the groundless rumors about", - "low eco supplies. As your Baron, I assure you,", - "the city has an endless supply of eco stores.", - "Those who would say we are running out,", - "are only trying to frighten and subvert!", - "I have everything in control, I command you", - "to have no fear." + "Lägg ingen vikt vid de grundlösa ryktena om", + "låga eco-resurser. Som er Baron, försäkrar jag er,", + "att staden har en oändlig tillgång av eco-resurser.", + "De som skulle säga att vi håller på att få slut,", + "försöker bara att skrämmas och omstörta!", + "Jag har allt under kontroll, jag befaller dig", + "att inte ha någon rädsla." ], "bar004": [ - "Go!" + "Kör!" ], "bb01fail": [ - "I think you should practice more." + "Jag tycker att du borde träna mer." ], "bb01int": [ - "Jak, this is Torn. The Underground needs good drivers", - "for our vehicle missions. Prove your skills on the", - "Ring Challenge and maybe we'll let you in on the action." + "Jak, detta är Torn. The Underground behöver bra förare", + "för våra fordonsuppdrag. Bevisa dina färdigheter på", + "ringutmaningen och kanske kommer vi att låta dig vara med." ], "bb01win": [ - "Not bad, I think we can use ya.", - "Here's a little reward for your effort." + "Inte dåligt, jag tror att vi kan ha användning av dig.", + "Här är en liten belöning för din ansträngning." ], "bb02fail": [ - "You're still a little timid. Try again." + "Du är fortfarande lite blygsam. Försök igen." ], "bb02int": [ - "We'd like to see you prove your driving skills. Take on", - "another Ring Challenge, let's see what you've got." + "Vi skulle vilja se dig bevisa din körförmåga. Ta dig an", + "en annan ringutmaning, låt oss se vad du går för." ], "bb02win": [ - "Not bad. You could be my getaway driver any time." + "Inte dåligt. Du kan vara min flyktförare när som helst." ], "bb03fail": [ - "I knew this one would prove too much for ya. Keep practicing." + "Jag visste att det här skulle visa sig för svårt för dig. Fortsätt öva." ], "bb03int": [ - "The next Ring Challenge will separate the men from the boys.", - "Let's see if you can handle it." + "Nästa ringutmaning kommer att separera män från pojkar.", + "Låt oss se om du klarar det." ], "bb03win": [ - "Very nice driving. I'm starting to think you could really", - "help us, Jak." + "Mycket bra körning. Jag börjar tro att du verkligen skulle kunna", + "hjälpa oss, Jak." ], "bb04fail": [ - "Too bad, I kinda hoped you could do this. Keep trying." + "Synd, jag hoppades på att du kunde göra detta. Fortsätt försöka." ], "bb04int": [ - "Torn here. I don't even know why I'm lettin' you try this", - "Ring Challenge, never beat it myself. I guess I'm morbidly", - "curious. Beat this one and you'll be the best driver", - "the Underground's ever had." + "Torn här. Jag vet inte ens varför jag låter dig pröva denna", + "ringutmaning, klarade aldrig den själv. Jag antar att jag är sjukt", + "nyfiken. Slå den här och du kommer att vara den bästa föraren", + "The Underground någonsin haft." ], "bb04win": [ - "Very nice, Jak! You're the best driver we've ever had." + "Mycket bra, Jak! Du är den bästa föraren vi någonsin haft." ], "bb05fail": [ - "You didn't get all the Bomb Bots, Jak!" + "Du fick inte alla bomb-robotar, Jak!" ], "bb05int": [ - "Jak, reports say more bomb bots are roaming the city.", - "They're a dangerous menace, and I need you to locate", - "and destroy each one before they hurt our interests." + "Jak, rapporter säger att fler bomb-robotar strövar runt i staden.", + "De är ett farligt hot, och jag vill att du hittar", + "och förgör var och en innan de skadar våra intressen." ], "bb05win": [ - "Good work! That oughta put a dent in the Baron's war budget." + "Bra jobbat! Det bör sätta en buckla i Barons krigsbudget." ], "bb06int": [ - "Jak, we need you to take out another group of Bomb Bots.", - "These mobile weapons keep showing up in the city, we gotta take them out as soon as possible." + "Jak, vi behöver dig för att ta ut en annan grupp av bomb-robotar.", + "Dessa mobila vapen dyker upp i staden,", + "vi måste ta ut dem så snart som möjligt." ], "bb06win": [ - "Another pile of bomb bot scrap metal for the KG", - "trash compactors. Mission accomplished, the Underground's", - "most grateful for your service." + "En annan hög av bomb-robot-metallskrot för KG's", + "avfallskomprimatorer. Uppdrag slutfört, The Underground är", + "mycket tacksam för din tjänst." ], "bb07fail": [ - "You lost an agent! NOT good at all, Jak! Mission failed!" + "Du förlorade en agent! INTE bra alls, Jak! Uppdraget misslyckades!" ], "bb07int": [ - "Torn here, I need you to go out and move more of our Agents to new locations in the city.", - "KG spies are watching our every move, so look out for trouble. Good luck." + "Torn här, Jag vill att du drar ut och flyttar fler av våra agenter", + "till nya platser i staden.", + "KG spioner håller ett vaksamt öga på oss,", + "så håll dig borta från problem. Lycka till." ], "bb07win": [ - "Nice shuttle work! You're keepin' people alive out there." + "Bra jobb med skjutsandet! Du håller folk vid liv där ute." ], "bb08fail": [ - "One of our best agents was arrested. The Shadow will NOT be", - "pleased! You failed." + "En av våra bästa agenter arresterades. Skuggan kommer INTE att vara", + "nöjd! Du misslyckades." ], "bb08int": [ - "Jak, some of our Agents have been compromised again.", - "Find each one and take them to special hideouts in the city.", - "The guard patrols are on high alert, so this is going to be a tough one. Keep your head down!" + "Jak, några av våra agenter har blivit avslöjade igen.", + "Hitta var och en och ta dem till speciella gömställen i staden.", + "Vaktpatrullerna är på hög beredskap,", + "så det här kommer att bli tufft. Håll huvudet nere!" ], "bb08win": [ - "That was good driving, Jak.", - "The Underground can breathe a little easier now." + "Det där var bra kört, Jak.", + "The Underground kan andas lite lättare nu." ], "bb09fail": [ - "You took too long, Jak. We're calling off the meeting." + "Du tog för lång tid på dig, Jak. Vi avbokar mötet." ], "bb09int": [ - "Jak, we're having an Underground meeting", - "with some special Agents. Pick up each Agent", - "and bring them to the meeting place quickly." + "Jak, vi har ett Underground möte", + "med några specialagenter. Plocka upp varje agent", + "och ta dem till mötesplatsen snabbt." ], "bb09win": [ - "Fast work, Jak! Some day, we might even", - "invite you to these meetings." + "Snabbt jobbat, Jak! En dag kanske vi", + "bjuder in dig till dessa möten." ], "bb10fail": [ - "Not fast enough, buddy! You've gotta be quick", - "with those deliveries." + "Inte snabbt nog, kompis! Du måste vara snabb", + "med dessa leveranser." ], "bb10int": [ - "Jak, you've got to prove your driving skills once again.", - "One of our Agents dropped off a package,", - "I need it delivered to the Hideout. Immediately." + "Jak, du måste bevisa din körförmåga igen.", + "En av våra agenter lämnade ett paket,", + "jag behöver ha det levererat till Gömstället. Omedelbart." ], "bb10win": [ - "Good work, Jak!" + "Bra jobbat, Jak!" ], "bb11fail": [ - "The package contents didn't make it. Go faster next time!" + "Paketets innehåll klarade inte det. Kör snabbare nästa gång!" ], "bb11int": [ - "Jak, I need you to take a package of eco", - "over to the power station. Get there quickly or the contents", - "will be useless to Vin." + "Jak, jag vill att du tar med dig ett paket eco", + "till kraftstationen. Ta dig dit snabbt annars kommer innehållet", + "vara värdelöst för Vin." ], "bb11win": [ - "Nice driving, Jak." + "Fin körning, Jak." ], "bb12fail": [ - "You didn't push it hard enough, newbie. Try again." + "Du pushade inte tillräckligt hårt, nybörjare. Försök igen." ], "bb12int": [ - "This is Torn, we've got another package delivery", - "for the Stadium. Make it quick!" + "Detta är Torn, vi har ytterligare en paketleverans", + "för Stadiumet. Gör det snabbt!" ], "bb12win": [ - "Not bad driving. You really oughta race", - "in the city championship." + "Ingen dålig körning. Du bör verkligen racea", + "i stadens mästerskap." ], "bb13fail": [ - "You gotta work on your speed, man." + "Du måste jobba på din fart, mannen." ], "bb13int": [ - "I need you to take a valuable item over to Onin.", - "You won't be able to drive the whole way,", - "but you still have to move fast. Good luck." + "Jag vill att du tar en värdefull sak över till Onin.", + "Du kommer inte att kunna köra hela vägen,", + "men du måste fortfarande röra dig snabbt. Lycka till." ], "bb13win": [ - "That's the way to get it done, good work." + "Det är så man får det gjort, bra arbete." ], "bb14fail": [ - "Too late, Jak! The agent is calling it off.", - "You need to reach it faster!" + "För sent, Jak! Agenten avbryter det.", + "Du måste nå det snabbare!" ], "bb14int": [ - "Jak, we have an Agent waiting for a package delivery.", - "Guard spies are watching this guy,", - "so if you don't get to him fast, he'll be arrested.", - "Take the package to him before it's too late." + "Jak, vi har en agent som väntar på en paketleverans.", + "Vaktspioner håller koll på den här killen,", + "så om du inte hinner till honom snabbt nog, kommer han att arresteras.", + "Ta paketet till honom innan det är för sent." ], "bb14win": [ - "Nice work, the delivery was a success. I like your style, Jak." + "Snyggt jobbat, leveransen var en framgång. Jag gillar din stil, Jak." ], "bb15fail": [ - "You screwed up, Jak! You didn't get it to the safe zone", - "as we asked." + "Du misslyckades, Jak! Du fick det inte till den säkra zonen", + "som vi bad om." ], "bb15farr": [ - "Get off the bike and get clear, Jak!!" + "Hoppa av cykeln och ta skydd, Jak!!" ], "bb15int": [ - "Jak, we found a bomb in the Slums", - "that was meant for the Shadow.", - "I need you to pick it up and take it out to the Farm Area", - "where we've marked a safe zone where it can explode.", - "Go quickly." + "Jak, vi hittade en bomb i Slummen", + "som var avsedd för Skuggan.", + "Jag vill att du plockar upp det och tar ut det till farmområdet", + "där vi har markerat en säker zon där den kan explodera.", + "Gå snabbt." ], "bb15win": [ - "That was amazing work, Jak! Thank you, I really mean that." + "Det där var grymt jobbat, Jak! Tack, jag menar det verkligen." ], "bb16fail": [ - "You didn't take out enough guards!", - "We need to hit them harder!" + "Du tog inte ut tillräckligt med vakter!", + "Vi måste slå dem hårdare!" ], "bb16int": [ - "Jak, this is Torn.", - "Erol's elite personal guard are moving through the city.", - "We need to hit them and hit them hard! Take out enough", - "guards before I have to call off the mission.", - "Get too few guards and we'll have missed an opportunity to", - "inflict real damage on our enemies." + "Jak, det här är Torn.", + "Erol's personliga elitvakt rör sig genom staden.", + "Vi måste slå dem och slå dem hårt! Ta ut tillräckligt", + "med vakter innan jag måste ringa av uppdraget.", + "Få för få vakter och vi har missat en möjlighet att", + "skada våra fiender på allvar." ], "bb16win": [ "Great hit 'n' run, Jak! That'll send a message to Erol." @@ -4911,10 +4915,10 @@ "Activating security defenses." ], "kg121": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg121a": [ - "Please advise, subject's description." + "Please advise, suspect's description." ], "kg122": [ "I've got civvies in sight." @@ -5689,11 +5693,11 @@ "fighting for the Underground." ], "kg233b": [ - "I'm worried about this new guy fighting for the Underground.", + "I'm worried about this new guy", "fighting for the Underground." ], "kg234": [ - "Yeah, they say he can change into some kind of... monster." + "Yeah, they say he can change into some kind of monster." ], "kg234a": [ "Yeah, they say he can change into some kind of monster." @@ -6939,7 +6943,7 @@ ], "prop049": [ "I am disappointed with this city's lack of", - "committment and sacrifice. Work harder! Eat less!", + "commitment and sacrifice. Work harder! Eat less!", "Drink only when I tell you! Sleep is optional.", "We are at war with an outside threat,", "don't make me declare war on you as well!" @@ -6947,13 +6951,14 @@ "prop050": [ "Greetings, people of this wonderful utopia. This year's", "championship race will begin shortly. All citizens", - "not under house arrest are invited to come down to", - "the Stadium and watch your favorite son Erol", + "not under house arrest are invited to come down", + "to the Stadium and watch your favorite son Erol", "once again show how the Krimzon Guard are the elite", - "warriors of this city. Bring the whole family! The first", - "one thousand children will get a mandatory", - "Krimzon Guard recruitment package and be", - "\"asked\" to join the Guard for life, what a treat!" + "warriors of this city. Bring the whole family!", + "The first one thousand children will get", + "a mandatory Krimzon Guard recruitment package", + "and be \"asked\" to join the Guard for life!", + "What a treat!" ], "prop051": [ "This is your Baron, I am still in control!", @@ -6984,20 +6989,22 @@ "it would be if the Metal Heads were in charge!" ], "prop054": [ - "We've had a few incidents with our lower class labor", - "force lately. If your Lurker is acting up, call Krimzon", - "Animal Control. Is your Lurker in a tree? Stuck in a", - "sewer grate? Foaming at the mouth? Call", - "the friendly officers of the K.A.C. and they will deal", - "with your furry slave. with all the love and care it", - "deserves... then haul it away for reconditioning.", + "We've had a few incidents with our lower class", + "labor force lately. If your Lurker is acting up,", + "call Krimzon Animal Control. Is your Lurker in a tree?", + "Stuck in a sewer grate? Foaming at the mouth?", + "Call the friendly officers of the K.A.C.", + "and they will deal with your furry slave", + "with all the love and care it deserves...", + "then haul it away for reconditioning.", "Remember, Lurkers can be dangerous!" ], "prop055": [ "Please give generously to the Baron eco fund.", - "Your munificent donation wil be used for a variety", - "of humanitarian needs: bombs, guns, armor, genetic", - "alteration research, all in the name of preserving this", + "Your munificent donation will be used for", + "a variety of humanitarian needs:", + "bombs, guns, armor, genetic alteration research,", + "all in the name of preserving this", "wonderful city of ours. Give often, give freely...", "or it will be taken from you!" ], @@ -7549,15 +7556,17 @@ "Kiss your shiny butt goodbye!" ], "sigt112": [ - "Born to kill baby!" + "Born to kill, baby!" ], "sigt113": [ "Two to the chest, one to the head." ], "spot004": [ - "Come out and cheer for me as I destroy the competition once again on the track.", - "This year's racing final will be to die for, I guarantee more thrills and more spills.", - "This time I want blood!...Bring the kids." + "Come out and cheer for me", + "as I destroy the competition once again on the track.", + "This year's racing final will be to die for,", + "I guarantee more thrills and more spills.", + "This time I want blood! Bring the kids." ], "tess001": [ "Hey, guys! This is Tess. Before Krew left, I saw him hide", @@ -7566,23 +7575,32 @@ "You might wanna come check it out." ], "tor001": [ - "The operation was a success. All Underground members are safe.", - "Come back to the hideout, I have a new mission for you while we wait for this alert to blow over." + "The operation was a success.", + "All Underground members are safe.", + "Come back to the hideout, I have a new mission for you", + "while we wait for this alert to blow over." ], "tor002": [ - "That should take some heat off the streets. Good work, I couldn't have done it better myself." + "That should take some heat off the streets.", + "Good work, I couldn't have done it better myself." ], "tor003": [ - "That's it, Jak, you're up! Try not to trigger any alarms, the garrison guards will be tough.", - "Get to the prison cell block and find the prisoners. Once there, we'll turn on the Warp Gate inside to get you all back out. Good luck." + "That's it, Jak, you're up! Try not to trigger any alarms,", + "the garrison guards will be tough.", + "Get to the prison cell block and find the prisoners.", + "Once there, we'll turn on the Warp Gate inside", + "to get you all back out. Good luck." ], "tor004": [ - "Ok, my old access codes should help Vin turn off the magnetic seal for the Fortress door." + "Okay, my old access codes should help Vin turn off", + "the magnetic seal for the Fortress door." ], "tor005": [ - "Jak, this is Torn, the city is under Metal Head attack. There's a large force moving toward the city wall from the ocean.", - "We need people manning the tower gunpods to stop that assault. Meet me at the seaside ocean wall in the Port, hurry!", - "We need every man we can get!" + "Jak, this is Torn, the city is under Metal Head attack!", + "There's a large force moving toward the city wall", + "from the ocean. We need people manning the tower gunpods", + "to stop that assault. Meet me at the seaside ocean wall", + "in the Port. Hurry, we need every man we can get!" ], "tor007": [ "Jak, it's a guard roadblock, get out of there!" @@ -7807,8 +7825,8 @@ "Too many of them!! Jak!!! AHHHH!!!" ], "ys001": [ - "Excellent work, boys! Come on back to the Hideout,", - "I have another task for you." + "Excellent work, boys! Come on back", + "to the Hideout, I have another task for you." ], "ys002": [ "Nice shooting, my boy!", diff --git a/game/assets/jak2/subtitle/subtitle_meta_en-US.json b/game/assets/jak2/subtitle/subtitle_meta_en-US.json index 5be7d23094..2ce8390479 100644 --- a/game/assets/jak2/subtitle/subtitle_meta_en-US.json +++ b/game/assets/jak2/subtitle/subtitle_meta_en-US.json @@ -13050,11 +13050,18 @@ "speaker": "torn" }, { - "frame_end": 247, + "frame_end": 165, "frame_start": 91, "merge": false, "offscreen": true, "speaker": "torn" + }, + { + "frame_end": 247, + "frame_start": 166, + "merge": false, + "offscreen": true, + "speaker": "torn" } ] }, @@ -13068,15 +13075,15 @@ "speaker": "torn" }, { - "frame_end": 262, - "frame_start": 198, + "frame_end": 197, + "frame_start": 90, "merge": false, "offscreen": true, "speaker": "torn" }, { - "frame_end": 197, - "frame_start": 90, + "frame_end": 262, + "frame_start": 198, "merge": false, "offscreen": true, "speaker": "torn" @@ -13097,18 +13104,32 @@ "bb07int": { "lines": [ { - "frame_end": 150, + "frame_end": 98, "frame_start": 0, "merge": false, "offscreen": true, "speaker": "torn" }, { - "frame_end": 304, + "frame_end": 150, + "frame_start": 99, + "merge": false, + "offscreen": true, + "speaker": "torn" + }, + { + "frame_end": 227, "frame_start": 151, "merge": false, "offscreen": true, "speaker": "torn" + }, + { + "frame_end": 304, + "frame_start": 228, + "merge": false, + "offscreen": true, + "speaker": "torn" } ] }, @@ -13158,11 +13179,18 @@ "speaker": "torn" }, { - "frame_end": 362, + "frame_end": 254, "frame_start": 201, "merge": false, "offscreen": true, "speaker": "torn" + }, + { + "frame_end": 362, + "frame_start": 255, + "merge": false, + "offscreen": true, + "speaker": "torn" } ] }, @@ -36948,7 +36976,7 @@ "speaker": "baron" }, { - "frame_end": 310, + "frame_end": 305, "frame_start": 225, "merge": false, "offscreen": true, @@ -36956,7 +36984,7 @@ }, { "frame_end": 405, - "frame_start": 311, + "frame_start": 306, "merge": false, "offscreen": true, "speaker": "baron" @@ -36969,29 +36997,36 @@ "speaker": "baron" }, { - "frame_end": 625, + "frame_end": 605, "frame_start": 498, "merge": false, "offscreen": true, "speaker": "baron" }, { - "frame_end": 717, - "frame_start": 626, + "frame_end": 689, + "frame_start": 606, "merge": false, "offscreen": true, "speaker": "baron" }, { - "frame_end": 812, - "frame_start": 718, + "frame_end": 785, + "frame_start": 690, + "merge": false, + "offscreen": true, + "speaker": "baron" + }, + { + "frame_end": 906, + "frame_start": 786, "merge": false, "offscreen": true, "speaker": "baron" }, { "frame_end": 966, - "frame_start": 813, + "frame_start": 907, "merge": false, "offscreen": true, "speaker": "baron" @@ -37167,50 +37202,57 @@ "prop054": { "lines": [ { - "frame_end": 102, + "frame_end": 92, "frame_start": 0, "merge": false, "offscreen": true, "speaker": "baron" }, { - "frame_end": 244, - "frame_start": 103, + "frame_end": 215, + "frame_start": 93, "merge": false, "offscreen": true, "speaker": "baron" }, { - "frame_end": 357, - "frame_start": 245, + "frame_end": 343, + "frame_start": 216, "merge": false, "offscreen": true, "speaker": "baron" }, { - "frame_end": 451, - "frame_start": 358, + "frame_end": 440, + "frame_start": 344, "merge": false, "offscreen": true, "speaker": "baron" }, { - "frame_end": 575, - "frame_start": 452, + "frame_end": 530, + "frame_start": 441, "merge": false, "offscreen": true, "speaker": "baron" }, { - "frame_end": 685, - "frame_start": 576, + "frame_end": 616, + "frame_start": 531, + "merge": false, + "offscreen": true, + "speaker": "baron" + }, + { + "frame_end": 721, + "frame_start": 617, "merge": false, "offscreen": true, "speaker": "baron" }, { "frame_end": 787, - "frame_start": 686, + "frame_start": 722, "merge": false, "offscreen": true, "speaker": "baron" @@ -37234,29 +37276,36 @@ "speaker": "baron" }, { - "frame_end": 208, + "frame_end": 186, "frame_start": 112, "merge": false, "offscreen": true, "speaker": "baron" }, { - "frame_end": 340, - "frame_start": 209, + "frame_end": 262, + "frame_start": 187, "merge": false, "offscreen": true, "speaker": "baron" }, { - "frame_end": 439, - "frame_start": 341, + "frame_end": 383, + "frame_start": 263, + "merge": false, + "offscreen": true, + "speaker": "baron" + }, + { + "frame_end": 442, + "frame_start": 384, "merge": false, "offscreen": true, "speaker": "baron" }, { "frame_end": 579, - "frame_start": 440, + "frame_start": 442, "merge": false, "offscreen": true, "speaker": "baron" @@ -39474,19 +39523,33 @@ "spot004": { "lines": [ { - "frame_end": 110, + "frame_end": 39, "frame_start": 0, "merge": false, "offscreen": true, "speaker": "errol" }, { - "frame_end": 305, + "frame_end": 110, + "frame_start": 40, + "merge": false, + "offscreen": true, + "speaker": "errol" + }, + { + "frame_end": 204, "frame_start": 111, "merge": false, "offscreen": true, "speaker": "errol" }, + { + "frame_end": 305, + "frame_start": 205, + "merge": false, + "offscreen": true, + "speaker": "errol" + }, { "frame_end": 407, "frame_start": 306, @@ -39531,80 +39594,143 @@ "tor001": { "lines": [ { - "frame_end": 110, + "frame_end": 57, "frame_start": 0, "merge": false, "offscreen": true, "speaker": "torn" }, { - "frame_end": 246, + "frame_end": 110, + "frame_start": 58, + "merge": false, + "offscreen": true, + "speaker": "torn" + }, + { + "frame_end": 184, "frame_start": 111, "merge": false, "offscreen": true, "speaker": "torn" + }, + { + "frame_end": 246, + "frame_start": 185, + "merge": false, + "offscreen": true, + "speaker": "torn" } ] }, "tor002": { "lines": [ { - "frame_end": 150, + "frame_end": 68, "frame_start": 0, "merge": false, "offscreen": true, "speaker": "torn" + }, + { + "frame_end": 150, + "frame_start": 69, + "merge": false, + "offscreen": true, + "speaker": "torn" } ] }, "tor003": { "lines": [ { - "frame_end": 160, + "frame_end": 95, "frame_start": 0, "merge": false, "offscreen": true, "speaker": "torn" }, { - "frame_end": 386, + "frame_end": 160, + "frame_start": 96, + "merge": false, + "offscreen": true, + "speaker": "torn" + }, + { + "frame_end": 255, "frame_start": 161, "merge": false, "offscreen": true, "speaker": "torn" + }, + { + "frame_end": 316, + "frame_start": 256, + "merge": false, + "offscreen": true, + "speaker": "torn" + }, + { + "frame_end": 386, + "frame_start": 317, + "merge": false, + "offscreen": true, + "speaker": "torn" } ] }, "tor004": { "lines": [ { - "frame_end": 163, + "frame_end": 97, "frame_start": 0, "merge": false, "offscreen": true, "speaker": "torn" + }, + { + "frame_end": 163, + "frame_start": 98, + "merge": false, + "offscreen": true, + "speaker": "torn" } ] }, "tor005": { "lines": [ { - "frame_end": 200, + "frame_end": 105, "frame_start": 0, "merge": false, "offscreen": true, "speaker": "torn" }, { - "frame_end": 380, - "frame_start": 201, + "frame_end": 171, + "frame_start": 106, + "merge": false, + "offscreen": true, + "speaker": "torn" + }, + { + "frame_end": 255, + "frame_start": 172, + "merge": false, + "offscreen": true, + "speaker": "torn" + }, + { + "frame_end": 351, + "frame_start": 256, "merge": false, "offscreen": true, "speaker": "torn" }, { "frame_end": 431, - "frame_start": 381, + "frame_start": 352, "merge": false, "offscreen": true, "speaker": "torn" @@ -40488,18 +40614,18 @@ "ys001": { "lines": [ { - "frame_end": 97, + "frame_end": 76, "frame_start": 0, "merge": false, "offscreen": true, - "speaker": "youngsamos" + "speaker": "youngsamos-before-rescue" }, { "frame_end": 145, - "frame_start": 98, + "frame_start": 77, "merge": false, "offscreen": true, - "speaker": "youngsamos" + "speaker": "youngsamos-before-rescue" } ] }, diff --git a/game/assets/jak2/subtitle/subtitle_meta_fr-FR.json b/game/assets/jak2/subtitle/subtitle_meta_fr-FR.json index bae57b2bf5..34099a8a6c 100644 --- a/game/assets/jak2/subtitle/subtitle_meta_fr-FR.json +++ b/game/assets/jak2/subtitle/subtitle_meta_fr-FR.json @@ -38,33 +38,15 @@ "offscreen": true, "speaker": "errol" }, - { - "frame_end": 588, - "frame_start": 426, - "merge": false, - "offscreen": true, - "speaker": "errol" - }, { "frame_end": 815, - "frame_start": 589, + "frame_start": 426, "merge": false, "offscreen": true, "speaker": "errol" } ] }, - "jakfall": { - "lines": [ - { - "frame_end": 93, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "jak" - } - ] - }, "sam001": { "lines": [ { diff --git a/game/assets/jak2/text/game_base_text_fi-FI.json b/game/assets/jak2/text/game_base_text_fi-FI.json index facd9eb101..8460f70ae5 100644 --- a/game/assets/jak2/text/game_base_text_fi-FI.json +++ b/game/assets/jak2/text/game_base_text_fi-FI.json @@ -1,531 +1,531 @@ { -"0100": "Lopeta", -"0101": "Tauko~", -"0102": "Tekstityksen kieli", -"0103": "Ääniformaatti", -"0104": "Mono", -"0105": "Stereo", -"0106": "Surround", -"0107": "Äänitehosteet", -"0108": "Musiikki", -"0109": "Puhe", -"010a": "Kieli", -"010b": "Värinätoiminto", -"010c": "Vinkit", -"010d": "Keskitä ruutu", -"010e": "Päällä", -"010f": "Pois", -"0110": "Käytä suuntanäppäimiä", -"0111": " English", -"0112": " Fran,cais", -"0113": " Deutsch", -"0114": " Español", -"0115": " Italiano", -"0116": " ~Y~Z~Z~Z~Y~Z~Z~Z~Y~Z~Z", -"0117": " にほんご", -"0118": "Kuvasuhde", -"0119": "Progressiivinen skannaus", -"011a": "Videotila", -"011b": "Peliasetukset", -"011c": "Grafiikan asetukset", -"011d": "Ääniasetukset", -"011e": "4x3", -"011f": "16x9", -"0120": "60Hz", -"0121": "50Hz", -"0122": "Jak II", -"0123": "Poistu demosta", -"0124": "Kyllä", -"0125": "Ei", -"0126": "Takaisin", -"0127": "OK", -"0128": "Seuraava", -"0129": "Edellinen", -"012a": "Jatka tallentamatta", -"012b": "Valitse tallennuspaikka", -"012c": "Valitse ladattava tallennus", -"012d": "Lataa peli", -"012e": "Tallenna peli", -"012f": "Tyhjä", -"0130": "Asetukset", -"0131": "Uusi peli", -"0132": "Paina START-näppäintä", -"0133": "Lopeta peli", -"0134": "Kartta", -"0135": "Valitse aloitus", -"0136": "Ennätykset", -"0137": "1. sija", -"0138": "2. sija", -"0139": "3. sija", -"013a": "4. sija", -"013b": "5. sija", -"013c": "6. sija", -"013d": "7. sija", -"013e": "8. sija", -"013f": "NYFE-leijuri", -"0140": "Luokka 1", -"0141": "Luokka 2", -"0142": "Luokka 3", -"0143": "Harjoitusrata", -"0144": "Haulikko", -"0145": "Läjäytin", -"0146": "Vulkanus-piippu", -"0147": "Rauhantekijä", -"0148": "Oninin haaste", -"0149": "Metallipää-mäiskintä", -"014a": "JET-lauta-haaste", -"014b": "Oninin teltta", -"014c": "Sikahevon saluuna", -"014d": "Stadion", -"014e": "Luokka 1 - käänteinen", -"014f": "Luokka 2 - käänteinen", -"0150": "Luokka 3 - käänteinen", -"0151": "Sataman kisa", -"0152": "Kaupungin kisa", -"0153": "Salaisuudet", -"0154": "Avattu", -"0155": "Poista Jakin pukinparta", -"0156": "Käänteinen maailma", -"0157": "Loputtomat ammukset", -"0158": "Haavoittumattomuus", -"0159": "Sankaritila", -"015a": "Välinäytösten 1. näytös", -"015b": "Välinäytösten 2. näytös", -"015c": "Välinäytösten 3. näytös", -"015d": "Leikekirja", -"015e": "Mega-leikekirja", -"015f": "Leikekirja 3", -"0160": "Tehtävän valinta", -"0161": "Loputon Raivo-Jak", -"0162": "Vulkanus-tykin harjoitusrata", -"0163": "Rauhantekijän harjoitusrata", -"0164": "Käänteiset kisat", -"0165": "Isopäinen Jak", -"0166": "Pienipäinen Jak", -"0167": "Saatavilla", -"0168": "Kerätty", -"0169": "Tehtävät", -"016a": "Valitse esialoitus", -"016b": "Valitse kioski-aloitus", -"016c": "Valitse kohtaus", -"016d": "Tekstitys", -"016e": "Aloita uudelleen", -"016f": "", -"0170": "", -"0171": "Ei mitään", -"0172": "Peli", -"0173": "Aloita/lopeta", -"0174": "Osta", -"0175": "Voitto", -"0176": "Häviö", -"0177": "Kokonaisaika", -"0178": "Kierros ", -"0179": "Palauta painamalla ", -"017a": "Kiireinen", -"017b": "Jatka painamalla ", -"017c": "____~%Suoritetut tehtävät", -"017d": "Suorittamattomat tehtävät", -"017e": "Yritä uudelleen?", -"017f": "Salaisuus saatavilla päävalikosta", -"0180": " = Kyllä, = Ei", -"0181": "Paina puhuaksesi.", -"0182": "Paina käyttääksesi.", -"0183": "Paina matkustaaksesi.", -"0184": "Valitse taso suuntanäppäimellä", -"0185": "Paina poistuaksesi.", -"0186": "Paina pelataksesi.", -"0187": "Halutako pelata uudelleen?", -"0188": "Tehtävä suoritettu", -"0189": "Tehtävä epäonnistui", -"018a": "Yritä uudelleen?", -"018b": "Ruutu ottaa nyt käyttöön 60Hz-tilan", -"018c": "Ruutu ottaa nyt käyttöön progressiivisen skannauksen", -"018d": "Jos kuva näkyy virheellisenä, televisiosi ei tue tätä tilaa", -"018e": "Jos niin käy, odota 10 sekuntia, niin ruutu palautuu takaisin", -"018f": "Ruutu on nyt 60Hz-tilassa", -"0190": "Ruutu on nyt Progresiivinen skannaus -tilassa", -"0191": "Haluatko pitää tämän tilan käytössä?", -"0192": "Levy poistettiin", -"0193": "Syötä Jak II -levy sisään, jotta voit jatkaa pelaamista", -"0194": "Virhe tietojen lukemisessa", -"0195": "Tarkista Jak II -levysi ja yritä uudelleen", -"0196": "Haluatko varmasti lopettaa?", -"0197": "Haluatko aloittaa pelin?", -"0198": "Ei tarpeeksi tilaa muistikortilla Memory__Card__(PS2) paikassa Memory__Card__Slot__~D", -"0199": "Ei Memory__Card__(PS2) liitettynä paikassa Memory__Card__slot__~D", -"019a": "Memory__Card__(PS2) paikassa Memory__Card__slot__~D on alustamaton", -"019b": "Jak II vaatii ~D Kt vapaata tilaa", -"019c": "Syötä Jak II -pelitietoja sisältävä Memory__Card__(PS2) paikkaan Memory__Card__slot__~D", -"019d": "Syötä Memory__Card__(PS2) jossa on tarpeeksi tilaa, muuten pelitietojasi ei voida tallentaa", -"019e": "Ilman alustamista pelitietoja ei voida tallentaa", -"019f": "Tallennetaan tietoja", -"01a0": "Ladataan tietoja", -"01a1": "Alustetaan", -"01a2": "Luodaan tallennustiedostoa", -"01a3": "Älä poista Memory__Card__(PS2) paikassa Memory__Card__slot__~D tai sammuta laitettasi", -"01a4": "Jak II -tallennus on jo olemassa valitsemassasi tiedostossa", -"01a5": "Haluatko korvata sen?", -"01a6": "Alusta?", -"01a7": "Jatka?", -"01a8": "Takaisin?", -"01a9": "Virhe ladattaessa", -"01aa": "Virhe tallentaessa", -"01ab": "Virhe alustaessa", -"01ac": "Virhe luodessa tallennustiedostoa", -"01ad": "Tarkista Memory__Card__(PS2) paikassa Memory__Card__slot__~D", -"01ae": "Tarkista Memory__Card__(PS2) paikassa Memory__Card__slot__~D ja yritä uudelleen", -"01af": "Memory__Card__(PS2) paikasta Memory__Card__slot__~D poistettiin", -"01b0": "Automaattinen tallennus on poistettu käytöstä", -"01b1": "Tallenna pelisi manuaalisesti, niin automaattinen tallennus palautetaan käyttöön", -"01b2": "Jak II -tallennustietoja ei löytynyt kortilta Memory__Card__(PS2) paikassa Memory__Card__slot__~D", -"01b3": "Haluatko luoda uuden Jak II -tallennuksen?", -"01b4": "Kun oheinen kuvake ilmestyy, edistykesi tallennetaan", -"01b5": "Kun tämä kuvake on ruudulla, älä irrota Memory__Card__(PS2) tai sammuta laitettasi", -"01b6": "Pakene linnoituksesta", -"01b7": "Suojele Koria ja lasta", -"01b8": "Nouda lippu aavekaupungista", -"01b9": "Etsi pumppaamon venttiili", -"01ba": "Räjäytä ammukset linnoituksessa", -"01bb": "Kuljeta toimitus Sikahevon saluunaan", -"01bc": "Läpäise haulikon harjoitusrata", -"01bd": "Suojele Sigiä pumppaamolla", -"01be": "Tuhoa tykit viemärissä", -"01bf": "Etsi läjäytin-modi", -"01c0": "Pelasta Vin avolouhoksella", -"01c1": "Voita aika kisatalliin", -"01c2": "Läpäise läjäyttimen harjoitusrata", -"01c3": "Tuhoa munat poralautalla", -"01c4": "Etsi pumppaamon partio", -"01c5": "Nouda rahat Krewille", -"01c6": "Voita JET-lauta-haaste stadionilla", -"01c7": "Etsi Linssi vuoristotemppelissä", -"01c8": "Etsi Siru vuoristotemppelissä", -"01c9": "Etsi Ratas vuoristotemppelissä", -"01ca": "Käynnistä 5 virtakytkintä", -"01cb": "Nouse hissillä palatsiin", -"01cc": "Päihitä paroni palatsissa", -"01cd": "Kuljeta Vastarinnan jäsenet", -"01ce": "Suojele paikkaa aavekaupungissa", -"01cf": "Nappaa tarkkailijat Havenin metsässä", -"01d0": "Saata lapsi voimalaan", -"01d1": "Pelasta vaanijoita Brutterille", -"01d2": "Tuhoa lasti satamalla", -"01d3": "Pysäytä tankkeri", -"01d4": "Tuhoa välineistö kaivannolla", -"01d5": "Räjäytä ecokaivot avolouhoksella", -"01d6": "Tyhjennä viemäri löytääksesi patsaan", -"01d7": "Tuhoa alus poralautalla", -"01d8": "Pelasta vaanijat kaivannolla", -"01d9": "Tapa Metallipäät Havenin metsässä", -"01da": "Voita luokan 3 kisa stadionilla", -"01db": "Nouda sinetin pala kaivannolla", -"01dc": "Nouda sinetin pala vesislummeilla", -"01dd": "Tuhoa 5 Villikissa-leijuria", -"01de": "Voita Oninin haaste", -"01df": "Käytä esineitä Ei-kenenkään-kanjonissa", -"01e0": "Kohtaa testit Marin haudassa", -"01e1": "Avaa holvin ovi Marin haudassa", -"01e2": "Läpäise ensimmäinen miehuuden testi", -"01e3": "Läpäise toinen miehuuden testi", -"01e4": "Päihitä paroni Marin haudassa", -"01e5": "Pelasta ystävät linnoituksesta", -"01e6": "Saata miehet viemärien läpi", -"01e7": "Etsi Rauhantekijä", -"01e8": "Voita luokan 2 kisa stadionilla", -"01e9": "Suojele piilopaikkaa pommiboteilta", -"01ea": "Tutki rakennustyömaa", -"01eb": "Kiipeä rakennustyömaata", -"01ec": "Voita Erol kisahaasteessa", -"01ed": "Tuhoa munat avolouhoksella", -"01ee": "Nouda Elämän siemen aavekaupungissa", -"01ef": "Vie Elämän siemen Havenin metsään", -"01f0": "Suojele Samosia Havenin metsässä", -"01f1": "Tuhoa poralautan torni", -"01f2": "Voita luokan 1 kisa stadionilla", -"01f3": "Tutki palatsia", -"01f4": "Hanki Marin sydän asetehtaalla", -"01f5": "Päihitä Krew asetehtaalla", -"01f6": "Voita peli Sikahevon saluunassa", -"01f7": "Etsi Sig satamanpohjalla", -"01f8": "Saata Sig satamanpohjan läpi", -"01f9": "Puolusta stadionia", -"01fa": "Puolusta vaanijapalloa", -"01fb": "Tuhoa tunnelit satamanpohjalla", -"01fc": "Taistele tiesi pesän muurille", -"01fd": "Löydä Paroni rakennustyömaalla", -"01fe": "Tuhoa pesän muuri", -"01ff": "Tuhoa Metalli-Kor pesällä", -"0200": "Puhu Korille", -"0201": "Puhu Tornille", -"0202": "Puhu Krewille", -"0203": "Puhu Oninille", -"0204": "Puhu Vinille", -"0205": "Puhu Varjolle", -"0206": "Puhu Sigille", -"0207": "Puhu Mekaanikolle", -"0208": "Puhu Keiralle", -"0209": "Puhu Brutterille", -"020a": "Tarkista basaari", -"020b": "Tarkista vesislummit", -"020c": "Mene Ei-kenenkään-kanjonille", -"020d": "Mene Marin hautaan", -"020e": "Voita Metallipää-mäiskintä", -"020f": "Puolusta sataman muuria", -"0210": "Tarkista rakennustyömaa", -"0211": "Hyökkää Metallipäiden pesään", -"0212": "Käy Oraakkelin luona", -"0213": "Haven City", -"0214": "Linnoitus", -"0215": "Laskeutumisalusta", -"0216": "Palatsin katto", -"0217": "Palatsi", -"0218": "Asetehdas", -"0219": "Aavekaupunki", -"021a": "Pumppaamo", -"021b": "Viemäri", -"021c": "Avolouhos", -"021d": "Vuoristotemppeli", -"021e": "Havenin metsä", -"021f": "Poralautta", -"0220": "Marin hauta", -"0221": "Kaivanto", -"0222": "Satamanpohja", -"0223": "Pesä", -"0224": "Hyppää painamalla ", -"0225": "Kieri painamalla liikkeessä", -"0226": "Paina ja sitten uudelleen ilmassa", -"0227": "Hyökkää painamalla tai ", -"0228": "Kieri ja paina sitten syöksyhyppyyn", -"0229": "Hyppää ja paina ilmassa", -"022a": "Paina ja sitten korkeaan hyppyyn", -"022b": "Ammu painamalla ", -"022c": " laittaa aseen pois", -"022d": " tai tuo aseen esiin", -"022e": "Pelaa haulikon harjoitusrata painamalla ", -"022f": " = Haulikon harjoitus~% = Vulkanus-tykin harjoitus", -"0230": "Vaihda asetta painamalla ", -"0231": "Pelaa läjäyttimen harjoitusrata painamalla ", -"0232": " = Läjäyttimen harjoitus~% = Rauhantekijän harjoitus", -"0233": "Potkaise kohdetta ja paina tehdäksesi pikatulisarjan", -"0234": "Ammu laatikoita", -"0235": "Tavoite", -"0236": "Kulta", -"0237": "Hopea", -"0238": "Pronssi", -"0239": "Käytä lautaa painamalla ", -"023a": "Hyppy: Paina ", -"023b": "Kyykkyhyppy: Paina ja sitten ", -"023c": "Voimahyppy: Paina hieman laskeuduttuasi hypystä", -"023d": "Kaideliuku: Paina ja ", -"023e": "Pyörähdys: Paina ja sitten ja ", -"023f": "Voltti: Paina ja sitten ja ", -"0240": "Temppu: Paina ja sitten ja ", -"0241": "Saat paljon pisteitä, jos liu'ut ja teet tempun liukuaksesi uudestaan", -"0242": "Aloita haaste aktivoimalla tuomari", -"0243": "Yritä uudelleen!", -"0244": "Palaa talliin", -"0245": "Tehtävä suoritettu: Palaa Krewin luo", -"0246": "Vaihda leijuvyöhykettä painamalla ", -"0247": "Sukella painamalla pohjassa uidessasi", -"0248": " = Turbo~% tai = Hyppy", -"0249": "Iske Titaaniasulla painamalla ", -"024a": "Tartu Titaaniasulla lohkareisiin painamalla ", -"024b": "Heitä nostetut esineet painamalla ", -"024c": "Paina rampin yläpäässä", -"024d": "Liu'u kaidetta JET-laudalla painamalla tai ", -"024e": "Käytä ja ", -"024f": "Pumppaamo", -"0250": "Avolouhos", -"0251": "Katso traileri", -"0252": " mennäksesi laudan päälle tai pois", -"0253": "Käytä pimeää voimaa painamalla ", -"0254": "Sony Computer Entertainment America~%presents", -"0255": "Sony Computer Entertainment Europe~%presents", -"0256": "Sony Computer Entertainment Korea~%presents", -"0257": "Sony Computer Entertainment Inc.~%presents", -"0258": "A game by", -"0259": "Jak II", -"025a": "Kaksi vuotta myöhemmin...", -"025b": "Viikko myöhemmin...", -"025c": "Asepäivitys hankittu", -"025d": "Haulikko hankittu", -"025e": "Läjäytin-modi mankittu", -"025f": "Vulkanus-piippu hankittu", -"0260": "Rauhantekijä hankittu", -"0261": "Haulikon tulinopeus päivitetty", -"0262": "Aseiden ammuskapasiteetti päivitetty", -"0263": "Aseiden vahinkoa päivitetty", -"0264": "Tehtävä suoritettu", -"0265": "Punainen turvapassi hankittu", -"0266": "Vihreä turvapassi hankittu", -"0267": "Keltainen turvapassi hankittu", -"0268": "Palatsin turvapassi hankittu", -"0269": "Musta turvapassi hankittu", -"026a": "Linssi hankittu", -"026b": "Ratas hankittu", -"026c": "Siru hankittu", -"026d": "Tuo 25 metallipäiden kallohelmeä", -"026e": "Tuo 200 metallipäiden kallohelmeä", -"026f": "Tuo 25 metallipäiden kallohelmeä", -"0270": "Tuo 200 metallipäiden kallohelmeä", -"0271": "Tuo 200 metallipäiden kallohelmeä", -"0272": "Tuo 100 metallipäiden kallohelmeä", -"0273": "Raivopommi: Paina ja sitten ", -"0274": "Raivopurkaus: Paina ja sitten ", -"0275": "Raivo-Jak on nyt haavoittumaton!", -"0276": "Raivojätti: Paina raivotilassa", -"0277": "Ohi", -"0278": "Valitse tapahtuma", -"0279": "Skeittipuisto", -"027a": "Luokan 3 kisa", -"027b": "Luokan 2 kisa", -"027c": "Luokan 1 kisa", -"027d": "Käänteinen luokan 3 kisa", -"027e": "Käänteinen luokan 2 kisa", -"027f": "Käänteinen luokan 1 kisa", -"0280": "Daxter saa suupalan", -"0281": "Tavataan Torn", -"0282": "Noutamassa lippua", -"0283": "Suojele pyhää paikkaa", -"0284": "Meidän maailmamme!", -"0285": "Vanhoja muistoja", -"0286": "Vin tarvitsee apua", -"0287": "Tavataan Vin", -"0288": "Hyviä ja huonoja uutisia", -"0289": "Suuri murskaus", -"028a": "Meillä on yhä ongelmia", -"028b": "Kaivot posahtavat!", -"028c": "Tavataan Kor ja lapsi", -"028d": "Vastarinta", -"028e": "Villikissa-tehtävä", -"028f": "Tornin toimitus", -"0290": "Tavataan Krew ja Sig", -"0291": "Yllätyshyökkäys!", -"0292": "Ashelin on huolissaan", -"0293": "Vin, kamu. Tarvitsemme palveluksen.", -"0294": "Kuka on verhojen takana?", -"0295": "Tiedonjyvä", -"0296": "Iloinen jälleennäkeminen", -"0297": "Kissatappelu", -"0298": "Jak poistuu paikalta", -"0299": "Daxterin suuri voitto", -"029a": "Keira paljastaa suunnitelmansa", -"029b": "Suuri kilpailu", -"029c": "Voittajan piiri", -"029d": "Tavataan Oraakkeli", -"029e": "Jak saa pimeän voiman", -"029f": "Jak saa toisen pimeän voiman", -"02a0": "Jak saa kolmannen pimeän voiman", -"02a1": "Jak saa neljännen pimeän voiman", -"02a2": "Valitus, naiset, ja laulu", -"02a3": "Rahankerääjät", -"02a4": "Mikä tämän lapsen tarina on?", -"02a5": "Krewilla on uusi keikka", -"02a6": "Tavataan Brutter", -"02a7": "Krewin kilpailusopimus", -"02a8": "Mitä te kaksi oikein teitte?", -"02a9": "Oninin haaste", -"02aa": "Marin sinetti on valmis", -"02ab": "Pelasta lisää vaanijoita", -"02ac": "Suojele piilopaikkaa", -"02ad": "Krew uhkailee", -"02ae": "Pelaaja astelee esiin", -"02af": "Saadaan aikakartta", -"02b0": "Brutter pelastaa päivän", -"02b1": "Leijutaan pois", -"02b2": "Saadaan keltainen ase", -"02b3": "Saadaan JET-lauta", -"02b4": "Jak laittaa JET-laudan pois", -"02b5": "Ihka oma Rauhantekijämme!", -"02b6": "Ulosmeno", -"02b7": "Jak matkaa pesään", -"02b8": "Paluu", -"02b9": "Ashelin kuljettaa Jakin", -"02ba": "Pala sinettiä", -"02bb": "Erol inhoaa häviötä", -"02bc": "Torn ja ammusvarasto", -"02bd": "Metallipäitä kaupungissa?", -"02be": "Nyt räjähtää!", -"02bf": "Torn myöntää petoksensa", -"02c0": "Aikakaksoset", -"02c1": "Krewin viemärikeikka", -"02c2": "Mikä on tuo löyhkä?", -"02c3": "Taiteenkeräilijä", -"02c4": "Että kaipaankin housuja!", -"02c5": "Sig paljastaa sielunsa", -"02c6": "Patsaanposauttelua", -"02c7": "Se on ansa!", -"02c8": "Daxter saa suupalan", -"02c9": "Daxter matkustaa putkea", -"02ca": "Työtarjous", -"02cb": "Torn tarjoaa tehtävän", -"02cc": "Tavataan Ashelin", -"02cd": "Daxter tekee siirtonsa", -"02ce": "Tästä tulee hauskaa!", -"02cf": "Boom, beibi!", -"02d0": "Peukut alas", -"02d1": "Heihei", -"02d2": "Temppu", -"02d3": "Hyvää yötä", -"02d4": "Toimit hienosti, tulokas", -"02d5": "Vin tahtoo munakokkelia", -"02d6": "Kor on huolissaan", -"02d7": "Poika on kadoksissa", -"02d8": "Ohjaustorni räjähtää", -"02d9": "Tavataan Onin ja Pecker", -"02da": "Vekotin romahtaa", -"02db": "Hyvät fiilikset", -"02dc": "Daxter kärventyy", -"02dd": "Salatapaaminen", -"02de": "Paroni kohtaa Jakin", -"02df": "Minä tuhoan sinut!", -"02e0": "Takaisin mistä aloitimme", -"02e1": "Salaisuus pommin rakentamiseen", -"02e2": "Krewin kaunotar", -"02e3": "Oi voi...", -"02e4": "Lentoon", -"02e5": "Laskeutumisalusta", -"02e6": "Jak löytää Marin haudan!", -"02e7": "tomb-open-door-res", -"02e8": "tomb-open-door-2-res", -"02e9": "Haudan ovet", -"02ea": "Ensimmäinen säde", -"02eb": "Toinen säde", -"02ec": "Ovet avautuvat", -"02ed": "Edeltäjäkivi!", -"02ee": "Paroni varastaa show'n", -"02ef": "Daxter ojentaa auttavan kätensä", -"02f0": "Daxterin karvainen takaa-ajo", -"02f1": "Tavataan Varjo", -"02f2": "Daxterin pöhkötarina", -"02f3": "Pecker haastaa riitaa", -"02f4": "Samos ja siemen", -"02f5": "Näky", -"02f6": "Kor ja lapsi", -"02f7": "Pelasta lisää vaanijoita", -"02f8": "Marin haudan legenda", -"02f9": "Se on kirous, eikö vain?", -"02fa": "Pora romahtaa", -"02fb": "Valotorni nousee", -"02fc": "Sinetti avaa portin", -"02fd": "Sig on ongelmissa", -"02fe": "Juokse!", -"02ff": "Sigin vahva käsi", -"0300": "Sieltä se taas tulee!", -"0301": "Sigin viimeinen hetki", -"0302": "Kivi... ase... pesä!", -"0303": "Jak matkaa pesään", -"0304": "Poistutaan pesästä", -"0305": "Kor hyppää esiin", -"0306": "Etkö tunnista häntä?", -"0307": "Outo uusi maailma", -"0308": "Juhlinta", -"0309": "", -"030a": "", -"030b": " English", -"030c": "Ota tekstitys käyttöön painamalla ", -"030d": "Tekstitys käytössä", -"030e": "Tekstitys ei käytössä", -"030f": "JET-lauta", -"0310": "Jatka" -} \ No newline at end of file + "0100": "Lopeta", + "0101": "Tauko~", + "0102": "Tekstityksen kieli", + "0103": "Ääniformaatti", + "0104": "Mono", + "0105": "Stereo", + "0106": "Surround", + "0107": "Äänitehosteet", + "0108": "Musiikki", + "0109": "Puhe", + "010a": "Kieli", + "010b": "Värinätoiminto", + "010c": "Vinkit", + "010d": "Keskitä ruutu", + "010e": "Päällä", + "010f": "Pois", + "0110": "Käytä suuntanäppäimiä", + "0111": " English", + "0112": " Fran,cais", + "0113": " Deutsch", + "0114": " Español", + "0115": " Italiano", + "0116": " ~Y~Z~Z~Z~Y~Z~Z~Z~Y~Z~Z", + "0117": " にほんご", + "0118": "Kuvasuhde", + "0119": "Progressiivinen skannaus", + "011a": "Videotila", + "011b": "Peliasetukset", + "011c": "Grafiikan asetukset", + "011d": "Ääniasetukset", + "011e": "4x3", + "011f": "16x9", + "0120": "60Hz", + "0121": "50Hz", + "0122": "Jak II", + "0123": "Poistu demosta", + "0124": "Kyllä", + "0125": "Ei", + "0126": "Takaisin", + "0127": "OK", + "0128": "Seuraava", + "0129": "Edellinen", + "012a": "Jatka tallentamatta", + "012b": "Valitse tallennuspaikka", + "012c": "Valitse ladattava tallennus", + "012d": "Lataa peli", + "012e": "Tallenna peli", + "012f": "Tyhjä", + "0130": "Asetukset", + "0131": "Uusi peli", + "0132": "Paina START-näppäintä", + "0133": "Lopeta peli", + "0134": "Kartta", + "0135": "Valitse aloitus", + "0136": "Ennätykset", + "0137": "1. sija", + "0138": "2. sija", + "0139": "3. sija", + "013a": "4. sija", + "013b": "5. sija", + "013c": "6. sija", + "013d": "7. sija", + "013e": "8. sija", + "013f": "NYFE-leijuri", + "0140": "Luokka 1", + "0141": "Luokka 2", + "0142": "Luokka 3", + "0143": "Harjoitusrata", + "0144": "Haulikko", + "0145": "Läjäytin", + "0146": "Vulkanus-piippu", + "0147": "Rauhantekijä", + "0148": "Oninin haaste", + "0149": "Metallipää-mäiskintä", + "014a": "JET-lauta-haaste", + "014b": "Oninin teltta", + "014c": "Sikahevon saluuna", + "014d": "Stadion", + "014e": "Luokka 1 - käänteinen", + "014f": "Luokka 2 - käänteinen", + "0150": "Luokka 3 - käänteinen", + "0151": "Sataman kisa", + "0152": "Kaupungin kisa", + "0153": "Salaisuudet", + "0154": "Avattu", + "0155": "Poista Jakin pukinparta", + "0156": "Käänteinen maailma", + "0157": "Loputtomat ammukset", + "0158": "Haavoittumattomuus", + "0159": "Sankaritila", + "015a": "Välinäytösten 1. näytös", + "015b": "Välinäytösten 2. näytös", + "015c": "Välinäytösten 3. näytös", + "015d": "Leikekirja", + "015e": "Mega-leikekirja", + "015f": "Leikekirja 3", + "0160": "Tehtävän valinta", + "0161": "Loputon Raivo-Jak", + "0162": "Vulkanus-tykin harjoitusrata", + "0163": "Rauhantekijän harjoitusrata", + "0164": "Käänteiset kisat", + "0165": "Isopäinen Jak", + "0166": "Pienipäinen Jak", + "0167": "Saatavilla", + "0168": "Kerätty", + "0169": "Tehtävät", + "016a": "Valitse esialoitus", + "016b": "Valitse kioski-aloitus", + "016c": "Valitse kohtaus", + "016d": "Tekstitys", + "016e": "Aloita uudelleen", + "016f": "", + "0170": "", + "0171": "Ei mitään", + "0172": "Peli", + "0173": "Aloita/lopeta", + "0174": "Osta", + "0175": "Voitto", + "0176": "Häviö", + "0177": "Kokonaisaika", + "0178": "Kierros ", + "0179": "Palauta painamalla ", + "017a": "Kiireinen", + "017b": "Jatka painamalla ", + "017c": "____~%Suoritetut tehtävät", + "017d": "Suorittamattomat tehtävät", + "017e": "Yritä uudelleen?", + "017f": "Salaisuus saatavilla päävalikosta", + "0180": " = Kyllä, = Ei", + "0181": "Paina puhuaksesi.", + "0182": "Paina käyttääksesi.", + "0183": "Paina matkustaaksesi.", + "0184": "Valitse taso suuntanäppäimellä", + "0185": "Paina poistuaksesi.", + "0186": "Paina pelataksesi.", + "0187": "Halutako pelata uudelleen?", + "0188": "Tehtävä suoritettu", + "0189": "Tehtävä epäonnistui", + "018a": "Yritä uudelleen?", + "018b": "Ruutu ottaa nyt käyttöön 60Hz-tilan", + "018c": "Ruutu ottaa nyt käyttöön progressiivisen skannauksen", + "018d": "Jos kuva näkyy virheellisenä, televisiosi ei tue tätä tilaa", + "018e": "Jos niin käy, odota 10 sekuntia, niin ruutu palautuu takaisin", + "018f": "Ruutu on nyt 60Hz-tilassa", + "0190": "Ruutu on nyt Progresiivinen skannaus -tilassa", + "0191": "Haluatko pitää tämän tilan käytössä?", + "0192": "Levy poistettiin", + "0193": "Syötä Jak II -levy sisään, jotta voit jatkaa pelaamista", + "0194": "Virhe tietojen lukemisessa", + "0195": "Tarkista Jak II -levysi ja yritä uudelleen", + "0196": "Haluatko varmasti lopettaa?", + "0197": "Haluatko aloittaa pelin?", + "0198": "Ei tarpeeksi tilaa muistikortilla Memory__Card__(PS2) paikassa Memory__Card__Slot__~D", + "0199": "Ei Memory__Card__(PS2) liitettynä paikassa Memory__Card__slot__~D", + "019a": "Memory__Card__(PS2) paikassa Memory__Card__slot__~D on alustamaton", + "019b": "Jak II vaatii ~D Kt vapaata tilaa", + "019c": "Syötä Jak II -pelitietoja sisältävä Memory__Card__(PS2) paikkaan Memory__Card__slot__~D", + "019d": "Syötä Memory__Card__(PS2) jossa on tarpeeksi tilaa, muuten pelitietojasi ei voida tallentaa", + "019e": "Ilman alustamista pelitietoja ei voida tallentaa", + "019f": "Tallennetaan tietoja", + "01a0": "Ladataan tietoja", + "01a1": "Alustetaan", + "01a2": "Luodaan tallennustiedostoa", + "01a3": "Älä poista Memory__Card__(PS2) paikassa Memory__Card__slot__~D tai sammuta laitettasi", + "01a4": "Jak II -tallennus on jo olemassa valitsemassasi tiedostossa", + "01a5": "Haluatko korvata sen?", + "01a6": "Alusta?", + "01a7": "Jatka?", + "01a8": "Takaisin?", + "01a9": "Virhe ladattaessa", + "01aa": "Virhe tallentaessa", + "01ab": "Virhe alustaessa", + "01ac": "Virhe luodessa tallennustiedostoa", + "01ad": "Tarkista Memory__Card__(PS2) paikassa Memory__Card__slot__~D", + "01ae": "Tarkista Memory__Card__(PS2) paikassa Memory__Card__slot__~D ja yritä uudelleen", + "01af": "Memory__Card__(PS2) paikasta Memory__Card__slot__~D poistettiin", + "01b0": "Automaattinen tallennus on poistettu käytöstä", + "01b1": "Tallenna pelisi manuaalisesti, niin automaattinen tallennus palautetaan käyttöön", + "01b2": "Jak II -tallennustietoja ei löytynyt kortilta Memory__Card__(PS2) paikassa Memory__Card__slot__~D", + "01b3": "Haluatko luoda uuden Jak II -tallennuksen?", + "01b4": "Kun oheinen kuvake ilmestyy, edistykesi tallennetaan", + "01b5": "Kun tämä kuvake on ruudulla, älä irrota Memory__Card__(PS2) tai sammuta laitettasi", + "01b6": "Pakene linnoituksesta", + "01b7": "Suojele Koria ja lasta", + "01b8": "Nouda lippu aavekaupungista", + "01b9": "Etsi pumppaamon venttiili", + "01ba": "Räjäytä ammukset linnoituksessa", + "01bb": "Kuljeta toimitus Sikahevon saluunaan", + "01bc": "Läpäise haulikon harjoitusrata", + "01bd": "Suojele Sigiä pumppaamolla", + "01be": "Tuhoa tykit viemärissä", + "01bf": "Etsi läjäytin-modi", + "01c0": "Pelasta Vin avolouhoksella", + "01c1": "Voita aika kisatalliin", + "01c2": "Läpäise läjäyttimen harjoitusrata", + "01c3": "Tuhoa munat poralautalla", + "01c4": "Etsi pumppaamon partio", + "01c5": "Nouda rahat Krewille", + "01c6": "Voita JET-lauta-haaste stadionilla", + "01c7": "Etsi Linssi vuoristotemppelissä", + "01c8": "Etsi Siru vuoristotemppelissä", + "01c9": "Etsi Ratas vuoristotemppelissä", + "01ca": "Käynnistä 5 virtakytkintä", + "01cb": "Nouse hissillä palatsiin", + "01cc": "Päihitä paroni palatsissa", + "01cd": "Kuljeta Vastarinnan jäsenet", + "01ce": "Suojele paikkaa aavekaupungissa", + "01cf": "Nappaa tarkkailijat Havenin metsässä", + "01d0": "Saata lapsi voimalaan", + "01d1": "Pelasta vaanijoita Brutterille", + "01d2": "Tuhoa lasti satamalla", + "01d3": "Pysäytä tankkeri", + "01d4": "Tuhoa välineistö kaivannolla", + "01d5": "Räjäytä ecokaivot avolouhoksella", + "01d6": "Tyhjennä viemäri löytääksesi patsaan", + "01d7": "Tuhoa alus poralautalla", + "01d8": "Pelasta vaanijat kaivannolla", + "01d9": "Tapa Metallipäät Havenin metsässä", + "01da": "Voita luokan 3 kisa stadionilla", + "01db": "Nouda sinetin pala kaivannolla", + "01dc": "Nouda sinetin pala vesislummeilla", + "01dd": "Tuhoa 5 Villikissa-leijuria", + "01de": "Voita Oninin haaste", + "01df": "Käytä esineitä Ei-kenenkään-kanjonissa", + "01e0": "Kohtaa testit Marin haudassa", + "01e1": "Avaa holvin ovi Marin haudassa", + "01e2": "Läpäise ensimmäinen miehuuden testi", + "01e3": "Läpäise toinen miehuuden testi", + "01e4": "Päihitä paroni Marin haudassa", + "01e5": "Pelasta ystävät linnoituksesta", + "01e6": "Saata miehet viemärien läpi", + "01e7": "Etsi Rauhantekijä", + "01e8": "Voita luokan 2 kisa stadionilla", + "01e9": "Suojele piilopaikkaa pommiboteilta", + "01ea": "Tutki rakennustyömaa", + "01eb": "Kiipeä rakennustyömaata", + "01ec": "Voita Erol kisahaasteessa", + "01ed": "Tuhoa munat avolouhoksella", + "01ee": "Nouda Elämän siemen aavekaupungissa", + "01ef": "Vie Elämän siemen Havenin metsään", + "01f0": "Suojele Samosia Havenin metsässä", + "01f1": "Tuhoa poralautan torni", + "01f2": "Voita luokan 1 kisa stadionilla", + "01f3": "Tutki palatsia", + "01f4": "Hanki Marin sydän asetehtaalla", + "01f5": "Päihitä Krew asetehtaalla", + "01f6": "Voita peli Sikahevon saluunassa", + "01f7": "Etsi Sig satamanpohjalla", + "01f8": "Saata Sig satamanpohjan läpi", + "01f9": "Puolusta stadionia", + "01fa": "Puolusta vaanijapalloa", + "01fb": "Tuhoa tunnelit satamanpohjalla", + "01fc": "Taistele tiesi pesän muurille", + "01fd": "Löydä Paroni rakennustyömaalla", + "01fe": "Tuhoa pesän muuri", + "01ff": "Tuhoa Metalli-Kor pesällä", + "0200": "Puhu Korille", + "0201": "Puhu Tornille", + "0202": "Puhu Krewille", + "0203": "Puhu Oninille", + "0204": "Puhu Vinille", + "0205": "Puhu Varjolle", + "0206": "Puhu Sigille", + "0207": "Puhu Mekaanikolle", + "0208": "Puhu Keiralle", + "0209": "Puhu Brutterille", + "020a": "Tarkista basaari", + "020b": "Tarkista vesislummit", + "020c": "Mene Ei-kenenkään-kanjonille", + "020d": "Mene Marin hautaan", + "020e": "Voita Metallipää-mäiskintä", + "020f": "Puolusta sataman muuria", + "0210": "Tarkista rakennustyömaa", + "0211": "Hyökkää Metallipäiden pesään", + "0212": "Käy Oraakkelin luona", + "0213": "Haven City", + "0214": "Linnoitus", + "0215": "Laskeutumisalusta", + "0216": "Palatsin katto", + "0217": "Palatsi", + "0218": "Asetehdas", + "0219": "Aavekaupunki", + "021a": "Pumppaamo", + "021b": "Viemäri", + "021c": "Avolouhos", + "021d": "Vuoristotemppeli", + "021e": "Havenin metsä", + "021f": "Poralautta", + "0220": "Marin hauta", + "0221": "Kaivanto", + "0222": "Satamanpohja", + "0223": "Pesä", + "0224": "Hyppää painamalla ", + "0225": "Kieri painamalla liikkeessä", + "0226": "Paina ja sitten uudelleen ilmassa", + "0227": "Hyökkää painamalla tai ", + "0228": "Kieri ja paina sitten syöksyhyppyyn", + "0229": "Hyppää ja paina ilmassa", + "022a": "Paina ja sitten korkeaan hyppyyn", + "022b": "Ammu painamalla ", + "022c": " laittaa aseen pois", + "022d": " tai tuo aseen esiin", + "022e": "Pelaa haulikon harjoitusrata painamalla ", + "022f": " = Haulikon harjoitus~% = Vulkanus-tykin harjoitus", + "0230": "Vaihda asetta painamalla ", + "0231": "Pelaa läjäyttimen harjoitusrata painamalla ", + "0232": " = Läjäyttimen harjoitus~% = Rauhantekijän harjoitus", + "0233": "Potkaise kohdetta ja paina tehdäksesi pikatulisarjan", + "0234": "Ammu laatikoita", + "0235": "Tavoite", + "0236": "Kulta", + "0237": "Hopea", + "0238": "Pronssi", + "0239": "Käytä lautaa painamalla ", + "023a": "Hyppy: Paina ", + "023b": "Kyykkyhyppy: Paina ja sitten ", + "023c": "Voimahyppy: Paina hieman laskeuduttuasi hypystä", + "023d": "Kaideliuku: Paina ja ", + "023e": "Pyörähdys: Paina ja sitten ja ", + "023f": "Voltti: Paina ja sitten ja ", + "0240": "Temppu: Paina ja sitten ja ", + "0241": "Saat paljon pisteitä, jos liu'ut ja teet tempun liukuaksesi uudestaan", + "0242": "Aloita haaste aktivoimalla tuomari", + "0243": "Yritä uudelleen!", + "0244": "Palaa talliin", + "0245": "Tehtävä suoritettu: Palaa Krewin luo", + "0246": "Vaihda leijuvyöhykettä painamalla ", + "0247": "Sukella painamalla pohjassa uidessasi", + "0248": " = Turbo~% tai = Hyppy", + "0249": "Iske Titaaniasulla painamalla ", + "024a": "Tartu Titaaniasulla lohkareisiin painamalla ", + "024b": "Heitä nostetut esineet painamalla ", + "024c": "Paina rampin yläpäässä", + "024d": "Liu'u kaidetta JET-laudalla painamalla tai ", + "024e": "Käytä ja ", + "024f": "Pumppaamo", + "0250": "Avolouhos", + "0251": "Katso traileri", + "0252": " mennäksesi laudan päälle tai pois", + "0253": "Käytä pimeää voimaa painamalla ", + "0254": "Sony Computer Entertainment America~%presents", + "0255": "Sony Computer Entertainment Europe~%presents", + "0256": "Sony Computer Entertainment Korea~%presents", + "0257": "Sony Computer Entertainment Inc.~%presents", + "0258": "A game by", + "0259": "Jak II", + "025a": "Kaksi vuotta myöhemmin...", + "025b": "Viikko myöhemmin...", + "025c": "Asepäivitys hankittu", + "025d": "Haulikko hankittu", + "025e": "Läjäytin-modi mankittu", + "025f": "Vulkanus-piippu hankittu", + "0260": "Rauhantekijä hankittu", + "0261": "Haulikon tulinopeus päivitetty", + "0262": "Aseiden ammuskapasiteetti päivitetty", + "0263": "Aseiden vahinkoa päivitetty", + "0264": "Tehtävä suoritettu", + "0265": "Punainen turvapassi hankittu", + "0266": "Vihreä turvapassi hankittu", + "0267": "Keltainen turvapassi hankittu", + "0268": "Palatsin turvapassi hankittu", + "0269": "Musta turvapassi hankittu", + "026a": "Linssi hankittu", + "026b": "Ratas hankittu", + "026c": "Siru hankittu", + "026d": "Tuo 25 metallipäiden kallohelmeä", + "026e": "Tuo 200 metallipäiden kallohelmeä", + "026f": "Tuo 25 metallipäiden kallohelmeä", + "0270": "Tuo 200 metallipäiden kallohelmeä", + "0271": "Tuo 200 metallipäiden kallohelmeä", + "0272": "Tuo 100 metallipäiden kallohelmeä", + "0273": "Raivopommi: Paina ja sitten ", + "0274": "Raivopurkaus: Paina ja sitten ", + "0275": "Raivo-Jak on nyt haavoittumaton!", + "0276": "Raivojätti: Paina raivotilassa", + "0277": "Ohi", + "0278": "Valitse tapahtuma", + "0279": "Skeittipuisto", + "027a": "Luokan 3 kisa", + "027b": "Luokan 2 kisa", + "027c": "Luokan 1 kisa", + "027d": "Käänteinen luokan 3 kisa", + "027e": "Käänteinen luokan 2 kisa", + "027f": "Käänteinen luokan 1 kisa", + "0280": "Daxter saa suupalan", + "0281": "Tavataan Torn", + "0282": "Noutamassa lippua", + "0283": "Suojele pyhää paikkaa", + "0284": "Meidän maailmamme!", + "0285": "Vanhoja muistoja", + "0286": "Vin tarvitsee apua", + "0287": "Tavataan Vin", + "0288": "Hyviä ja huonoja uutisia", + "0289": "Suuri murskaus", + "028a": "Meillä on yhä ongelmia", + "028b": "Kaivot posahtavat!", + "028c": "Tavataan Kor ja lapsi", + "028d": "Vastarinta", + "028e": "Villikissa-tehtävä", + "028f": "Tornin toimitus", + "0290": "Tavataan Krew ja Sig", + "0291": "Yllätyshyökkäys!", + "0292": "Ashelin on huolissaan", + "0293": "Vin, kamu. Tarvitsemme palveluksen.", + "0294": "Kuka on verhojen takana?", + "0295": "Tiedonjyvä", + "0296": "Iloinen jälleennäkeminen", + "0297": "Kissatappelu", + "0298": "Jak poistuu paikalta", + "0299": "Daxterin suuri voitto", + "029a": "Keira paljastaa suunnitelmansa", + "029b": "Suuri kilpailu", + "029c": "Voittajan piiri", + "029d": "Tavataan Oraakkeli", + "029e": "Jak saa pimeän voiman", + "029f": "Jak saa toisen pimeän voiman", + "02a0": "Jak saa kolmannen pimeän voiman", + "02a1": "Jak saa neljännen pimeän voiman", + "02a2": "Valitus, naiset, ja laulu", + "02a3": "Rahankerääjät", + "02a4": "Mikä tämän lapsen tarina on?", + "02a5": "Krewilla on uusi keikka", + "02a6": "Tavataan Brutter", + "02a7": "Krewin kilpailusopimus", + "02a8": "Mitä te kaksi oikein teitte?", + "02a9": "Oninin haaste", + "02aa": "Marin sinetti on valmis", + "02ab": "Pelasta lisää vaanijoita", + "02ac": "Suojele piilopaikkaa", + "02ad": "Krew uhkailee", + "02ae": "Pelaaja astelee esiin", + "02af": "Saadaan aikakartta", + "02b0": "Brutter pelastaa päivän", + "02b1": "Leijutaan pois", + "02b2": "Saadaan keltainen ase", + "02b3": "Saadaan JET-lauta", + "02b4": "Jak laittaa JET-laudan pois", + "02b5": "Ihka oma Rauhantekijämme!", + "02b6": "Ulosmeno", + "02b7": "Jak matkaa pesään", + "02b8": "Paluu", + "02b9": "Ashelin kuljettaa Jakin", + "02ba": "Pala sinettiä", + "02bb": "Erol inhoaa häviötä", + "02bc": "Torn ja ammusvarasto", + "02bd": "Metallipäitä kaupungissa?", + "02be": "Nyt räjähtää!", + "02bf": "Torn myöntää petoksensa", + "02c0": "Aikakaksoset", + "02c1": "Krewin viemärikeikka", + "02c2": "Mikä on tuo löyhkä?", + "02c3": "Taiteenkeräilijä", + "02c4": "Että kaipaankin housuja!", + "02c5": "Sig paljastaa sielunsa", + "02c6": "Patsaanposauttelua", + "02c7": "Se on ansa!", + "02c8": "Daxter saa suupalan", + "02c9": "Daxter matkustaa putkea", + "02ca": "Työtarjous", + "02cb": "Torn tarjoaa tehtävän", + "02cc": "Tavataan Ashelin", + "02cd": "Daxter tekee siirtonsa", + "02ce": "Tästä tulee hauskaa!", + "02cf": "Boom, beibi!", + "02d0": "Peukut alas", + "02d1": "Heihei", + "02d2": "Temppu", + "02d3": "Hyvää yötä", + "02d4": "Toimit hienosti, tulokas", + "02d5": "Vin tahtoo munakokkelia", + "02d6": "Kor on huolissaan", + "02d7": "Poika on kadoksissa", + "02d8": "Ohjaustorni räjähtää", + "02d9": "Tavataan Onin ja Pecker", + "02da": "Vekotin romahtaa", + "02db": "Hyvät fiilikset", + "02dc": "Daxter kärventyy", + "02dd": "Salatapaaminen", + "02de": "Paroni kohtaa Jakin", + "02df": "Minä tuhoan sinut!", + "02e0": "Takaisin mistä aloitimme", + "02e1": "Salaisuus pommin rakentamiseen", + "02e2": "Krewin kaunotar", + "02e3": "Oi voi...", + "02e4": "Lentoon", + "02e5": "Laskeutumisalusta", + "02e6": "Jak löytää Marin haudan!", + "02e7": "tomb-open-door-res", + "02e8": "tomb-open-door-2-res", + "02e9": "Haudan ovet", + "02ea": "Ensimmäinen säde", + "02eb": "Toinen säde", + "02ec": "Ovet avautuvat", + "02ed": "Edeltäjäkivi!", + "02ee": "Paroni varastaa show'n", + "02ef": "Daxter ojentaa auttavan kätensä", + "02f0": "Daxterin karvainen takaa-ajo", + "02f1": "Tavataan Varjo", + "02f2": "Daxterin pöhkötarina", + "02f3": "Pecker haastaa riitaa", + "02f4": "Samos ja siemen", + "02f5": "Näky", + "02f6": "Kor ja lapsi", + "02f7": "Pelasta lisää vaanijoita", + "02f8": "Marin haudan legenda", + "02f9": "Se on kirous, eikö vain?", + "02fa": "Pora romahtaa", + "02fb": "Valotorni nousee", + "02fc": "Sinetti avaa portin", + "02fd": "Sig on ongelmissa", + "02fe": "Juokse!", + "02ff": "Sigin vahva käsi", + "0300": "Sieltä se taas tulee!", + "0301": "Sigin viimeinen hetki", + "0302": "Kivi... ase... pesä!", + "0303": "Jak matkaa pesään", + "0304": "Poistutaan pesästä", + "0305": "Kor hyppää esiin", + "0306": "Etkö tunnista häntä?", + "0307": "Outo uusi maailma", + "0308": "Juhlinta", + "0309": "", + "030a": "", + "030b": " English", + "030c": "Ota tekstitys käyttöön painamalla ", + "030d": "Tekstitys käytössä", + "030e": "Tekstitys ei käytössä", + "030f": "JET-lauta", + "0310": "Jatka" +} diff --git a/game/assets/jak2/text/game_custom_text_ca-ES.json b/game/assets/jak2/text/game_custom_text_ca-ES.json index f9a2027239..4b2b5a5cf4 100644 --- a/game/assets/jak2/text/game_custom_text_ca-ES.json +++ b/game/assets/jak2/text/game_custom_text_ca-ES.json @@ -232,5 +232,7 @@ "1336": "Menú de progrés ràpid", "1337": "Distància LOD PS2", "1338": "Apagat", - "1339": "Mostra" + "1339": "Mostra", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_da-DK.json b/game/assets/jak2/text/game_custom_text_da-DK.json index 57a0220f2e..ecd55f445c 100644 --- a/game/assets/jak2/text/game_custom_text_da-DK.json +++ b/game/assets/jak2/text/game_custom_text_da-DK.json @@ -232,5 +232,7 @@ "1336": "Hurtig Fremskridt Menu", "1337": "PS2 LOD Afstand", "1338": "Fra", - "1339": "Skærm" + "1339": "Skærm", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_de-DE.json b/game/assets/jak2/text/game_custom_text_de-DE.json index 41f31eaa9c..adab1d323c 100644 --- a/game/assets/jak2/text/game_custom_text_de-DE.json +++ b/game/assets/jak2/text/game_custom_text_de-DE.json @@ -232,5 +232,7 @@ "1336": "Schnelles Fortschrittsmenü", "1337": "PS2 LOD-Distanz", "1338": "Aus", - "1339": "Anzeige" + "1339": "Anzeige", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_en-GB.json b/game/assets/jak2/text/game_custom_text_en-GB.json index 188b0c94b1..63fc277d76 100644 --- a/game/assets/jak2/text/game_custom_text_en-GB.json +++ b/game/assets/jak2/text/game_custom_text_en-GB.json @@ -232,5 +232,7 @@ "1336": "Fast Progress Menu", "1337": "PS2 LOD Distance", "1338": "Off", - "1339": "Display" + "1339": "Display", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_en-US.json b/game/assets/jak2/text/game_custom_text_en-US.json index 089a8b6530..da31dd34d9 100644 --- a/game/assets/jak2/text/game_custom_text_en-US.json +++ b/game/assets/jak2/text/game_custom_text_en-US.json @@ -234,7 +234,8 @@ "1338": "Off", "1339": "Display", "133a": " Suomi", - + "133b": "Hint Subtitles", + "2000": "", "2001": "", "2002": "", diff --git a/game/assets/jak2/text/game_custom_text_es-ES.json b/game/assets/jak2/text/game_custom_text_es-ES.json index 61a5f90673..3968bcba24 100644 --- a/game/assets/jak2/text/game_custom_text_es-ES.json +++ b/game/assets/jak2/text/game_custom_text_es-ES.json @@ -28,7 +28,7 @@ "1210": "Ancho", "1211": "Alto", "1212": "??????????", - "1213": "Reproduciendo...", + "1213": "Jugando...", "1214": "Sin Canción", "1215": "Por defecto", "1216": "Arma Mórfica", @@ -204,7 +204,7 @@ "1311": "Any% - All Orbs", "1312": "Any% - Hero Mode", "1313": "Tiempo Local", - "1314": "¡Aviso!", + "1314": "¡Advertencia!", "1315": "Esta opción es muy experimental. Si no juegas a 60 frames por segundo, pueden surgir problemas gráficos y de jugabilidad.", "1316": "Puntuación local", "1320": "Ningún", @@ -232,5 +232,7 @@ "1336": "Menú Rápido", "1337": "Distancia de LOD de PS2", "1338": "Desactivado", - "1339": "Pantalla" + "1339": "Pantalla", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_fi-FI.json b/game/assets/jak2/text/game_custom_text_fi-FI.json index dc75a70f7b..d59277d41c 100644 --- a/game/assets/jak2/text/game_custom_text_fi-FI.json +++ b/game/assets/jak2/text/game_custom_text_fi-FI.json @@ -232,5 +232,7 @@ "1336": "Nopeampi valikko", "1337": "PS2 yksityskohtien etäisyys", "1338": "Pois", - "1339": "Näyttö" + "1339": "Näyttö", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_fr-FR.json b/game/assets/jak2/text/game_custom_text_fr-FR.json index c8b453b235..0e3adf767f 100644 --- a/game/assets/jak2/text/game_custom_text_fr-FR.json +++ b/game/assets/jak2/text/game_custom_text_fr-FR.json @@ -232,5 +232,7 @@ "1336": "Menu de pause rapide", "1337": "Distance du niveau de détail PS2", "1338": "Non", - "1339": "Écran" + "1339": "Écran", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_hu-HU.json b/game/assets/jak2/text/game_custom_text_hu-HU.json index 2dde99a23b..8ef2fa611f 100644 --- a/game/assets/jak2/text/game_custom_text_hu-HU.json +++ b/game/assets/jak2/text/game_custom_text_hu-HU.json @@ -232,5 +232,7 @@ "1336": "Gyors Fejlődési Menü", "1337": "PS2 LOD Távolság", "1338": "Nak nek", - "1339": "Megjelenítés" + "1339": "Megjelenítés", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_is-IS.json b/game/assets/jak2/text/game_custom_text_is-IS.json index 5c3379b00f..36083b5ef0 100644 --- a/game/assets/jak2/text/game_custom_text_is-IS.json +++ b/game/assets/jak2/text/game_custom_text_is-IS.json @@ -232,5 +232,7 @@ "1336": "Fast Progress Menu", "1337": "PS2 LOD Distance", "1338": "Off", - "1339": "Display" + "1339": "Display", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_it-IT.json b/game/assets/jak2/text/game_custom_text_it-IT.json index 284625fa02..c9e9d24755 100644 --- a/game/assets/jak2/text/game_custom_text_it-IT.json +++ b/game/assets/jak2/text/game_custom_text_it-IT.json @@ -232,5 +232,7 @@ "1336": "Menu veloce", "1337": "Distanza LOD PS2", "1338": "No", - "1339": "Monitor" + "1339": "Monitor", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_ja-JP.json b/game/assets/jak2/text/game_custom_text_ja-JP.json index cb492cc6c1..68951f271a 100644 --- a/game/assets/jak2/text/game_custom_text_ja-JP.json +++ b/game/assets/jak2/text/game_custom_text_ja-JP.json @@ -74,8 +74,8 @@ "123f": "字幕にスピーカーを表示", "1240": "いつもしなく", "1241": "オフスクリーン", - "1242": "?時", - "1243": "ゲーム地?", + "1242": "いつも", + "1243": "ゲーム地いき", "1244": "アメリカ(SCEA)", "1245": "ヨーロッパ(SCEE)", "1246": "にほん(SCEI)", @@ -84,30 +84,30 @@ "1249": "~DX", "124a": "コントローラーLEDオプション", "124b": "プレイヤーステータスを表示", - "124c": "?力を表示", + "124c": "たい力を表示", "124d": "オートセーブを無?にする", "124e": "オートセーブ オフ", "124f": "オートセーブをきっても よろしいでしょうか?", "1250": "ヘイブンシティのターボジェットボード", - "1251": "敵の?力バー", - "1252": "??の?力バー", - "1253": "??の無敵", + "1251": "敵のたい力バー", + "1252": "乗り物たい力バー", + "1253": "乗り物の無敵", "1254": "????", "1255": "コレクションを自動?に??する", "1256": "ミュージックプレイヤー", "1257": "テクスチャなしモード", "1258": "?いムービー", "1259": "?いムービー", - "125a": "高?ゲームプレイ", - "125b": "低?ゲームプレイ", + "125a": "高そくゲームプレイ", + "125b": "低そくゲームプレイ", "125c": "ヘイブンシティの???行", "125d": "プリカーソルオーブトラッカー", "125e": "リアルタイムオブデイ", - "125f": "??なヘブンシティ", + "125f": "へいわなヘブンシティ", "1260": "ジェットボードトリックディスプレイ", "1261": "?い天?", - "1262": "?い天?", - "1263": "??ハイジャック??ライン", + "1262": "いい天こう", + "1263": "乗り物ハイジャックおんせいライン", "1264": "ロック中", "1265": "3つのバルブをすべてヒットさせ、~D秒以内に?~S?のマールの像を見つける", "1266": "ヘブンシティの??を~D人?らす", @@ -130,22 +130,22 @@ "128c": "高", "128d": "クレジット", "128e": "フレームレート", - "128f": "その?", + "128f": "そのほか", "1290": "スピードラン モード", - "1291": "入力??", - "1292": "????に戻す", + "1291": "入力せってい", + "1292": "しょきせっていに戻す", "1293": "コントローラーオプション", "1294": "コントローラーを選?する", "1295": "アナログデッドゾーン", - "1296": "ウィンドウのフォーカスが外れているときは無?する", + "1296": "ウィンドウのフォーカスが外れているときは無しする", "1297": "コントローラーのLEDで?力を表示する", "1298": "LEDを?の??で使用", - "1299": "キーボードを??にする", - "129a": "マウスを??にする", + "1299": "キーボードをゆうこうにする", + "129a": "マウスをゆうこうにする", "129b": "マウスオプション", "129c": "?跡カメラ", "129d": "水?感?", - "129e": "??感?", + "129e": "すいちょく感ど", "129f": "プレイヤーの?動", "12a0": "オブジェクトの?", "12a1": "ノーマル", @@ -169,10 +169,10 @@ "12b3": "タイタンスーツのボディ", "12b4": "砲撃台", "12b5": "パンチ", - "12b6": "フロップ", - "12b7": "アッパーカット", - "12b8": "スピン", - "12b9": "ロール", + "12b6": "すいちょく頭突き", + "12b7": "すいちょくアッパーカット", + "12b8": "?り?り", + "12b9": "前転", "12bf": "ダークボム", "12c0": "ダークブラスト", "12c3": "クリムゾンガード", @@ -182,7 +182,7 @@ "12c7": "グリム", "12c8": "モグ", "12c9": "メタルヘッド", - "12ca": "?の友?", + "12ca": "ほかの友だち", "12cb": "?の敵", "1300": "自動でカーソルを?す", "1301": "バインドの??り?て", @@ -191,9 +191,9 @@ "1304": "マウスのバインド", "1305": "オプションなし", "1306": "?機中", - "1307": "???", - "1308": "??", - "1309": "高解像?の空", + "1307": "みせってい", + "1308": "ふめい", + "1309": "高解像どの空", "130a": "高?エアロックとドア", "130b": "高?エレベーター", "130c": "スピードラン", @@ -229,8 +229,10 @@ "1333": "PS2オプション", "1334": "アクターカリング", "1335": "?制?に??マッピング", - "1336": "高?進行??メニュー", - "1337": "PS2 LOD ??", + "1336": "高そく進行じょうきょうメニュー", + "1337": "PS2 LOD きょり", "1338": "オフ", - "1339": "ディスプレイ" + "1339": "ディスプレイ", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_lt-LT.json b/game/assets/jak2/text/game_custom_text_lt-LT.json index b66139518b..08b5f0825d 100644 --- a/game/assets/jak2/text/game_custom_text_lt-LT.json +++ b/game/assets/jak2/text/game_custom_text_lt-LT.json @@ -232,5 +232,7 @@ "1336": "Spartus Pažangos Meniu", "1337": "PS2 Objektų Detalių Atstumas", "1338": "Išjungti", - "1339": "Ekranas" + "1339": "Ekranas", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_nl-NL.json b/game/assets/jak2/text/game_custom_text_nl-NL.json index a4b98c202f..9c8364722c 100644 --- a/game/assets/jak2/text/game_custom_text_nl-NL.json +++ b/game/assets/jak2/text/game_custom_text_nl-NL.json @@ -232,5 +232,7 @@ "1336": "Snel voortgangsmenu", "1337": "PS2 LOD-afstand", "1338": "Uit", - "1339": "Weergave" + "1339": "Weergave", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_no-NO.json b/game/assets/jak2/text/game_custom_text_no-NO.json index 23ad7f1832..cd19c1c2e7 100644 --- a/game/assets/jak2/text/game_custom_text_no-NO.json +++ b/game/assets/jak2/text/game_custom_text_no-NO.json @@ -232,5 +232,7 @@ "1336": "Fast Progress Menu", "1337": "PS2 LOD Distance", "1338": "Off", - "1339": "Display" + "1339": "Display", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_pl-PL.json b/game/assets/jak2/text/game_custom_text_pl-PL.json index 5d660cd15d..d27a70a588 100644 --- a/game/assets/jak2/text/game_custom_text_pl-PL.json +++ b/game/assets/jak2/text/game_custom_text_pl-PL.json @@ -232,5 +232,7 @@ "1336": "Szybkie Menu Postępu", "1337": "Odległość rysowania PS2", "1338": "Wył.", - "1339": "Wyświetlacz" + "1339": "Wyświetlacz", + "133a": "Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_pt-BR.json b/game/assets/jak2/text/game_custom_text_pt-BR.json index f88c16e699..f0ec718eb3 100644 --- a/game/assets/jak2/text/game_custom_text_pt-BR.json +++ b/game/assets/jak2/text/game_custom_text_pt-BR.json @@ -232,5 +232,7 @@ "1336": "Menu de Progresso rápido", "1337": "Distância LOD PS2", "1338": "Desligado", - "1339": "Tela" + "1339": "Tela", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_pt-PT.json b/game/assets/jak2/text/game_custom_text_pt-PT.json index ab65603744..3877e1db41 100644 --- a/game/assets/jak2/text/game_custom_text_pt-PT.json +++ b/game/assets/jak2/text/game_custom_text_pt-PT.json @@ -232,5 +232,7 @@ "1336": "Fast Progress Menu", "1337": "PS2 LOD Distance", "1338": "Off", - "1339": "Display" + "1339": "Display", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak2/text/game_custom_text_sv-SE.json b/game/assets/jak2/text/game_custom_text_sv-SE.json index 7b3ee27b14..3f1d490a11 100644 --- a/game/assets/jak2/text/game_custom_text_sv-SE.json +++ b/game/assets/jak2/text/game_custom_text_sv-SE.json @@ -232,5 +232,7 @@ "1336": "Fast Progress Menu", "1337": "PS2 LOD Distance", "1338": "Off", - "1339": "Display" + "1339": "Display", + "133a": " Suomi", + "133b": "Hint Subtitles" } diff --git a/game/assets/jak3/app256.png b/game/assets/jak3/app256.png index dddfc07f2d..f49ab8096c 100644 Binary files a/game/assets/jak3/app256.png and b/game/assets/jak3/app256.png differ diff --git a/game/assets/jak3/app64.png b/game/assets/jak3/app64.png index 2b47380c66..6ea319a2b8 100644 Binary files a/game/assets/jak3/app64.png and b/game/assets/jak3/app64.png differ diff --git a/game/assets/jak3/game_subtitle.gp b/game/assets/jak3/game_subtitle.gp index 89f54566f0..f81fcd83f4 100644 --- a/game/assets/jak3/game_subtitle.gp +++ b/game/assets/jak3/game_subtitle.gp @@ -3,55 +3,82 @@ (subtitle-v2 (file-json :language-id 0 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_en-US.json") (file-json :language-id 1 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_fr-FR.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_fr-FR.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_fr-FR.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_fr-FR.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") (file-json :language-id 2 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_de-DE.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_de-DE.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_de-DE.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_de-DE.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") (file-json :language-id 3 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_es-ES.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_es-ES.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_es-ES.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_es-ES.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") (file-json :language-id 4 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_it-IT.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_it-IT.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_it-IT.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_it-IT.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") (file-json + ;; commentary :language-id 5 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_jp-JP.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_jp-JP.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_cm-CM.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_cm-CM.json") (file-json :language-id 6 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_ko-KR.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_ko-KR.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json") + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_jp-JP.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_jp-JP.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") (file-json :language-id 7 - :text-version "jak2" - :lines "game/assets/jak2/subtitle/subtitle_lines_en-GB.json" - :meta "game/assets/jak2/subtitle/subtitle_meta_en-GB.json" - :lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json" - :meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json")) + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_ko-KR.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_ko-KR.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") + (file-json + :language-id 8 + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_ru-RU.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_ru-RU.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") + (file-json + :language-id 9 + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_pt-PT.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_pt-PT.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") + (file-json + :language-id 10 + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_nl-NL.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_nl-NL.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json") + (file-json + :language-id 11 + :text-version "jak3" + :lines "game/assets/jak3/subtitle/subtitle_lines_en-GB.json" + :meta "game/assets/jak3/subtitle/subtitle_meta_en-GB.json" + :lines-base "game/assets/jak3/subtitle/subtitle_lines_en-US.json" + :meta-base "game/assets/jak3/subtitle/subtitle_meta_en-US.json")) diff --git a/game/assets/jak3/subtitle/subtitle_lines_cm-CM.json b/game/assets/jak3/subtitle/subtitle_lines_cm-CM.json new file mode 100644 index 0000000000..adafe6184e --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_lines_cm-CM.json @@ -0,0 +1,50 @@ +{ + "cutscenes": {}, + "other": {}, + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } +} diff --git a/game/assets/jak3/subtitle/subtitle_lines_de-DE.json b/game/assets/jak3/subtitle/subtitle_lines_de-DE.json index 7942f008bc..adafe6184e 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_de-DE.json +++ b/game/assets/jak3/subtitle/subtitle_lines_de-DE.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_en-GB.json b/game/assets/jak3/subtitle/subtitle_lines_en-GB.json index 7942f008bc..adafe6184e 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_en-GB.json +++ b/game/assets/jak3/subtitle/subtitle_lines_en-GB.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_en-US.json b/game/assets/jak3/subtitle/subtitle_lines_en-US.json index 7942f008bc..f018863718 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_en-US.json +++ b/game/assets/jak3/subtitle/subtitle_lines_en-US.json @@ -1,5 +1,50 @@ { "cutscenes": {}, - "other": {}, - "speakers": {} + "other": { "dax128": ["Head for the city, Jak."] }, + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_es-ES.json b/game/assets/jak3/subtitle/subtitle_lines_es-ES.json index 7942f008bc..adafe6184e 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_es-ES.json +++ b/game/assets/jak3/subtitle/subtitle_lines_es-ES.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_fr-FR.json b/game/assets/jak3/subtitle/subtitle_lines_fr-FR.json index 7942f008bc..adafe6184e 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_fr-FR.json +++ b/game/assets/jak3/subtitle/subtitle_lines_fr-FR.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_it-IT.json b/game/assets/jak3/subtitle/subtitle_lines_it-IT.json index 7942f008bc..adafe6184e 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_it-IT.json +++ b/game/assets/jak3/subtitle/subtitle_lines_it-IT.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_jp-JP.json b/game/assets/jak3/subtitle/subtitle_lines_jp-JP.json index 7942f008bc..adafe6184e 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_jp-JP.json +++ b/game/assets/jak3/subtitle/subtitle_lines_jp-JP.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_ko-KR.json b/game/assets/jak3/subtitle/subtitle_lines_ko-KR.json index 7942f008bc..adafe6184e 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_ko-KR.json +++ b/game/assets/jak3/subtitle/subtitle_lines_ko-KR.json @@ -1,5 +1,50 @@ { "cutscenes": {}, "other": {}, - "speakers": {} + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } } diff --git a/game/assets/jak3/subtitle/subtitle_lines_nl-NL.json b/game/assets/jak3/subtitle/subtitle_lines_nl-NL.json new file mode 100644 index 0000000000..adafe6184e --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_lines_nl-NL.json @@ -0,0 +1,50 @@ +{ + "cutscenes": {}, + "other": {}, + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } +} diff --git a/game/assets/jak3/subtitle/subtitle_lines_pt-PT.json b/game/assets/jak3/subtitle/subtitle_lines_pt-PT.json new file mode 100644 index 0000000000..adafe6184e --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_lines_pt-PT.json @@ -0,0 +1,50 @@ +{ + "cutscenes": {}, + "other": {}, + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } +} diff --git a/game/assets/jak3/subtitle/subtitle_lines_ru-RU.json b/game/assets/jak3/subtitle/subtitle_lines_ru-RU.json new file mode 100644 index 0000000000..adafe6184e --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_lines_ru-RU.json @@ -0,0 +1,50 @@ +{ + "cutscenes": {}, + "other": {}, + "speakers": { + "jak": "Jak", + "darkjak": "Dark Jak", + "daxter": "Daxter", + "pecker": "Pecker", + "veger": "Count Veger", + "ashelin": "Ashelin", + "wastelander-male": "Wastelander", + "wastelander-female": "Wastelander", + "citizen-female": "Citizen", + "citizen-male": "Citizen", + "marauder": "Marauder", + "damas": "Damas", + "errol": "Errol", + "errol-hologram": "???", + "guard": "Freedom League Guard", + "guard-a": "Guard A", + "guard-b": "Guard B", + "jinx": "Jinx", + "keira": "Keira", + "kleiver": "Kleiver", + "onin": "Onin", + "oracle": "Oracle", + "precursor": "Precursor", + "ottsel-dummy": "Ottsel Dummy", + "ottsel-leader": "Ottsel Leader", + "ottsel-surfer": "Ottsel Surfer", + "ottsel-veger": "Ottsel Veger", + "ottsel-tess": "Ottsel Tess", + "computer": "Computer", + "samos": "Samos", + "seem": "Seem", + "sig": "Sig", + "tess": "Tess", + "torn": "Torn", + "vin": "Vin", + "krew": "Krew", + "baron": "Baron Praxis", + "scherr": "Josh Scherr", + "arey": "Daniel Arey", + "baldwin": "Eric Baldwin", + "schimpf": "Adam Schimpf", + "martinsen": "Jason Martinsen", + "phillips": "Kion Phillips", + "yates": "Jeremy Yates" + } +} diff --git a/game/assets/jak3/subtitle/subtitle_meta_cm-CM.json b/game/assets/jak3/subtitle/subtitle_meta_cm-CM.json new file mode 100644 index 0000000000..495996ba8e --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_meta_cm-CM.json @@ -0,0 +1,4 @@ +{ + "cutscenes": {}, + "other": {} +} diff --git a/game/assets/jak3/subtitle/subtitle_meta_en-US.json b/game/assets/jak3/subtitle/subtitle_meta_en-US.json index 495996ba8e..811141e4da 100644 --- a/game/assets/jak3/subtitle/subtitle_meta_en-US.json +++ b/game/assets/jak3/subtitle/subtitle_meta_en-US.json @@ -1,4 +1,9448 @@ { - "cutscenes": {}, - "other": {} + "cutscenes": { + "wascity-leaper-race-intro": { + "lines": [ + { + "frame_end": 91.0, + "frame_start": 46.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 170.0, + "frame_start": 95.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 227.0, + "frame_start": 175.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 320.0, + "frame_start": 281.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 444.0, + "frame_start": 321.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 535.0, + "frame_start": 445.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 609.0, + "frame_start": 541.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 695.0, + "frame_start": 610.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 747.0, + "frame_start": 696.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 851.0, + "frame_start": 788.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 926.0, + "frame_start": 852.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1007.0, + "frame_start": 927.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1134.0, + "frame_start": 1008.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1188.0, + "frame_start": 1147.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1264.0, + "frame_start": 1214.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1336.0, + "frame_start": 1271.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-gun-res": { + "lines": [ + { + "frame_end": 184.0, + "frame_start": 75.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 258.0, + "frame_start": 185.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 400.0, + "frame_start": 259.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 544.0, + "frame_start": 401.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-defend-res": { + "lines": [ + { + "frame_end": 56.0, + "frame_start": 25.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 147.0, + "frame_start": 57.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 187.0, + "frame_start": 148.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 306.0, + "frame_start": 188.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 440.0, + "frame_start": 307.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 524.0, + "frame_start": 448.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 631.0, + "frame_start": 535.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 764.0, + "frame_start": 632.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 816.0, + "frame_start": 765.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 948.0, + "frame_start": 830.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1060.0, + "frame_start": 949.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1185.0, + "frame_start": 1061.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1281.0, + "frame_start": 1196.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1427.0, + "frame_start": 1282.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1493.0, + "frame_start": 1428.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1608.0, + "frame_start": 1502.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1690.0, + "frame_start": 1623.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1806.0, + "frame_start": 1703.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1865.0, + "frame_start": 1817.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "volcano-indax-1-intro": { + "lines": [ + { + "frame_end": 151.0, + "frame_start": 102.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "tower-destroy-intro": { + "lines": [ + { + "frame_end": 344.0, + "frame_start": 298.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 394.0, + "frame_start": 345.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 455.0, + "frame_start": 405.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 502.0, + "frame_start": 460.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 554.0, + "frame_start": 511.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 660.0, + "frame_start": 555.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-tests-res-b": { + "lines": [ + { + "frame_end": 241.0, + "frame_start": 166.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 280.0, + "frame_start": 242.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 325.0, + "frame_start": 296.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 418.0, + "frame_start": 338.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 546.0, + "frame_start": 422.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 619.0, + "frame_start": 547.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 735.0, + "frame_start": 620.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 853.0, + "frame_start": 806.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-tests-res-a": { + "lines": [ + { + "frame_end": 226.0, + "frame_start": 51.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 339.0, + "frame_start": 227.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 514.0, + "frame_start": 340.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 632.0, + "frame_start": 515.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 771.0, + "frame_start": 633.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-tests-intro": { + "lines": [ + { + "frame_end": 232.0, + "frame_start": 191.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 273.0, + "frame_start": 233.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-oracle-res": { + "lines": [ + { + "frame_end": 154.0, + "frame_start": 57.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 258.0, + "frame_start": 173.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 353.0, + "frame_start": 259.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 464.0, + "frame_start": 354.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 573.0, + "frame_start": 465.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 752.0, + "frame_start": 574.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 850.0, + "frame_start": 762.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 962.0, + "frame_start": 851.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1067.0, + "frame_start": 965.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1185.0, + "frame_start": 1068.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1223.0, + "frame_start": 1189.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1346.0, + "frame_start": 1226.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1371.0, + "frame_start": 1351.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1518.0, + "frame_start": 1381.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1651.0, + "frame_start": 1582.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1840.0, + "frame_start": 1673.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-oracle-intro": { + "lines": [ + { + "frame_end": 182.0, + "frame_start": 136.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 271.0, + "frame_start": 183.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 324.0, + "frame_start": 275.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 416.0, + "frame_start": 325.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 571.0, + "frame_start": 419.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 694.0, + "frame_start": 572.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 784.0, + "frame_start": 695.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 845.0, + "frame_start": 796.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-defend-res": { + "lines": [ + { + "frame_end": 147.0, + "frame_start": 33.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 223.0, + "frame_start": 148.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 329.0, + "frame_start": 224.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 506.0, + "frame_start": 353.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 694.0, + "frame_start": 544.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 809.0, + "frame_start": 716.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 919.0, + "frame_start": 810.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1030.0, + "frame_start": 928.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1223.0, + "frame_start": 1031.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1275.0, + "frame_start": 1230.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-gun-intro": { + "lines": [ + { + "frame_end": 121.0, + "frame_start": 20.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 156.0, + "frame_start": 122.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 226.0, + "frame_start": 158.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 309.0, + "frame_start": 227.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 382.0, + "frame_start": 310.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 437.0, + "frame_start": 383.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 585.0, + "frame_start": 440.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-defend-intro": { + "lines": [ + { + "frame_end": 153.0, + "frame_start": 37.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 254.0, + "frame_start": 162.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 366.0, + "frame_start": 264.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 527.0, + "frame_start": 367.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 628.0, + "frame_start": 547.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 707.0, + "frame_start": 629.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 817.0, + "frame_start": 708.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 927.0, + "frame_start": 823.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 999.0, + "frame_start": 928.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1067.0, + "frame_start": 1000.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1108.0, + "frame_start": 1068.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-climb-res": { + "lines": [ + { + "frame_end": 99.0, + "frame_start": 57.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 192.0, + "frame_start": 104.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 267.0, + "frame_start": 193.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 342.0, + "frame_start": 269.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 455.0, + "frame_start": 343.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 496.0, + "frame_start": 457.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 591.0, + "frame_start": 497.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 701.0, + "frame_start": 592.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 780.0, + "frame_start": 702.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 907.0, + "frame_start": 781.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 972.0, + "frame_start": 908.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 993.0, + "frame_start": 976.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1015.0, + "frame_start": 994.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1047.0, + "frame_start": 1016.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1088.0, + "frame_start": 1048.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1105.0, + "frame_start": 1089.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1123.0, + "frame_start": 1106.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1142.0, + "frame_start": 1124.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1235.0, + "frame_start": 1181.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "sewer-kg-met-intro": { + "lines": [ + { + "frame_end": 100.0, + "frame_start": 37.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 149.0, + "frame_start": 101.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 214.0, + "frame_start": 150.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 290.0, + "frame_start": 215.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 394.0, + "frame_start": 291.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 471.0, + "frame_start": 395.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 544.0, + "frame_start": 478.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 672.0, + "frame_start": 556.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 692.0, + "frame_start": 679.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 795.0, + "frame_start": 706.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 869.0, + "frame_start": 806.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 928.0, + "frame_start": 870.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "volcano-darkeco-res": { + "lines": [ + { + "frame_end": 207.0, + "frame_start": 171.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 245.0, + "frame_start": 213.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 316.0, + "frame_start": 246.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 361.0, + "frame_start": 331.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 482.0, + "frame_start": 362.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 518.0, + "frame_start": 483.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 592.0, + "frame_start": 536.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 754.0, + "frame_start": 614.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 790.0, + "frame_start": 755.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 874.0, + "frame_start": 791.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 910.0, + "frame_start": 879.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1011.0, + "frame_start": 994.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1041.0, + "frame_start": 1026.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1087.0, + "frame_start": 1057.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1124.0, + "frame_start": 1109.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1276.0, + "frame_start": 1138.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1322.0, + "frame_start": 1287.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1392.0, + "frame_start": 1323.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1452.0, + "frame_start": 1393.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1529.0, + "frame_start": 1481.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1593.0, + "frame_start": 1530.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1709.0, + "frame_start": 1594.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1820.0, + "frame_start": 1785.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1852.0, + "frame_start": 1821.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "sewer-explore-intro": { + "lines": [ + { + "frame_end": 100.0, + "frame_start": 37.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 149.0, + "frame_start": 101.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 214.0, + "frame_start": 150.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 290.0, + "frame_start": 215.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 394.0, + "frame_start": 291.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 471.0, + "frame_start": 395.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 544.0, + "frame_start": 478.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 672.0, + "frame_start": 556.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 692.0, + "frame_start": 679.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 795.0, + "frame_start": 706.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 869.0, + "frame_start": 806.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 928.0, + "frame_start": 870.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "precursor-tour-res": { + "lines": [ + { + "frame_end": 94.0, + "frame_start": 52.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 120.0, + "frame_start": 99.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 147.0, + "frame_start": 126.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 196.0, + "frame_start": 151.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 240.0, + "frame_start": 197.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 316.0, + "frame_start": 241.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 358.0, + "frame_start": 317.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 404.0, + "frame_start": 359.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 488.0, + "frame_start": 407.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 539.0, + "frame_start": 502.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "precursor-destroy-ship-res": { + "lines": [ + { + "frame_end": 492.0, + "frame_start": 401.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 590.0, + "frame_start": 512.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 641.0, + "frame_start": 591.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 681.0, + "frame_start": 650.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 730.0, + "frame_start": 682.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 759.0, + "frame_start": 731.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 774.0, + "frame_start": 760.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 880.0, + "frame_start": 865.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 919.0, + "frame_start": 898.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1632.0, + "frame_start": 1590.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "temple-jak-gets-light-glide": { + "lines": [ + { + "frame_end": 196.0, + "frame_start": 62.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 345.0, + "frame_start": 197.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 561.0, + "frame_start": 352.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6801.0, + "frame_start": 567.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "port-assault-intro": { + "lines": [ + { + "frame_end": 114.0, + "frame_start": 30.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 171.0, + "frame_start": 115.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 214.0, + "frame_start": 172.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 319.0, + "frame_start": 215.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 362.0, + "frame_start": 320.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 438.0, + "frame_start": 363.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 526.0, + "frame_start": 439.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 568.0, + "frame_start": 527.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 668.0, + "frame_start": 569.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 740.0, + "frame_start": 669.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "palace-ruins-attack-res": { + "lines": [ + { + "frame_end": 320.0, + "frame_start": 299.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 416.0, + "frame_start": 337.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 582.0, + "frame_start": 451.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 751.0, + "frame_start": 598.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 879.0, + "frame_start": 802.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 967.0, + "frame_start": 893.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1175.0, + "frame_start": 968.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1266.0, + "frame_start": 1176.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1403.0, + "frame_start": 1283.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1566.0, + "frame_start": 1404.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1744.0, + "frame_start": 1620.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1964.0, + "frame_start": 1947.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2069.0, + "frame_start": 1986.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2221.0, + "frame_start": 2070.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2291.0, + "frame_start": 2222.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2430.0, + "frame_start": 2292.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2565.0, + "frame_start": 2431.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2716.0, + "frame_start": 2566.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2782.0, + "frame_start": 2730.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2880.0, + "frame_start": 2801.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3018.0, + "frame_start": 2881.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3142.0, + "frame_start": 3111.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3241.0, + "frame_start": 3148.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3293.0, + "frame_start": 3246.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3416.0, + "frame_start": 3294.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3447.0, + "frame_start": 3417.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "nest-hunt-intro": { + "lines": [ + { + "frame_end": 37.0, + "frame_start": 15.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 95.0, + "frame_start": 38.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 193.0, + "frame_start": 96.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 304.0, + "frame_start": 194.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 411.0, + "frame_start": 305.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 467.0, + "frame_start": 412.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 563.0, + "frame_start": 468.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "nest-eggs-intro": { + "lines": [ + { + "frame_end": 128.0, + "frame_start": 38.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 231.0, + "frame_start": 129.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 349.0, + "frame_start": 232.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 435.0, + "frame_start": 350.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 567.0, + "frame_start": 436.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 644.0, + "frame_start": 568.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 694.0, + "frame_start": 645.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 727.0, + "frame_start": 701.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 786.0, + "frame_start": 729.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 879.0, + "frame_start": 787.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 978.0, + "frame_start": 880.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1046.0, + "frame_start": 979.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1132.0, + "frame_start": 1047.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1226.0, + "frame_start": 1133.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "mine-boss-res": { + "lines": [ + { + "frame_end": 339.0, + "frame_start": 311.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 404.0, + "frame_start": 341.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 492.0, + "frame_start": 412.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-protect-hq-intro": { + "lines": [ + { + "frame_end": 92.0, + "frame_start": 31.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 201.0, + "frame_start": 93.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 265.0, + "frame_start": 205.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 340.0, + "frame_start": 272.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 382.0, + "frame_start": 343.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 473.0, + "frame_start": 388.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 511.0, + "frame_start": 474.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 596.0, + "frame_start": 512.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 680.0, + "frame_start": 603.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 815.0, + "frame_start": 688.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 864.0, + "frame_start": 816.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 941.0, + "frame_start": 865.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1063.0, + "frame_start": 942.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1165.0, + "frame_start": 1064.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1244.0, + "frame_start": 1166.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1343.0, + "frame_start": 1254.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1390.0, + "frame_start": 1344.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1504.0, + "frame_start": 1391.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1621.0, + "frame_start": 1515.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1728.0, + "frame_start": 1633.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1897.0, + "frame_start": 1729.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1931.0, + "frame_start": 1905.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2039.0, + "frame_start": 1936.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2087.0, + "frame_start": 2040.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2178.0, + "frame_start": 2091.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-power-game-res": { + "lines": [ + { + "frame_end": 100.0, + "frame_start": 71.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 205.0, + "frame_start": 110.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 297.0, + "frame_start": 206.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 361.0, + "frame_start": 298.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 453.0, + "frame_start": 371.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 480.0, + "frame_start": 454.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "catacombs-wild-ride-res": { + "lines": [ + { + "frame_end": 751.0, + "frame_start": 478.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 938.0, + "frame_start": 799.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1081.0, + "frame_start": 939.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1233.0, + "frame_start": 1117.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1523.0, + "frame_start": 1234.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1579.0, + "frame_start": 1547.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1689.0, + "frame_start": 1580.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1796.0, + "frame_start": 1694.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2002.0, + "frame_start": 1919.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2162.0, + "frame_start": 2003.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2267.0, + "frame_start": 2168.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2429.0, + "frame_start": 2268.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2649.0, + "frame_start": 2449.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2782.0, + "frame_start": 2652.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2862.0, + "frame_start": 2783.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2921.0, + "frame_start": 2863.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3118.0, + "frame_start": 3010.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3291.0, + "frame_start": 3119.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3491.0, + "frame_start": 3439.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3683.0, + "frame_start": 3496.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3936.0, + "frame_start": 3684.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3974.0, + "frame_start": 3950.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4029.0, + "frame_start": 3988.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4090.0, + "frame_start": 4038.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4153.0, + "frame_start": 4095.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4198.0, + "frame_start": 4159.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4345.0, + "frame_start": 4199.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4395.0, + "frame_start": 4346.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4441.0, + "frame_start": 4400.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4545.0, + "frame_start": 4445.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4611.0, + "frame_start": 4546.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4648.0, + "frame_start": 4614.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4745.0, + "frame_start": 4649.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4866.0, + "frame_start": 4798.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4954.0, + "frame_start": 4867.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4981.0, + "frame_start": 4960.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5008.0, + "frame_start": 4982.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5057.0, + "frame_start": 5013.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5079.0, + "frame_start": 5058.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5221.0, + "frame_start": 5080.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5291.0, + "frame_start": 5222.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5375.0, + "frame_start": 5292.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5440.0, + "frame_start": 5379.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5548.0, + "frame_start": 5441.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5636.0, + "frame_start": 5549.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5724.0, + "frame_start": 5654.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5787.0, + "frame_start": 5725.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5907.0, + "frame_start": 5798.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6030.0, + "frame_start": 5965.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6162.0, + "frame_start": 6042.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6243.0, + "frame_start": 6163.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6311.0, + "frame_start": 6248.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6345.0, + "frame_start": 6321.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6382.0, + "frame_start": 6352.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6509.0, + "frame_start": 6383.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6543.0, + "frame_start": 6510.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6603.0, + "frame_start": 6545.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6640.0, + "frame_start": 6616.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 6823.0, + "frame_start": 6777.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-power-game-intro": { + "lines": [ + { + "frame_end": 129.0, + "frame_start": 79.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 186.0, + "frame_start": 130.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 277.0, + "frame_start": 195.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 333.0, + "frame_start": 281.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 399.0, + "frame_start": 334.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 463.0, + "frame_start": 401.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 555.0, + "frame_start": 472.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 658.0, + "frame_start": 556.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 744.0, + "frame_start": 659.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 804.0, + "frame_start": 757.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 899.0, + "frame_start": 807.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1031.0, + "frame_start": 900.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1082.0, + "frame_start": 1032.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1221.0, + "frame_start": 1083.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1321.0, + "frame_start": 1222.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1434.0, + "frame_start": 1322.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1523.0, + "frame_start": 1435.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1550.0, + "frame_start": 1532.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1573.0, + "frame_start": 1558.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1601.0, + "frame_start": 1577.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1630.0, + "frame_start": 1602.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1653.0, + "frame_start": 1634.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1682.0, + "frame_start": 1658.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1748.0, + "frame_start": 1683.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1871.0, + "frame_start": 1749.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1959.0, + "frame_start": 1872.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2090.0, + "frame_start": 1960.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2132.0, + "frame_start": 2095.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2212.0, + "frame_start": 2138.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2322.0, + "frame_start": 2213.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2369.0, + "frame_start": 2323.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2480.0, + "frame_start": 2377.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2607.0, + "frame_start": 2485.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2741.0, + "frame_start": 2608.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2773.0, + "frame_start": 2742.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2871.0, + "frame_start": 2789.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2935.0, + "frame_start": 2872.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2982.0, + "frame_start": 2940.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-gun-course-2-res": { + "lines": [ + { + "frame_end": 75.0, + "frame_start": 17.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 172.0, + "frame_start": 76.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 227.0, + "frame_start": 173.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 351.0, + "frame_start": 228.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-leaper-race-res": { + "lines": [ + { + "frame_end": 69.0, + "frame_start": 46.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 151.0, + "frame_start": 70.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 207.0, + "frame_start": 161.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 296.0, + "frame_start": 215.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 409.0, + "frame_start": 297.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 448.0, + "frame_start": 410.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 550.0, + "frame_start": 449.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 588.0, + "frame_start": 558.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 641.0, + "frame_start": 591.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 679.0, + "frame_start": 642.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 791.0, + "frame_start": 680.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 875.0, + "frame_start": 792.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "palace-ruins-attack-intro": { + "lines": [ + { + "frame_end": 173.0, + "frame_start": 40.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 312.0, + "frame_start": 174.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 501.0, + "frame_start": 386.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 655.0, + "frame_start": 502.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 756.0, + "frame_start": 656.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 915.0, + "frame_start": 873.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 979.0, + "frame_start": 917.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1063.0, + "frame_start": 980.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1148.0, + "frame_start": 1074.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1246.0, + "frame_start": 1149.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1291.0, + "frame_start": 1258.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-port-attack-intro": { + "lines": [ + { + "frame_end": 133.0, + "frame_start": 31.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 219.0, + "frame_start": 146.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 294.0, + "frame_start": 223.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 391.0, + "frame_start": 295.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 418.0, + "frame_start": 400.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 496.0, + "frame_start": 425.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 575.0, + "frame_start": 497.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 678.0, + "frame_start": 576.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 766.0, + "frame_start": 679.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 838.0, + "frame_start": 767.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 919.0, + "frame_start": 839.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1022.0, + "frame_start": 948.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1072.0, + "frame_start": 1023.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1164.0, + "frame_start": 1080.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1223.0, + "frame_start": 1165.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1334.0, + "frame_start": 1224.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1398.0, + "frame_start": 1343.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1462.0, + "frame_start": 1399.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1540.0, + "frame_start": 1463.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1606.0, + "frame_start": 1541.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1682.0, + "frame_start": 1611.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1726.0, + "frame_start": 1686.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1786.0, + "frame_start": 1727.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "forest-ring-chase-res": { + "lines": [ + { + "frame_end": 199.0, + "frame_start": 85.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 325.0, + "frame_start": 200.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 421.0, + "frame_start": 335.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 569.0, + "frame_start": 431.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 720.0, + "frame_start": 570.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 819.0, + "frame_start": 721.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 942.0, + "frame_start": 820.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1130.0, + "frame_start": 943.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1345.0, + "frame_start": 1131.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1397.0, + "frame_start": 1353.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1464.0, + "frame_start": 1406.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1549.0, + "frame_start": 1473.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1715.0, + "frame_start": 1550.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1810.0, + "frame_start": 1716.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1925.0, + "frame_start": 1811.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2019.0, + "frame_start": 1926.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-gun-course-2-intro": { + "lines": [ + { + "frame_end": 61.0, + "frame_start": 41.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 99.0, + "frame_start": 62.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 178.0, + "frame_start": 100.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 244.0, + "frame_start": 179.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 383.0, + "frame_start": 246.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 462.0, + "frame_start": 384.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 562.0, + "frame_start": 463.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 679.0, + "frame_start": 568.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 764.0, + "frame_start": 680.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 852.0, + "frame_start": 769.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 897.0, + "frame_start": 861.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 939.0, + "frame_start": 899.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1074.0, + "frame_start": 945.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1181.0, + "frame_start": 1075.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1213.0, + "frame_start": 1182.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-rescue": { + "lines": [ + { + "frame_end": 285.0, + "frame_start": 155.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 377.0, + "frame_start": 309.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 415.0, + "frame_start": 378.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 468.0, + "frame_start": 435.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 566.0, + "frame_start": 469.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-port-attack-intro-b": { + "lines": [ + { + "frame_end": 82.0, + "frame_start": 51.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-gun-course-1-res": { + "lines": [ + { + "frame_end": 129.0, + "frame_start": 46.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 216.0, + "frame_start": 131.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 335.0, + "frame_start": 218.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 366.0, + "frame_start": 336.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 452.0, + "frame_start": 367.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-protect-hq-res": { + "lines": [ + { + "frame_end": 59.0, + "frame_start": 19.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 200.0, + "frame_start": 60.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 309.0, + "frame_start": 201.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 404.0, + "frame_start": 310.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 525.0, + "frame_start": 405.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 609.0, + "frame_start": 526.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 671.0, + "frame_start": 616.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 740.0, + "frame_start": 678.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 819.0, + "frame_start": 741.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 916.0, + "frame_start": 820.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 991.0, + "frame_start": 917.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1096.0, + "frame_start": 1034.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1141.0, + "frame_start": 1097.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1157.0, + "frame_start": 1142.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1213.0, + "frame_start": 1174.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1268.0, + "frame_start": 1214.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1295.0, + "frame_start": 1269.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1385.0, + "frame_start": 1299.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1491.0, + "frame_start": 1386.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1551.0, + "frame_start": 1492.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1618.0, + "frame_start": 1554.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1804.0, + "frame_start": 1635.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1856.0, + "frame_start": 1805.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1949.0, + "frame_start": 1901.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2030.0, + "frame_start": 1956.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2114.0, + "frame_start": 2031.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2254.0, + "frame_start": 2115.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2390.0, + "frame_start": 2266.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2436.0, + "frame_start": 2391.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2533.0, + "frame_start": 2437.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2626.0, + "frame_start": 2540.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2751.0, + "frame_start": 2627.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2830.0, + "frame_start": 2752.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2903.0, + "frame_start": 2831.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-find-catacomb-ent-intro": { + "lines": [ + { + "frame_end": 76.0, + "frame_start": 15.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 168.0, + "frame_start": 85.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 259.0, + "frame_start": 169.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 346.0, + "frame_start": 260.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 503.0, + "frame_start": 347.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 638.0, + "frame_start": 509.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 752.0, + "frame_start": 644.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 840.0, + "frame_start": 765.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 964.0, + "frame_start": 850.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1056.0, + "frame_start": 965.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1171.0, + "frame_start": 1057.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1217.0, + "frame_start": 1172.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1370.0, + "frame_start": 1223.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1457.0, + "frame_start": 1380.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1529.0, + "frame_start": 1458.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1630.0, + "frame_start": 1530.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1727.0, + "frame_start": 1631.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-pre-game-res": { + "lines": [ + { + "frame_end": 83.0, + "frame_start": 59.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 157.0, + "frame_start": 96.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 261.0, + "frame_start": 190.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 307.0, + "frame_start": 262.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 380.0, + "frame_start": 317.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 524.0, + "frame_start": 381.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 568.0, + "frame_start": 526.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 636.0, + "frame_start": 569.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 708.0, + "frame_start": 637.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 794.0, + "frame_start": 709.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 863.0, + "frame_start": 796.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 937.0, + "frame_start": 865.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1024.0, + "frame_start": 946.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1312.0, + "frame_start": 1229.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1378.0, + "frame_start": 1319.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1481.0, + "frame_start": 1379.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1569.0, + "frame_start": 1487.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1644.0, + "frame_start": 1570.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1700.0, + "frame_start": 1651.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1796.0, + "frame_start": 1701.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "factory-boss-res": { + "lines": [ + { + "frame_end": 305.0, + "frame_start": 265.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 390.0, + "frame_start": 315.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 486.0, + "frame_start": 426.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-blow-tower-intro": { + "lines": [ + { + "frame_end": 99.0, + "frame_start": 15.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 136.0, + "frame_start": 100.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 206.0, + "frame_start": 143.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 264.0, + "frame_start": 211.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 343.0, + "frame_start": 272.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 386.0, + "frame_start": 344.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 471.0, + "frame_start": 387.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 525.0, + "frame_start": 477.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 576.0, + "frame_start": 526.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 599.0, + "frame_start": 579.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 666.0, + "frame_start": 600.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 713.0, + "frame_start": 667.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 735.0, + "frame_start": 714.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 831.0, + "frame_start": 736.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 960.0, + "frame_start": 832.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1018.0, + "frame_start": 961.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1038.0, + "frame_start": 1019.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1116.0, + "frame_start": 1039.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1199.0, + "frame_start": 1117.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1329.0, + "frame_start": 1200.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1367.0, + "frame_start": 1332.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1479.0, + "frame_start": 1368.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1594.0, + "frame_start": 1480.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1711.0, + "frame_start": 1603.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-fight-1-intro": { + "lines": [ + { + "frame_end": 111.0, + "frame_start": 40.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 226.0, + "frame_start": 114.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 295.0, + "frame_start": 230.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 360.0, + "frame_start": 299.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 513.0, + "frame_start": 392.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 577.0, + "frame_start": 515.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 610.0, + "frame_start": 578.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 745.0, + "frame_start": 614.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 784.0, + "frame_start": 746.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 888.0, + "frame_start": 787.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 933.0, + "frame_start": 898.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 995.0, + "frame_start": 945.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1049.0, + "frame_start": 999.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1131.0, + "frame_start": 1051.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-destroy-grid-res": { + "lines": [ + { + "frame_end": 172.0, + "frame_start": 119.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 247.0, + "frame_start": 173.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 312.0, + "frame_start": 259.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 371.0, + "frame_start": 313.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 413.0, + "frame_start": 372.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-fight-3-res": { + "lines": [ + { + "frame_end": 104.0, + "frame_start": 85.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 157.0, + "frame_start": 114.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 182.0, + "frame_start": 159.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 251.0, + "frame_start": 187.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 282.0, + "frame_start": 252.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 363.0, + "frame_start": 284.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 454.0, + "frame_start": 372.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 499.0, + "frame_start": 455.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 604.0, + "frame_start": 500.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 636.0, + "frame_start": 607.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 879.0, + "frame_start": 795.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 982.0, + "frame_start": 880.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1068.0, + "frame_start": 1001.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1112.0, + "frame_start": 1079.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-port-fight-intro": { + "lines": [ + { + "frame_end": 65.0, + "frame_start": 15.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 111.0, + "frame_start": 66.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 195.0, + "frame_start": 113.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 291.0, + "frame_start": 196.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 363.0, + "frame_start": 296.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 475.0, + "frame_start": 364.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 521.0, + "frame_start": 477.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 588.0, + "frame_start": 523.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 606.0, + "frame_start": 589.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 732.0, + "frame_start": 609.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 766.0, + "frame_start": 733.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 852.0, + "frame_start": 767.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 879.0, + "frame_start": 856.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 956.0, + "frame_start": 880.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1009.0, + "frame_start": 957.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1121.0, + "frame_start": 1010.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1183.0, + "frame_start": 1122.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1334.0, + "frame_start": 1184.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1421.0, + "frame_start": 1336.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1465.0, + "frame_start": 1422.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1546.0, + "frame_start": 1466.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1576.0, + "frame_start": 1547.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1611.0, + "frame_start": 1577.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1677.0, + "frame_start": 1615.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1725.0, + "frame_start": 1678.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "catacomb-get-shield": { + "lines": [ + { + "frame_end": 172.0, + "frame_start": 60.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 284.0, + "frame_start": 173.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 397.0, + "frame_start": 285.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 499.0, + "frame_start": 398.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-fight-2-intro": { + "lines": [ + { + "frame_end": 130.0, + "frame_start": 25.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 237.0, + "frame_start": 131.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 325.0, + "frame_start": 238.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 415.0, + "frame_start": 326.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 491.0, + "frame_start": 418.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 578.0, + "frame_start": 492.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 625.0, + "frame_start": 579.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 717.0, + "frame_start": 626.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 788.0, + "frame_start": 718.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 868.0, + "frame_start": 790.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "factory-boss-intro": { + "lines": [ + { + "frame_end": 347.0, + "frame_start": 226.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 407.0, + "frame_start": 354.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 566.0, + "frame_start": 415.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 690.0, + "frame_start": 567.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 849.0, + "frame_start": 691.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 986.0, + "frame_start": 850.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1064.0, + "frame_start": 987.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1117.0, + "frame_start": 1066.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1188.0, + "frame_start": 1118.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1236.0, + "frame_start": 1189.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1381.0, + "frame_start": 1247.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1506.0, + "frame_start": 1382.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1641.0, + "frame_start": 1507.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1744.0, + "frame_start": 1642.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1799.0, + "frame_start": 1753.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "volcano-indax-2-intro": { + "lines": [ + { + "frame_end": 178.0, + "frame_start": 129.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-fight-1-res": { + "lines": [ + { + "frame_end": 273.0, + "frame_start": 204.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 384.0, + "frame_start": 276.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 495.0, + "frame_start": 386.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 537.0, + "frame_start": 500.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 564.0, + "frame_start": 539.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 635.0, + "frame_start": 571.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 673.0, + "frame_start": 636.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 771.0, + "frame_start": 684.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 878.0, + "frame_start": 772.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 961.0, + "frame_start": 879.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1077.0, + "frame_start": 962.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1201.0, + "frame_start": 1078.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1265.0, + "frame_start": 1202.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1371.0, + "frame_start": 1266.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1432.0, + "frame_start": 1372.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1498.0, + "frame_start": 1433.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1567.0, + "frame_start": 1499.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "catacombs-travel-res": { + "lines": [ + { + "frame_end": 108.0, + "frame_start": 40.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 170.0, + "frame_start": 110.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 260.0, + "frame_start": 171.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 362.0, + "frame_start": 268.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 431.0, + "frame_start": 373.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 556.0, + "frame_start": 432.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-fight-2-res": { + "lines": [ + { + "frame_end": 83.0, + "frame_start": 10.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 131.0, + "frame_start": 86.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 217.0, + "frame_start": 135.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 290.0, + "frame_start": 219.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 415.0, + "frame_start": 293.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 529.0, + "frame_start": 416.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 637.0, + "frame_start": 530.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 712.0, + "frame_start": 638.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 791.0, + "frame_start": 714.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 855.0, + "frame_start": 792.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 928.0, + "frame_start": 856.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1022.0, + "frame_start": 930.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1098.0, + "frame_start": 1040.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1149.0, + "frame_start": 1101.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1171.0, + "frame_start": 1150.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1254.0, + "frame_start": 1172.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1338.0, + "frame_start": 1255.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1478.0, + "frame_start": 1339.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1597.0, + "frame_start": 1479.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1711.0, + "frame_start": 1598.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-training-1-intro": { + "lines": [ + { + "frame_end": 112.0, + "frame_start": 27.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 204.0, + "frame_start": 113.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 307.0, + "frame_start": 205.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 408.0, + "frame_start": 308.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 519.0, + "frame_start": 409.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 665.0, + "frame_start": 520.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 796.0, + "frame_start": 732.0, + "merge": true, + "offscreen": false, + "speaker": "jak" + }, + { + "frame_end": 888.0, + "frame_start": 798.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 961.0, + "frame_start": 889.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 986.0, + "frame_start": 962.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 1101.0, + "frame_start": 987.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 1162.0, + "frame_start": 1102.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 1235.0, + "frame_start": 1163.0, + "merge": true, + "offscreen": false, + "speaker": "daxter" + }, + { + "frame_end": 1317.0, + "frame_start": 1241.0, + "merge": true, + "offscreen": false, + "speaker": "damas" + }, + { + "frame_end": 1388.0, + "frame_start": 1318.0, + "merge": true, + "offscreen": false, + "speaker": "damas" + }, + { + "frame_end": 1494.0, + "frame_start": 1398.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 1542.0, + "frame_start": 1498.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 1657.0, + "frame_start": 1543.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + }, + { + "frame_end": 1684.0, + "frame_start": 1658.0, + "merge": true, + "offscreen": false, + "speaker": "daxter" + }, + { + "frame_end": 1745.0, + "frame_start": 1685.0, + "merge": true, + "offscreen": false, + "speaker": "pecker" + } + ] + }, + "arena-fight-3-intro": { + "lines": [ + { + "frame_end": 211.0, + "frame_start": 142.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 439.0, + "frame_start": 212.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 488.0, + "frame_start": 440.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 555.0, + "frame_start": 493.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 630.0, + "frame_start": 556.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 646.0, + "frame_start": 631.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 661.0, + "frame_start": 647.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 751.0, + "frame_start": 662.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 802.0, + "frame_start": 752.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 935.0, + "frame_start": 803.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "tower-destroy-res": { + "lines": [ + { + "frame_end": 127.0, + "frame_start": 32.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 222.0, + "frame_start": 128.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 292.0, + "frame_start": 223.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 344.0, + "frame_start": 297.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 444.0, + "frame_start": 345.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 473.0, + "frame_start": 450.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 553.0, + "frame_start": 474.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 682.0, + "frame_start": 554.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 760.0, + "frame_start": 683.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 797.0, + "frame_start": 787.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 947.0, + "frame_start": 798.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 974.0, + "frame_start": 948.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1088.0, + "frame_start": 1054.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "arena-outro": { + "lines": [ + { + "frame_end": 254.0, + "frame_start": 178.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 376.0, + "frame_start": 255.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 489.0, + "frame_start": 377.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 660.0, + "frame_start": 499.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 777.0, + "frame_start": 671.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 879.0, + "frame_start": 788.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 980.0, + "frame_start": 880.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1064.0, + "frame_start": 981.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1172.0, + "frame_start": 1069.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1245.0, + "frame_start": 1173.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1299.0, + "frame_start": 1246.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1386.0, + "frame_start": 1303.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1528.0, + "frame_start": 1391.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1588.0, + "frame_start": 1533.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1673.0, + "frame_start": 1589.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1785.0, + "frame_start": 1684.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1881.0, + "frame_start": 1805.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1923.0, + "frame_start": 1893.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2023.0, + "frame_start": 1934.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2117.0, + "frame_start": 2024.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2179.0, + "frame_start": 2118.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2271.0, + "frame_start": 2180.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2382.0, + "frame_start": 2281.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2475.0, + "frame_start": 2387.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2547.0, + "frame_start": 2476.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2719.0, + "frame_start": 2594.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2916.0, + "frame_start": 2785.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2977.0, + "frame_start": 2919.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3137.0, + "frame_start": 3081.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3245.0, + "frame_start": 3138.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3364.0, + "frame_start": 3277.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3454.0, + "frame_start": 3388.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3598.0, + "frame_start": 3461.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3674.0, + "frame_start": 3631.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3819.0, + "frame_start": 3696.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3888.0, + "frame_start": 3827.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4019.0, + "frame_start": 3889.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4158.0, + "frame_start": 4020.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4283.0, + "frame_start": 4194.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4310.0, + "frame_start": 4293.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4367.0, + "frame_start": 4319.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 4906.0, + "frame_start": 4860.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5015.0, + "frame_start": 4907.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5100.0, + "frame_start": 5017.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5192.0, + "frame_start": 5106.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5297.0, + "frame_start": 5193.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 5367.0, + "frame_start": 5298.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-blow-barricade-intro": { + "lines": [ + { + "frame_end": 147.0, + "frame_start": 36.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 248.0, + "frame_start": 154.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 312.0, + "frame_start": 249.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 392.0, + "frame_start": 313.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 436.0, + "frame_start": 393.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 517.0, + "frame_start": 438.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 593.0, + "frame_start": 518.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 673.0, + "frame_start": 594.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 816.0, + "frame_start": 678.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 930.0, + "frame_start": 817.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1004.0, + "frame_start": 931.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1068.0, + "frame_start": 1005.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-chase-intro": { + "lines": [ + { + "frame_end": 97.0, + "frame_start": 21.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 189.0, + "frame_start": 98.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 231.0, + "frame_start": 199.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 299.0, + "frame_start": 233.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 404.0, + "frame_start": 302.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 465.0, + "frame_start": 405.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 535.0, + "frame_start": 466.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 568.0, + "frame_start": 540.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 648.0, + "frame_start": 570.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 782.0, + "frame_start": 649.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 877.0, + "frame_start": 783.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 956.0, + "frame_start": 878.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1036.0, + "frame_start": 957.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1097.0, + "frame_start": 1037.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1177.0, + "frame_start": 1098.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1281.0, + "frame_start": 1178.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1320.0, + "frame_start": 1284.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1361.0, + "frame_start": 1327.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1448.0, + "frame_start": 1362.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "mine-boss-intro": { + "lines": [ + { + "frame_end": 362.0, + "frame_start": 259.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 409.0, + "frame_start": 363.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 547.0, + "frame_start": 410.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 626.0, + "frame_start": 548.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 798.0, + "frame_start": 627.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 927.0, + "frame_start": 799.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 993.0, + "frame_start": 936.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1051.0, + "frame_start": 994.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1157.0, + "frame_start": 1059.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1217.0, + "frame_start": 1158.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1279.0, + "frame_start": 1218.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1370.0, + "frame_start": 1280.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1542.0, + "frame_start": 1380.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1608.0, + "frame_start": 1543.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1657.0, + "frame_start": 1613.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1707.0, + "frame_start": 1660.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1785.0, + "frame_start": 1708.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1882.0, + "frame_start": 1786.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1964.0, + "frame_start": 1883.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2048.0, + "frame_start": 1965.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2166.0, + "frame_start": 2049.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2233.0, + "frame_start": 2169.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2256.0, + "frame_start": 2234.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2294.0, + "frame_start": 2259.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2397.0, + "frame_start": 2295.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2423.0, + "frame_start": 2398.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2530.0, + "frame_start": 2424.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2594.0, + "frame_start": 2531.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2693.0, + "frame_start": 2595.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2716.0, + "frame_start": 2694.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2810.0, + "frame_start": 2717.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2971.0, + "frame_start": 2811.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3175.0, + "frame_start": 3060.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-blow-barricade-res": { + "lines": [ + { + "frame_end": 86.0, + "frame_start": 56.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 157.0, + "frame_start": 87.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 241.0, + "frame_start": 158.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 287.0, + "frame_start": 242.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 344.0, + "frame_start": 288.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-get-to-catacombs-intro": { + "lines": [ + { + "frame_end": 76.0, + "frame_start": 15.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 168.0, + "frame_start": 85.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 259.0, + "frame_start": 169.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 346.0, + "frame_start": 260.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 503.0, + "frame_start": 347.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 638.0, + "frame_start": 509.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 752.0, + "frame_start": 644.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 840.0, + "frame_start": 765.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 964.0, + "frame_start": 850.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1056.0, + "frame_start": 965.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1171.0, + "frame_start": 1057.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1217.0, + "frame_start": 1172.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1370.0, + "frame_start": 1223.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1457.0, + "frame_start": 1380.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1529.0, + "frame_start": 1458.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1630.0, + "frame_start": 1530.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1727.0, + "frame_start": 1631.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-glide-res": { + "lines": [ + { + "frame_end": 301.0, + "frame_start": 231.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 336.0, + "frame_start": 308.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 382.0, + "frame_start": 339.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 440.0, + "frame_start": 413.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-palace": { + "lines": [ + { + "frame_end": 101.0, + "frame_start": 79.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 118.0, + "frame_start": 107.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 188.0, + "frame_start": 119.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 271.0, + "frame_start": 189.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 373.0, + "frame_start": 272.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 425.0, + "frame_start": 374.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 496.0, + "frame_start": 434.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 578.0, + "frame_start": 497.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 665.0, + "frame_start": 579.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 709.0, + "frame_start": 673.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 767.0, + "frame_start": 716.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 851.0, + "frame_start": 768.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 940.0, + "frame_start": 852.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1308.0, + "frame_start": 1255.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1473.0, + "frame_start": 1444.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1499.0, + "frame_start": 1481.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1945.0, + "frame_start": 1890.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-sniper-fight-intro": { + "lines": [ + { + "frame_end": 115.0, + "frame_start": 37.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 216.0, + "frame_start": 116.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 321.0, + "frame_start": 217.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 447.0, + "frame_start": 322.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 496.0, + "frame_start": 448.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 592.0, + "frame_start": 502.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-port-attack-res": { + "lines": [ + { + "frame_end": 79.0, + "frame_start": 9.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-drop": { + "lines": [ + { + "frame_end": 997.0, + "frame_start": 908.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1098.0, + "frame_start": 998.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1240.0, + "frame_start": 1099.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1336.0, + "frame_start": 1245.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1402.0, + "frame_start": 1337.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1480.0, + "frame_start": 1403.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1519.0, + "frame_start": 1481.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1569.0, + "frame_start": 1523.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1629.0, + "frame_start": 1570.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1677.0, + "frame_start": 1630.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1809.0, + "frame_start": 1678.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1858.0, + "frame_start": 1811.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1930.0, + "frame_start": 1865.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1994.0, + "frame_start": 1936.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2035.0, + "frame_start": 1995.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2133.0, + "frame_start": 2036.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2156.0, + "frame_start": 2134.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2203.0, + "frame_start": 2158.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2308.0, + "frame_start": 2204.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2323.0, + "frame_start": 2309.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2385.0, + "frame_start": 2326.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2480.0, + "frame_start": 2386.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2588.0, + "frame_start": 2500.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2800.0, + "frame_start": 2774.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2836.0, + "frame_start": 2801.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2933.0, + "frame_start": 2836.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3054.0, + "frame_start": 2934.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3123.0, + "frame_start": 3056.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3224.0, + "frame_start": 3124.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3253.0, + "frame_start": 3225.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3350.0, + "frame_start": 3254.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3399.0, + "frame_start": 3351.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 3454.0, + "frame_start": 3401.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "palace-ruins-patrol-intro": { + "lines": [ + { + "frame_end": 80.0, + "frame_start": 22.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 157.0, + "frame_start": 81.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 230.0, + "frame_start": 199.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 384.0, + "frame_start": 323.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 465.0, + "frame_start": 385.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-artifact-race-1-intro": { + "lines": [ + { + "frame_end": 94.0, + "frame_start": 62.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 179.0, + "frame_start": 95.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 212.0, + "frame_start": 183.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 278.0, + "frame_start": 217.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 334.0, + "frame_start": 279.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 365.0, + "frame_start": 337.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 459.0, + "frame_start": 368.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 604.0, + "frame_start": 460.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 752.0, + "frame_start": 609.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 802.0, + "frame_start": 753.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 861.0, + "frame_start": 803.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 952.0, + "frame_start": 862.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1021.0, + "frame_start": 955.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-lizard-catch-2": { + "lines": [ + { + "frame_end": 121.0, + "frame_start": 79.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "sewer-met-hum-intro": { + "lines": [ + { + "frame_end": 124.0, + "frame_start": 44.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 191.0, + "frame_start": 137.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 218.0, + "frame_start": 195.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 236.0, + "frame_start": 219.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 390.0, + "frame_start": 246.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 506.0, + "frame_start": 394.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 605.0, + "frame_start": 513.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 748.0, + "frame_start": 606.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 861.0, + "frame_start": 749.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 917.0, + "frame_start": 862.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1022.0, + "frame_start": 930.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1097.0, + "frame_start": 1028.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1155.0, + "frame_start": 1105.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1274.0, + "frame_start": 1156.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1383.0, + "frame_start": 1281.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1504.0, + "frame_start": 1384.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1639.0, + "frame_start": 1505.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1791.0, + "frame_start": 1640.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1853.0, + "frame_start": 1792.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1909.0, + "frame_start": 1869.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-hijack-vehicle-res": { + "lines": [ + { + "frame_end": 29.0, + "frame_start": 6.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 96.0, + "frame_start": 37.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 132.0, + "frame_start": 110.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 166.0, + "frame_start": 135.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 331.0, + "frame_start": 307.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 372.0, + "frame_start": 332.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-lizard-catch-3": { + "lines": [ + { + "frame_end": 128.0, + "frame_start": 75.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 379.0, + "frame_start": 295.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 466.0, + "frame_start": 380.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 502.0, + "frame_start": 474.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 580.0, + "frame_start": 503.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 620.0, + "frame_start": 584.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 661.0, + "frame_start": 627.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-training": { + "lines": [ + { + "frame_end": 333.0, + "frame_start": 162.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 408.0, + "frame_start": 334.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 483.0, + "frame_start": 409.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 581.0, + "frame_start": 484.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 728.0, + "frame_start": 584.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 821.0, + "frame_start": 735.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 963.0, + "frame_start": 822.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1021.0, + "frame_start": 964.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1092.0, + "frame_start": 1022.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1204.0, + "frame_start": 1093.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1279.0, + "frame_start": 1207.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1363.0, + "frame_start": 1280.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1477.0, + "frame_start": 1364.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1614.0, + "frame_start": 1478.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1697.0, + "frame_start": 1616.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1902.0, + "frame_start": 1699.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1981.0, + "frame_start": 1903.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2070.0, + "frame_start": 1982.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2201.0, + "frame_start": 2071.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2256.0, + "frame_start": 2202.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2360.0, + "frame_start": 2258.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2438.0, + "frame_start": 2362.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 2492.0, + "frame_start": 2450.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-ffhq": { + "lines": [ + { + "frame_end": 74.0, + "frame_start": 27.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 146.0, + "frame_start": 75.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 218.0, + "frame_start": 147.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 273.0, + "frame_start": 219.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 333.0, + "frame_start": 274.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 400.0, + "frame_start": 334.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 468.0, + "frame_start": 403.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 541.0, + "frame_start": 469.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 629.0, + "frame_start": 542.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 673.0, + "frame_start": 630.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 768.0, + "frame_start": 675.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 858.0, + "frame_start": 769.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 917.0, + "frame_start": 862.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-artifact-race-1-res": { + "lines": [ + { + "frame_end": 133.0, + "frame_start": 56.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 223.0, + "frame_start": 138.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 305.0, + "frame_start": 225.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 418.0, + "frame_start": 306.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 525.0, + "frame_start": 419.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 592.0, + "frame_start": 526.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 696.0, + "frame_start": 593.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 802.0, + "frame_start": 697.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-artifact-race-2-intro": { + "lines": [ + { + "frame_end": 133.0, + "frame_start": 69.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 198.0, + "frame_start": 134.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 247.0, + "frame_start": 199.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 317.0, + "frame_start": 254.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 337.0, + "frame_start": 325.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 412.0, + "frame_start": 338.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 441.0, + "frame_start": 413.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 554.0, + "frame_start": 442.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 583.0, + "frame_start": 555.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-oasis-defense-res": { + "lines": [ + { + "frame_end": 140.0, + "frame_start": 73.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 237.0, + "frame_start": 141.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 318.0, + "frame_start": 238.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 385.0, + "frame_start": 331.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 449.0, + "frame_start": 391.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 528.0, + "frame_start": 454.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 617.0, + "frame_start": 529.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 652.0, + "frame_start": 618.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 747.0, + "frame_start": 666.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 804.0, + "frame_start": 756.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 859.0, + "frame_start": 805.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 896.0, + "frame_start": 870.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 957.0, + "frame_start": 917.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1031.0, + "frame_start": 958.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1072.0, + "frame_start": 1032.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1151.0, + "frame_start": 1073.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1214.0, + "frame_start": 1152.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1240.0, + "frame_start": 1215.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1282.0, + "frame_start": 1264.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-beast-battle-intro": { + "lines": [ + { + "frame_end": 158.0, + "frame_start": 44.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 195.0, + "frame_start": 159.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 234.0, + "frame_start": 201.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 399.0, + "frame_start": 239.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 521.0, + "frame_start": 400.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 594.0, + "frame_start": 522.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 646.0, + "frame_start": 595.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 766.0, + "frame_start": 647.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 825.0, + "frame_start": 767.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 898.0, + "frame_start": 826.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 969.0, + "frame_start": 912.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1060.0, + "frame_start": 975.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-catch-lizards-intro": { + "lines": [ + { + "frame_end": 212.0, + "frame_start": 60.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 302.0, + "frame_start": 220.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 423.0, + "frame_start": 310.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 466.0, + "frame_start": 426.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 506.0, + "frame_start": 468.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 638.0, + "frame_start": 507.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 749.0, + "frame_start": 670.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 850.0, + "frame_start": 750.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 892.0, + "frame_start": 860.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1065.0, + "frame_start": 929.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1152.0, + "frame_start": 1067.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1235.0, + "frame_start": 1153.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1274.0, + "frame_start": 1236.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1391.0, + "frame_start": 1302.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1477.0, + "frame_start": 1392.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1553.0, + "frame_start": 1478.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1627.0, + "frame_start": 1554.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1697.0, + "frame_start": 1637.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1873.0, + "frame_start": 1763.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-tired": { + "lines": [ + { + "frame_end": 239.0, + "frame_start": 215.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 284.0, + "frame_start": 252.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 369.0, + "frame_start": 337.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 435.0, + "frame_start": 388.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 558.0, + "frame_start": 453.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 660.0, + "frame_start": 621.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "wascity-pre-game-intro": { + "lines": [ + { + "frame_end": 146.0, + "frame_start": 49.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 209.0, + "frame_start": 147.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 256.0, + "frame_start": 210.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 329.0, + "frame_start": 259.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 427.0, + "frame_start": 331.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 492.0, + "frame_start": 429.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 556.0, + "frame_start": 493.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 604.0, + "frame_start": 560.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 747.0, + "frame_start": 610.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 825.0, + "frame_start": 751.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 893.0, + "frame_start": 830.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 951.0, + "frame_start": 894.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1071.0, + "frame_start": 952.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1135.0, + "frame_start": 1072.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1222.0, + "frame_start": 1136.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1306.0, + "frame_start": 1230.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1336.0, + "frame_start": 1307.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1395.0, + "frame_start": 1338.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1519.0, + "frame_start": 1396.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1635.0, + "frame_start": 1520.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1693.0, + "frame_start": 1638.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1727.0, + "frame_start": 1694.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1830.0, + "frame_start": 1807.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-final-boss-intro": { + "lines": [ + { + "frame_end": 143.0, + "frame_start": 90.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 221.0, + "frame_start": 196.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 329.0, + "frame_start": 262.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 766.0, + "frame_start": 723.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 799.0, + "frame_start": 770.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 867.0, + "frame_start": 800.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 960.0, + "frame_start": 879.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1014.0, + "frame_start": 961.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1054.0, + "frame_start": 1028.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-hover-intro": { + "lines": [ + { + "frame_end": 114.0, + "frame_start": 56.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 244.0, + "frame_start": 115.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 374.0, + "frame_start": 245.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 433.0, + "frame_start": 375.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 514.0, + "frame_start": 434.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 626.0, + "frame_start": 515.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 729.0, + "frame_start": 629.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 826.0, + "frame_start": 730.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 884.0, + "frame_start": 827.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 953.0, + "frame_start": 887.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1042.0, + "frame_start": 958.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1102.0, + "frame_start": 1043.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1251.0, + "frame_start": 1108.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-hover-res": { + "lines": [ + { + "frame_end": 295.0, + "frame_start": 262.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 325.0, + "frame_start": 296.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 399.0, + "frame_start": 326.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 464.0, + "frame_start": 401.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 574.0, + "frame_start": 465.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 618.0, + "frame_start": 575.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 656.0, + "frame_start": 620.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 744.0, + "frame_start": 658.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 786.0, + "frame_start": 745.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 867.0, + "frame_start": 799.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 916.0, + "frame_start": 868.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 966.0, + "frame_start": 917.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1031.0, + "frame_start": 973.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1086.0, + "frame_start": 1032.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1136.0, + "frame_start": 1087.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-jump-mission-intro": { + "lines": [ + { + "frame_end": 243.0, + "frame_start": 89.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 308.0, + "frame_start": 260.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 383.0, + "frame_start": 318.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 474.0, + "frame_start": 384.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 586.0, + "frame_start": 475.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 686.0, + "frame_start": 587.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 793.0, + "frame_start": 687.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 830.0, + "frame_start": 808.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 901.0, + "frame_start": 837.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1023.0, + "frame_start": 902.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1125.0, + "frame_start": 1024.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1160.0, + "frame_start": 1126.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1251.0, + "frame_start": 1161.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1315.0, + "frame_start": 1252.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1421.0, + "frame_start": 1316.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1457.0, + "frame_start": 1430.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1622.0, + "frame_start": 1465.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1680.0, + "frame_start": 1623.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1772.0, + "frame_start": 1681.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1906.0, + "frame_start": 1773.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1994.0, + "frame_start": 1907.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-oasis-defense-res-b": { + "lines": [ + { + "frame_end": 75.0, + "frame_start": 30.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 214.0, + "frame_start": 95.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 332.0, + "frame_start": 223.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 362.0, + "frame_start": 336.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 465.0, + "frame_start": 363.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 598.0, + "frame_start": 477.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 672.0, + "frame_start": 623.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 797.0, + "frame_start": 743.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "nest-hunt-res": { + "lines": [ + { + "frame_end": 142.0, + "frame_start": 31.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 274.0, + "frame_start": 143.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 347.0, + "frame_start": 285.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 387.0, + "frame_start": 354.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 467.0, + "frame_start": 396.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 551.0, + "frame_start": 479.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 590.0, + "frame_start": 552.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 628.0, + "frame_start": 591.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 703.0, + "frame_start": 629.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 765.0, + "frame_start": 704.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 857.0, + "frame_start": 766.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 912.0, + "frame_start": 862.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 977.0, + "frame_start": 917.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1042.0, + "frame_start": 978.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1148.0, + "frame_start": 1043.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1181.0, + "frame_start": 1149.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1296.0, + "frame_start": 1194.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1412.0, + "frame_start": 1345.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1454.0, + "frame_start": 1424.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1526.0, + "frame_start": 1459.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1568.0, + "frame_start": 1527.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-rescue-intro": { + "lines": [ + { + "frame_end": 83.0, + "frame_start": 17.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 194.0, + "frame_start": 84.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 288.0, + "frame_start": 207.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 337.0, + "frame_start": 289.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 404.0, + "frame_start": 338.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 478.0, + "frame_start": 405.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "factory-sky-battle-intro": { + "lines": [ + { + "frame_end": 81.0, + "frame_start": 30.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 146.0, + "frame_start": 82.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 229.0, + "frame_start": 147.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 329.0, + "frame_start": 230.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 405.0, + "frame_start": 330.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 530.0, + "frame_start": 410.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 588.0, + "frame_start": 538.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 650.0, + "frame_start": 589.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 708.0, + "frame_start": 651.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 776.0, + "frame_start": 709.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 878.0, + "frame_start": 778.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 942.0, + "frame_start": 881.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "city-gun-course-intro": { + "lines": [ + { + "frame_end": 107.0, + "frame_start": 73.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 136.0, + "frame_start": 109.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 272.0, + "frame_start": 137.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 323.0, + "frame_start": 273.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 379.0, + "frame_start": 326.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 408.0, + "frame_start": 381.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 489.0, + "frame_start": 409.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 518.0, + "frame_start": 490.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 586.0, + "frame_start": 521.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 694.0, + "frame_start": 587.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 830.0, + "frame_start": 695.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 977.0, + "frame_start": 831.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1036.0, + "frame_start": 997.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1096.0, + "frame_start": 1057.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1269.0, + "frame_start": 1097.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "forest-turn-on-machine-res": { + "lines": [ + { + "frame_end": 297.0, + "frame_start": 187.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 434.0, + "frame_start": 366.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 521.0, + "frame_start": 436.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 612.0, + "frame_start": 527.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 653.0, + "frame_start": 613.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 681.0, + "frame_start": 663.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 719.0, + "frame_start": 702.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "desert-course-race-intro": { + "lines": [ + { + "frame_end": 83.0, + "frame_start": 12.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 157.0, + "frame_start": 84.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 243.0, + "frame_start": 158.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 338.0, + "frame_start": 244.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 394.0, + "frame_start": 339.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 432.0, + "frame_start": 406.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 471.0, + "frame_start": 438.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 615.0, + "frame_start": 472.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 674.0, + "frame_start": 616.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 718.0, + "frame_start": 680.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 816.0, + "frame_start": 724.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 867.0, + "frame_start": 817.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 922.0, + "frame_start": 868.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 971.0, + "frame_start": 923.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1015.0, + "frame_start": 978.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1071.0, + "frame_start": 1025.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1155.0, + "frame_start": 1078.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1281.0, + "frame_start": 1160.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1320.0, + "frame_start": 1282.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1359.0, + "frame_start": 1327.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1457.0, + "frame_start": 1366.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1547.0, + "frame_start": 1458.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1599.0, + "frame_start": 1548.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1659.0, + "frame_start": 1604.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1674.0, + "frame_start": 1660.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1748.0, + "frame_start": 1707.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 1818.0, + "frame_start": 1749.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + }, + "intro-lost": { + "lines": [ + { + "frame_end": 207.0, + "frame_start": 107.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 271.0, + "frame_start": 208.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 357.0, + "frame_start": 272.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 478.0, + "frame_start": 358.0, + "merge": true, + "offscreen": false, + "speaker": "none" + }, + { + "frame_end": 611.0, + "frame_start": 479.0, + "merge": true, + "offscreen": false, + "speaker": "none" + } + ] + } + }, + "other": { + "dax128": { + "lines": [ + { + "frame_start": 0, + "frame_end": 41, + "merge": false, + "offscreen": true, + "speaker": "daxter" + } + ] + } + } } diff --git a/game/assets/jak3/subtitle/subtitle_meta_nl-NL.json b/game/assets/jak3/subtitle/subtitle_meta_nl-NL.json new file mode 100644 index 0000000000..495996ba8e --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_meta_nl-NL.json @@ -0,0 +1,4 @@ +{ + "cutscenes": {}, + "other": {} +} diff --git a/game/assets/jak3/subtitle/subtitle_meta_pt-PT.json b/game/assets/jak3/subtitle/subtitle_meta_pt-PT.json new file mode 100644 index 0000000000..495996ba8e --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_meta_pt-PT.json @@ -0,0 +1,4 @@ +{ + "cutscenes": {}, + "other": {} +} diff --git a/game/assets/jak3/subtitle/subtitle_meta_ru-RU.json b/game/assets/jak3/subtitle/subtitle_meta_ru-RU.json new file mode 100644 index 0000000000..495996ba8e --- /dev/null +++ b/game/assets/jak3/subtitle/subtitle_meta_ru-RU.json @@ -0,0 +1,4 @@ +{ + "cutscenes": {}, + "other": {} +} diff --git a/game/assets/sdl_controller_db.txt b/game/assets/sdl_controller_db.txt index b7c402f42e..da77cd0431 100644 --- a/game/assets/sdl_controller_db.txt +++ b/game/assets/sdl_controller_db.txt @@ -20,6 +20,7 @@ 03000000801000000900000000000000,8BitDo F30 Arcade Stick,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00001038000000000000,8BitDo F30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, +05000000c82d00006a28000000000000,8BitDo GameCube,a:b0,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b9,paddle2:b8,rightshoulder:b10,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b1,y:b4,platform:Windows, 03000000c82d00001251000000000000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00001151000000000000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000150000000000000,8BitDo M30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b11,x:b4,y:b3,platform:Windows, @@ -73,6 +74,8 @@ 03000000c82d00000260000000000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000261000000000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00001230000000000000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000c82d00001b30000000000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000c82d00001d30000000000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00001530000000000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00001630000000000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00001730000000000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, @@ -116,7 +119,7 @@ 03000000050b00000679000000000000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000503200000110000000000000,Atari VCS Classic Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,start:b3,platform:Windows, 03000000503200000210000000000000,Atari VCS Modern Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows, -03000000380800001889000000000000,AtGames Legends Gamer Pro,a:b1,b:b2,x:b0,y:b3,start:b9,leftshoulder:b13,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:b14,righttrigger:b7,platform:Windows, +03000000380800001889000000000000,AtGames Legends Gamer Pro,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b14,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000008a3500000102000000000000,Backbone One,a:b4,b:b5,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b10,leftstick:b17,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b18,righttrigger:b13,rightx:a3,righty:a4,start:b15,x:b7,y:b8,platform:Windows, 030000008a3500000201000000000000,Backbone One,a:b4,b:b5,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b10,leftstick:b17,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b18,righttrigger:b13,rightx:a3,righty:a4,start:b15,x:b7,y:b8,platform:Windows, 030000008a3500000302000000000000,Backbone One,a:b4,b:b5,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b10,leftstick:b17,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b18,righttrigger:b13,rightx:a3,righty:a4,start:b15,x:b7,y:b8,platform:Windows, @@ -320,11 +323,13 @@ 030000000d0f0000c100000000000000,Horipad Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000f600000000000000,Horipad Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000000d0f00006700000000000000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, +030000000d0f00009601000000000000,Horipad Steam,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b2,paddle1:b15,paddle2:b5,paddle3:b19,paddle4:b18,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 030000000d0f0000dc00000000000000,Horipad Switch,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000242e00000b20000000000000,Hyperkin Admiral N64 Controller,+rightx:b11,+righty:b13,-rightx:b8,-righty:b12,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,platform:Windows, 03000000242e0000ff0b000000000000,Hyperkin N64 Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,platform:Windows, 03000000790000004e95000000000000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows, 03000000242e00006a48000000000000,Hyperkin RetroN Sq,a:b3,b:b7,back:b5,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b0,rightshoulder:b1,start:b4,x:b2,y:b6,platform:Windows, +03000000242f00000a20000000000000,Hyperkin Scout,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows, 03000000242e00006a38000000000000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b3,start:b5,platform:Windows, 03000000d81d00000e00000000000000,iBuffalo AC02 Arcade Joystick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows, 03000000d81d00000f00000000000000,iBuffalo BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, @@ -407,6 +412,7 @@ 03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, 0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000242e0000f500000000000000,Mayflash N64 Adapter,a:b2,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows, 03000000242f0000f400000000000000,Mayflash N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a5,start:b9,platform:Windows, 03000000790000007918000000000000,Mayflash N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,righttrigger:b7,rightx:a3,righty:a2,start:b8,platform:Windows, 030000008f0e00001030000000000000,Mayflash Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:b7,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows, @@ -478,6 +484,7 @@ 03000000790000002201000000000000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 030000006f0e00008501000000000000,PDP Fightpad Pro GameCube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000006f0e00000901000000000000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, +030000006f0e00008901000000000000,PDP Realmz Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000008f0e00004100000000000000,PlaySega,a:b1,b:b0,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b4,y:b3,platform:Windows, 03000000666600006706000000000000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows, 03000000e30500009605000000000000,PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, @@ -491,6 +498,8 @@ 03000000d620000012a7000000000000,PowerA Fusion Nintendo Switch Fight Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000dd62000016a7000000000000,PowerA Fusion Pro Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000d620000013a7000000000000,PowerA Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +03000000d62000002640000000000000,PowerA OPS Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000d62000003340000000000000,PowerA OPS Pro Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 0300000062060000d570000000000000,PowerA PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000d620000014a7000000000000,PowerA Spectra Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, @@ -742,6 +751,7 @@ 03000000bd12000012d0000000000000,USB Controller,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows, 03000000ff1100004133000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 03000000632500002305000000000000,USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, +03000000882800000305000000000000,V5 Game Pad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,x:b2,y:b3,platform:Windows, 03000000790000001a18000000000000,Venom,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00000302000000000000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows, @@ -773,7 +783,6 @@ 03000000120c00000a88000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a2,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 03000000120c00001088000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2~,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5~,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000002a0600002000000000000000,Xbox Controller,a:b0,b:b1,back:b13,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b5,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b15,righttrigger:b7,rightx:a2,righty:a5,start:b12,x:b2,y:b3,platform:Windows, -03000000300f00008888000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:b13,dpleft:b10,dpright:b11,dpup:b12,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 03000000380700001645000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 03000000380700002645000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000380700003645000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, @@ -782,7 +791,6 @@ 030000005e0400008502000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e0400008702000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b7,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 030000005e0400008902000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b10,leftstick:b8,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b9,righttrigger:b4,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, -030000000d0f00006300000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e0400000c0b000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000d102000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000dd02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, @@ -816,6 +824,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Mac OS X, 03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, +03000000c82d00006a28000000010000,8BitDo GameCube,a:b0,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b9,paddle2:b8,rightshoulder:b10,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b1,y:b4,platform:Mac OS X, 03000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00001251000000020000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, @@ -857,6 +866,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00000260000001000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00000261000000010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X, 03000000c82d00001230000000010000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +03000000c82d00001b30000001000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +03000000c82d00001d30000001000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00001530000001000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00001630000001000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00001730000001000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, @@ -882,7 +893,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000008a3500000201000000010000,Backbone One,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 030000008a3500000202000000010000,Backbone One,a:b0,b:b1,back:b16,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b17,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b15,x:b2,y:b3,platform:Mac OS X, 030000008a3500000402000000010000,Backbone One,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, -030000008a3500000302000000010000,Backbone One PlayStationÆ Edition,a:b0,b:b1,back:b16,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b17,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b15,x:b2,y:b3,platform:Mac OS X, +030000008a3500000302000000010000,Backbone One PlayStation Edition,a:b0,b:b1,back:b16,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b17,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b15,x:b2,y:b3,platform:Mac OS X, 03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X, 03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X, @@ -1083,7 +1094,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e040000d102000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000dd02000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000e002000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X, -030000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b10,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Mac OS X, +030000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X, 030000005e040000e302000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, @@ -1095,6 +1106,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e040000130b000015050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 030000005e040000130b000007050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 030000005e040000130b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +030000005e040000130b000022050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 030000005e040000220b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000120c0000100e000000010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X, @@ -1102,10 +1114,12 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, # Linux 03000000c82d00000031000011010000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000631000000010000,8BitDo Adapter 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux, 03000000021000000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +05000000c82d00006a28000000010000,8BitDo GameCube,a:b0,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b9,paddle2:b8,rightshoulder:b10,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b1,y:b4,platform:Linux, 03000000c82d00001251000011010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00001151000011010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, @@ -1119,7 +1133,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00000451000000010000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux, 03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, +03000000c82d00006928000011010000,8BitDo N64,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Linux, 05000000c82d00006928000000010000,8BitDo N64,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Linux, +03000000c82d00006928000011010000,8BitDo N64,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Linux, 05000000c82d00002590000001000000,8BitDo NEOGEO,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000008000000210000011010000,8BitDo NES30,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux, @@ -1140,6 +1156,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00000331000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000431000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00002867000000010000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b3,y:b4,platform:Linux, +03000000c82d00000060000011010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 030000003512000012ab000010010000,8BitDo SFC30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux, @@ -1158,6 +1175,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 05000000c82d00000261000000010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000202800000900000000010000,8BitDo SNES30,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00001230000000010000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000c82d00000a31000014010000,8BitDo Ultimate 2C,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00001d30000011010000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +05000000c82d00001b30000001000000,8BitDo Ultimate 2C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b5,paddle2:b2,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00001530000011010000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00001630000011010000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00001730000011010000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, @@ -1224,6 +1244,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux, 03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux, 03000000a306000022f6000011010000,Cyborg V3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, +030000005e0400008e02000002010000,Data Frog S80,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, 03000000791d00000103000010010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, @@ -1405,10 +1426,13 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 05000000c62400001a89000000010000,MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000250900006688000000010000,MP8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, 030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000f70600000100000000010000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Linux, 030000006f0e00001311000011010000,N64 Controller,+rightx:b10,+righty:b3,-rightx:b0,-righty:b11,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,platform:Linux, 030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006b140000010c000010010000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 03000000853200000706000012010000,Nacon GC-100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +0300000085320000170d000011010000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +0300000085320000190d000011010000,Nacon Revolution 5 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, 030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000004f1f00000800000011010000,NeoGeo PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 0300000092120000474e000000010000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Linux, @@ -1486,6 +1510,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000d62000000f20000001010000,PowerA Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d62000000b20000001010000,PowerA Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000250900000017000010010000,PS/SS/N64 Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b5,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2~,righty:a3,start:b8,platform:Linux, 03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, @@ -1554,6 +1579,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, 0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000321500000b10000011010000,Razer Wolverine PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, +030000000d0f0000c100000010010000,Retro Bit Legacy16,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b12,leftshoulder:b4,lefttrigger:b6,misc1:b13,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, +030000000d0f0000c100000072056800,Retro Bit Legacy16,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b5,leftshoulder:b9,lefttrigger:+a4,misc1:b11,rightshoulder:b10,righttrigger:+a5,start:b6,x:b3,y:b2,platform:Linux, 03000000790000001100000010010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Linux, 0300000003040000c197000011010000,Retrode Adapter,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux, 190000004b4800000111000000010000,RetroGame Joypad,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, @@ -1594,6 +1621,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000bc2000000055000010010000,Shanwan Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000f025000021c1000010010000,Shanwan Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000341a00000908000010010000,SL6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, +030000004b2900000430000011000000,Snakebyte Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 050000004c050000cc09000001000000,Sony DualShock 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, 03000000ff000000cb01000010010000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, 03000000250900000500000000010000,Sony PS2 pad with SmartJoy Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, @@ -1676,6 +1704,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e040000a102000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000a102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000a102000030060000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000006f0e00001503000000020000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000000010000,Xbox 360 EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000a102000014010000,Xbox 360 Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400000202000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, @@ -1695,6 +1724,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e040000ea02000011050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 060000005e040000ea0200000b050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 060000005e040000ea0200000d050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +060000005e040000ea02000016050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000120b000007050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, @@ -1738,6 +1768,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 33313433353539306634656436353432,8BitDo Dogbone,a:b1,b:b0,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 38426974446f20446f67626f6e65204d,8BitDo Dogbone,a:b1,b:b0,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b6,platform:Android, 34343439373236623466343934376233,8BitDo FC30 Pro,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b28,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b29,righttrigger:b7,start:b5,x:b30,y:b2,platform:Android, +38426974446f204e4743204d6f646b69,8BitDo GameCube,a:b0,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,paddle1:b18,paddle2:b17,rightshoulder:b15,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b1,y:b3,platform:Android, 38426974446f2038426974446f204c69,8BitDo Lite,a:b1,b:b0,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 30643332373663313263316637356631,8BitDo Lite 2,a:b1,b:b0,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, 38426974446f204c6974652032000000,8BitDo Lite 2,a:b1,b:b0,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android, @@ -1905,7 +1936,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 32666633663735353234363064386132,PS2,a:b23,b:b22,back:b29,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b27,lefttrigger:b25,leftx:a0,lefty:a1,rightshoulder:b28,righttrigger:b26,rightx:a3,righty:a2,start:b30,x:b24,y:b21,platform:Android, 050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 536f6e7920504c415953544154494f4e,PS3 Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, -61363034663839376638653463633865,PS3 Controller,a:b0,b:b1,back:b15,dpdown:a14,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, +61363034663839376638653463633865,PS3 Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 66366539656564653432353139356536,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 66383132326164626636313737373037,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 050000004c050000c405000000783f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, @@ -1928,7 +1959,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 65366465656364636137653363376531,PS4 Controller,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b0,y:b2,platform:Android, 66613532303965383534396638613230,PS4 Controller,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android, 050000004c050000e60c0000fffe3f00,PS5 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android, -050000004c050000e60c0000fffe3f80,PS5 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a3,rightx:a4,righty:a5,start:b16,x:b0,y:b2,platform:Android, +050000004c050000e60c0000fffe3f80,PS5 Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a3,rightx:a4,righty:a5,start:b16,x:b2,y:b17,platform:Android, 050000004c050000e60c0000ffff3f00,PS5 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 32346465346533616263386539323932,PS5 Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, 32633532643734376632656664383733,PS5 Controller,a:b1,b:b19,back:b17,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android, diff --git a/game/graphics/gfx_test.cpp b/game/graphics/gfx_test.cpp index a07809ae1e..de5ec0dd5f 100644 --- a/game/graphics/gfx_test.cpp +++ b/game/graphics/gfx_test.cpp @@ -2,13 +2,15 @@ #include "game/system/hid/sdl_util.h" +#include "third-party/glad/include/glad/glad.h" + namespace tests { void to_json(json& j, const GPUTestOutput& obj) { - j = json{ - {"success", obj.success}, - {"error", obj.error}, - {"errorCause", obj.errorCause}, - }; + json_serialize(success); + json_serialize(error); + json_serialize(errorCause); + json_serialize_optional(gpuRendererString); + json_serialize_optional(gpuVendorString); } GPUTestOutput run_gpu_test(const std::string& test_type) { @@ -40,7 +42,20 @@ GPUTestOutput run_gpu_test(const std::string& test_type) { output = {false, "Required OpenGL Version is not supported", sdl_util::log_and_return_error("SDL initialization failed")}; } else { - output = {true, "", ""}; + gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress); + if (!gladLoadGL()) { + output = {false, "Unable to init GLAD", ""}; + } else { + output = {true, "", ""}; + const auto rendererString = glGetString(GL_RENDERER); + if (rendererString) { + output.gpuRendererString = (const char*)rendererString; + } + const auto vendorString = glGetString(GL_VENDOR); + if (vendorString) { + output.gpuVendorString = (const char*)vendorString; + } + } SDL_GL_DeleteContext(glContext); } SDL_DestroyWindow(window); diff --git a/game/graphics/gfx_test.h b/game/graphics/gfx_test.h index 6fbc6bc0d0..f2693105da 100644 --- a/game/graphics/gfx_test.h +++ b/game/graphics/gfx_test.h @@ -9,6 +9,8 @@ struct GPUTestOutput { bool success; std::string error; std::string errorCause; + std::optional gpuRendererString; + std::optional gpuVendorString; }; void to_json(json& j, const GPUTestOutput& obj); diff --git a/game/graphics/opengl_renderer/OpenGLRenderer.cpp b/game/graphics/opengl_renderer/OpenGLRenderer.cpp index 7d88d9c2ce..756e62275b 100644 --- a/game/graphics/opengl_renderer/OpenGLRenderer.cpp +++ b/game/graphics/opengl_renderer/OpenGLRenderer.cpp @@ -168,7 +168,8 @@ void OpenGLRenderer::init_bucket_renderers_jak3() { std::vector{tfrag3::TFragmentTreeKind::NORMAL}, false, i, anim_slot_array()); Tie3* tie = init_bucket_renderer( fmt::format("tie-l{}-tfrag", i), BucketCategory::TIE, - GET_BUCKET_ID_FOR_LIST(BucketId::TIE_L0_TFRAG, BucketId::TIE_L1_TFRAG, i), i); + GET_BUCKET_ID_FOR_LIST(BucketId::TIE_L0_TFRAG, BucketId::TIE_L1_TFRAG, i), i, + anim_slot_array()); init_bucket_renderer( fmt::format("etie-l{}-tfrag", i), BucketCategory::TIE, GET_BUCKET_ID_FOR_LIST(BucketId::ETIE_L0_TFRAG, BucketId::ETIE_L1_TFRAG, i), tie, @@ -366,16 +367,14 @@ void OpenGLRenderer::init_bucket_renderers_jak3() { BucketId::DEBUG_NO_ZBUF1, m_texture_animator, true); // 578 init_bucket_renderer("tex-hud-hud-alpha", BucketCategory::TEX, - BucketId::TEX_HUD_HUD_ALPHA, m_texture_animator); - - init_bucket_renderer("tex-hud-hud-alpha", BucketCategory::TEX, - BucketId::TEX_HUD_HUD_ALPHA, m_texture_animator); + BucketId::TEX_HUD_HUD_ALPHA, m_texture_animator, + true); init_bucket_renderer("hud-draw-hud-alpha", BucketCategory::OTHER, BucketId::HUD_DRAW_HUD_ALPHA, 0x8000); init_bucket_renderer("tex-hud-pris2", BucketCategory::TEX, BucketId::TEX_HUD_PRIS2, m_texture_animator); - init_bucket_renderer("hud-draw-pris2", BucketCategory::TEX, - BucketId::HUD_DRAW_PRIS2, m_texture_animator); + init_bucket_renderer("hud-draw-pris2", BucketCategory::OTHER, + BucketId::HUD_DRAW_PRIS2, 0x8000); init_bucket_renderer("progress", BucketCategory::OTHER, BucketId::BUCKET582, 0x8000); @@ -433,7 +432,8 @@ void OpenGLRenderer::init_bucket_renderers_jak2() { std::vector{tfrag3::TFragmentTreeKind::NORMAL}, false, i, anim_slot_array()); Tie3* tie = init_bucket_renderer( fmt::format("tie-l{}-tfrag", i), BucketCategory::TIE, - GET_BUCKET_ID_FOR_LIST(BucketId::TIE_L0_TFRAG, BucketId::TIE_L1_TFRAG, i), i); + GET_BUCKET_ID_FOR_LIST(BucketId::TIE_L0_TFRAG, BucketId::TIE_L1_TFRAG, i), i, + anim_slot_array()); init_bucket_renderer( fmt::format("etie-l{}-tfrag", i), BucketCategory::TIE, GET_BUCKET_ID_FOR_LIST(BucketId::ETIE_L0_TFRAG, BucketId::ETIE_L1_TFRAG, i), tie, diff --git a/game/graphics/opengl_renderer/Shader.cpp b/game/graphics/opengl_renderer/Shader.cpp index cfdaed6ed2..9850d6b624 100644 --- a/game/graphics/opengl_renderer/Shader.cpp +++ b/game/graphics/opengl_renderer/Shader.cpp @@ -130,6 +130,7 @@ ShaderLibrary::ShaderLibrary(GameVersion version) { at(ShaderId::GLOW_PROBE_ON_GRID) = {"glow_probe_on_grid", version}; at(ShaderId::HFRAG) = {"hfrag", version}; at(ShaderId::HFRAG_MONTAGE) = {"hfrag_montage", version}; + at(ShaderId::PLAIN_TEXTURE) = {"plain_texture", version}; for (auto& shader : m_shaders) { ASSERT_MSG(shader.okay(), "error compiling shader"); diff --git a/game/graphics/opengl_renderer/Shader.h b/game/graphics/opengl_renderer/Shader.h index f7a4f8f551..02769f9528 100644 --- a/game/graphics/opengl_renderer/Shader.h +++ b/game/graphics/opengl_renderer/Shader.h @@ -63,6 +63,7 @@ enum class ShaderId { GLOW_PROBE_ON_GRID = 36, HFRAG = 37, HFRAG_MONTAGE = 38, + PLAIN_TEXTURE = 39, MAX_SHADERS }; diff --git a/game/graphics/opengl_renderer/SkyRenderer.cpp b/game/graphics/opengl_renderer/SkyRenderer.cpp index 0aed0333bb..556410cd44 100644 --- a/game/graphics/opengl_renderer/SkyRenderer.cpp +++ b/game/graphics/opengl_renderer/SkyRenderer.cpp @@ -122,6 +122,7 @@ void SkyBlendHandler::draw_debug_window() { if (ImGui::TreeNode("tfrag")) { m_tfrag_renderer.draw_debug_window(); + ImGui::Checkbox("enable", &m_tfrag_renderer.enabled()); ImGui::TreePop(); } } diff --git a/game/graphics/opengl_renderer/TextureAnimator.cpp b/game/graphics/opengl_renderer/TextureAnimator.cpp index 9025a6daae..1146ae9b38 100644 --- a/game/graphics/opengl_renderer/TextureAnimator.cpp +++ b/game/graphics/opengl_renderer/TextureAnimator.cpp @@ -55,6 +55,16 @@ // then it's actually treated as a palette texture, but we don't really do this. // This breaks the fade-out/thresholding, and likely the colors. But it still looks vaguely like // clouds. +void debug_save_opengl_texture(const std::string& out, GLuint texture) { + glBindTexture(GL_TEXTURE_2D, texture); + int w, h; + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); + lg::print("saving texture with size {} x {}\n", w, h); + std::vector data(w * h * 4); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, data.data()); + file_util::write_rgba_png(out, data.data(), w, h); +} /*! * A simple list of preallocated textures by size. If a texture needs to be resized, it's faster @@ -262,6 +272,71 @@ void opengl_upload_texture(GLint dest, const void* data, int w, int h) { glBindTexture(GL_TEXTURE_2D, 0); } +/*! + * Upload a texture and generate mipmaps. Assumes the usual RGBA format. + * The size of the destination and source texture don't need to match. + */ +void opengl_upload_resize_texture(FramebufferTexturePair& fbt, + const void* data, + const math::Vector2& data_size, + ShaderLibrary& shaders) { + { + FramebufferTexturePairContext ctx(fbt); + GLuint temp_texture = 0; + GLuint vao = 0; + GLuint vertex_buffer = 0; + glGenTextures(1, &temp_texture); + glBindTexture(GL_TEXTURE_2D, temp_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data_size.x(), data_size.y(), 0, GL_RGBA, + GL_UNSIGNED_INT_8_8_8_8_REV, data); + + glGenVertexArrays(1, &vao); + glGenBuffers(1, &vertex_buffer); + glBindVertexArray(vao); + + struct Vertex { + float x, y; + }; + + std::array vertices = { + Vertex{-1, -1}, + Vertex{-1, 1}, + Vertex{1, -1}, + Vertex{1, 1}, + }; + + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * 4, vertices.data(), GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, // location 0 in the shader + 2, // 2 floats per vert + GL_FLOAT, // floats + GL_TRUE, // normalized, ignored, + sizeof(Vertex), // + nullptr // + ); + + auto& shader = shaders[ShaderId::PLAIN_TEXTURE]; + shader.activate(); + glUniform1i(glGetUniformLocation(shader.id(), "tex_T0"), 0); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, temp_texture); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vertex_buffer); + glDeleteTextures(1, &temp_texture); + } + glBindTexture(GL_TEXTURE_2D, fbt.texture()); + glGenerateMipmap(GL_TEXTURE_2D); +} + /*! * Utility class to grab CLUTs from the source textures, blend them, and produce a destination RGBA * texture using the index data in dest. @@ -417,7 +492,8 @@ TextureAnimator::TextureAnimator(ShaderLibrary& shaders, GL_UNSIGNED_INT_8_8_8_8_REV), m_slime_final_scroll_texture(kFinalSlimeTextureSize, kFinalSlimeTextureSize, - GL_UNSIGNED_INT_8_8_8_8_REV) { + GL_UNSIGNED_INT_8_8_8_8_REV), + m_shaders(&shaders) { glGenVertexArrays(1, &m_vao); glGenBuffers(1, &m_vertex_buffer); glBindVertexArray(m_vao); @@ -522,8 +598,28 @@ TextureAnimator::TextureAnimator(ShaderLibrary& shaders, default: ASSERT_NOT_REACHED(); } - setup_sky(); + + // Patch up references to animated textures + std::map name_to_slot; + for (const auto& anim_array : m_fixed_anim_arrays) { + for (const auto& anim : anim_array.anims) { + name_to_slot[anim.def.tex_name] = anim.dest_slot; + } + } + + for (auto& anim_array : m_fixed_anim_arrays) { + for (auto& anim : anim_array.anims) { + for (size_t i = 0; i < anim.src_textures.size(); i++) { + const auto& it = name_to_slot.find(anim.def.layers.at(i).tex_name); + if (it != name_to_slot.end()) { + lg::error("Patching ref to {} in {}", it->first, anim.def.tex_name); + anim.src_textures[i].is_anim_slot = true; + anim.src_textures[i].idx = it->second; + } + } + } + } } /*! @@ -544,6 +640,11 @@ int TextureAnimator::create_fixed_anim_array(const std::vector& de if (anim.def.override_size) { anim.fbt.emplace(anim.def.override_size->x(), anim.def.override_size->y(), GL_UNSIGNED_INT_8_8_8_8_REV); + // I think there's kind of a bug here - if the game accesses a resized texture before + // the animation is run once, it can end up using the wrong size. + // For PC, we just resize the texture to the new size at startup, which avoids the texture + // changing sizes at runtime. + opengl_upload_resize_texture(*anim.fbt, dtex->data.data(), {dtex->w, dtex->h}, *m_shaders); } else { anim.fbt.emplace(dtex->w, dtex->h, GL_UNSIGNED_INT_8_8_8_8_REV); opengl_upload_texture(anim.fbt->texture(), dtex->data.data(), dtex->w, dtex->h); @@ -555,7 +656,10 @@ int TextureAnimator::create_fixed_anim_array(const std::vector& de for (const auto& layer : def.layers) { auto* stex = tex_by_name(m_common_level, layer.tex_name); GLint gl_texture = m_opengl_texture_pool.allocate(stex->w, stex->h); - anim.src_textures.push_back(gl_texture); + FixedAnimSource src; + src.idx = gl_texture; + src.is_anim_slot = false; + anim.src_textures.push_back(src); opengl_upload_texture(gl_texture, stex->data.data(), stex->w, stex->h); } @@ -632,10 +736,14 @@ void TextureAnimator::copy_private_to_public() { int TextureAnimator::create_clut_blender_group(const std::vector& textures, const std::string& suffix0, const std::string& suffix1, - const std::optional& dgo) { + const std::optional& dgo, + bool add_to_pool) { int ret = m_clut_blender_groups.size(); m_clut_blender_groups.emplace_back(); add_to_clut_blender_group(ret, textures, suffix0, suffix1, dgo); + if (add_to_pool) { + m_clut_blender_groups.back().move_to_pool = true; + } return ret; } @@ -1136,23 +1244,23 @@ void TextureAnimator::handle_texture_anim_data(DmaFollower& dma, break; case PcTextureAnimCodesJak2::DARKJAK: { auto p = scoped_prof("darkjak"); - run_clut_blender_group(tf, m_darkjak_clut_blender_idx, frame_idx); + run_clut_blender_group(tf, m_darkjak_clut_blender_idx, frame_idx, texture_pool); } break; case PcTextureAnimCodesJak2::PRISON_JAK: { auto p = scoped_prof("prisonjak"); - run_clut_blender_group(tf, m_jakb_prison_clut_blender_idx, frame_idx); + run_clut_blender_group(tf, m_jakb_prison_clut_blender_idx, frame_idx, texture_pool); } break; case PcTextureAnimCodesJak2::ORACLE_JAK: { auto p = scoped_prof("oraclejak"); - run_clut_blender_group(tf, m_jakb_oracle_clut_blender_idx, frame_idx); + run_clut_blender_group(tf, m_jakb_oracle_clut_blender_idx, frame_idx, texture_pool); } break; case PcTextureAnimCodesJak2::NEST_JAK: { auto p = scoped_prof("nestjak"); - run_clut_blender_group(tf, m_jakb_nest_clut_blender_idx, frame_idx); + run_clut_blender_group(tf, m_jakb_nest_clut_blender_idx, frame_idx, texture_pool); } break; case PcTextureAnimCodesJak2::KOR_TRANSFORM: { auto p = scoped_prof("kor"); - run_clut_blender_group(tf, m_kor_transform_clut_blender_idx, frame_idx); + run_clut_blender_group(tf, m_kor_transform_clut_blender_idx, frame_idx, texture_pool); } break; case PcTextureAnimCodesJak2::SKULL_GEM: case PcTextureAnimCodesJak2::BOMB: @@ -1217,11 +1325,12 @@ void TextureAnimator::handle_texture_anim_data(DmaFollower& dma, break; case PcTextureAnimCodesJak3::DARKJAK: { auto p = scoped_prof("darkjak"); - run_clut_blender_group(tf, m_darkjak_clut_blender_idx, frame_idx); + run_clut_blender_group(tf, m_darkjak_clut_blender_idx, frame_idx, texture_pool); } break; case PcTextureAnimCodesJak3::DARKJAK_HIGHRES: { auto p = scoped_prof("darkjak-highres"); - run_clut_blender_group(tf, m_darkjak_highres_clut_blender_idx, frame_idx); + run_clut_blender_group(tf, m_darkjak_highres_clut_blender_idx, frame_idx, + texture_pool); } break; case PcTextureAnimCodesJak3::SKULL_GEM: case PcTextureAnimCodesJak3::DEFAULT_WATER: @@ -1475,26 +1584,48 @@ PcTextureId TextureAnimator::get_id_for_tbp(TexturePool* pool, u64 tbp, u64 othe } } -void debug_save_opengl_texture(const std::string& out, GLuint texture) { - glBindTexture(GL_TEXTURE_2D, texture); - int w, h; - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); - lg::print("saving texture with size {} x {}\n", w, h); - std::vector data(w * h * 4); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, data.data()); - file_util::write_rgba_png(out, data.data(), w, h); -} - -void TextureAnimator::run_clut_blender_group(DmaTransfer& tf, int idx, u64 frame_idx) { +void TextureAnimator::run_clut_blender_group(DmaTransfer& tf, + int idx, + u64 frame_idx, + TexturePool* texture_pool) { + auto& blenders = m_clut_blender_groups.at(idx); + const int tbps_size = sizeof(u32) * 4 * ((blenders.blenders.size() + 3) / 4); float f; - ASSERT(tf.size_bytes == 16); + ASSERT(tf.size_bytes == 16 + tbps_size); memcpy(&f, tf.data, sizeof(float)); float weights[2] = {1.f - f, f}; - auto& blender = m_clut_blender_groups.at(idx); - blender.last_updated_frame = frame_idx; - for (size_t i = 0; i < blender.blenders.size(); i++) { - m_private_output_slots[blender.outputs[i]] = blender.blenders[i].run(weights); + blenders.last_updated_frame = frame_idx; + for (size_t i = 0; i < blenders.blenders.size(); i++) { + m_private_output_slots[blenders.outputs[i]] = blenders.blenders[i].run(weights); + } + + const u32* tbps = (const u32*)(tf.data + 16); + + // give to the pool for renderers that don't know how to access this directly + if (blenders.move_to_pool) { + for (size_t i = 0; i < blenders.blenders.size(); i++) { + auto& blender = blenders.blenders[i]; + const u32 tbp = tbps[i]; + if (tbp == UINT32_MAX) { + continue; + } + ASSERT(tbp < 0x40000); + m_skip_tbps.push_back(tbp); // known to be an output texture. + if (blender.pool_gpu_tex) { + // TODO: handle debug checkbox. + texture_pool->move_existing_to_vram(blender.pool_gpu_tex, tbp); + ASSERT(texture_pool->lookup(tbp).value() == blender.texture()); + } else { + TextureInput in; + in.gpu_texture = blender.texture(); + in.w = blender.w(); + in.h = blender.h(); + in.debug_page_name = "PC-ANIM"; + in.debug_name = std::to_string(tbp); + in.id = get_id_for_tbp(texture_pool, tbp, idx); + blender.pool_gpu_tex = texture_pool->give_texture_and_load_to_vram(in, tbp); + } + } } } @@ -2434,15 +2565,18 @@ void TextureAnimator::set_draw_data_from_interpolated(DrawData* result, math::Vector2f pos_offset(2048.f + (vals.offset.x() * w), 2048.f + (vals.offset.y() * h)); math::Vector2f st_scale = vals.st_scale; math::Vector2f st_offset = vals.st_offset; - math::Vector2f corners[4] = {math::Vector2f{-0.5, -0.5}, math::Vector2f{0.5, -0.5}, - math::Vector2f{-0.5, 0.5}, math::Vector2f{0.5, 0.5}}; + const std::array fixed_corners = { + math::Vector2f{-0.5, -0.5}, math::Vector2f{0.5, -0.5}, math::Vector2f{-0.5, 0.5}, + math::Vector2f{0.5, 0.5}}; + auto pos_corners = fixed_corners; + if (vals.rot) { const float rotation_radians = 2.f * M_PI * vals.rot / 65536.f; const float sine = std::sin(rotation_radians); const float cosine = std::cos(rotation_radians); math::Vector2f vx(sine, cosine); math::Vector2f vy(cosine, -sine); - for (auto& corner : corners) { + for (auto& corner : pos_corners) { corner = vx * corner.x() + vy * corner.y(); } } @@ -2450,7 +2584,7 @@ void TextureAnimator::set_draw_data_from_interpolated(DrawData* result, math::Vector2 poss[4]; for (int i = 0; i < 4; i++) { - poss[i] = ((corners[i].elementwise_multiply(pos_scale) + pos_offset) * 16.f).cast(); + poss[i] = ((pos_corners[i].elementwise_multiply(pos_scale) + pos_offset) * 16.f).cast(); } if (vals.st_rot != 0) { @@ -2460,12 +2594,12 @@ void TextureAnimator::set_draw_data_from_interpolated(DrawData* result, math::Vector2f vx(sine, cosine); math::Vector2f vy(cosine, -sine); for (int i = 0; i < 4; i++) { - math::Vector2f corner = corners[i].elementwise_multiply(st_scale); + math::Vector2f corner = fixed_corners[i].elementwise_multiply(st_scale); sts[i] = st_offset + vx * corner.x() + vy * corner.y(); } } else { for (int i = 0; i < 4; i++) { - sts[i] = corners[i].elementwise_multiply(st_scale) + st_offset; + sts[i] = fixed_corners[i].elementwise_multiply(st_scale) + st_offset; } } @@ -2511,7 +2645,6 @@ void TextureAnimator::run_fixed_animation(FixedAnim& anim, float time) { LayerVals interpolated_values; DrawData draw_data; - // Loop over layers for (size_t layer_idx = 0; layer_idx < anim.def.layers.size(); layer_idx++) { auto& layer_def = anim.def.layers[layer_idx]; @@ -2521,13 +2654,22 @@ void TextureAnimator::run_fixed_animation(FixedAnim& anim, float time) { continue; } + if (layer_def.disable) { + continue; + } + // interpolate interpolate_layer_values( (time - layer_def.start_time) / (layer_def.end_time - layer_def.start_time), &interpolated_values, layer_dyn.start_vals, layer_dyn.end_vals); // shader setup - set_up_opengl_for_fixed(layer_def, anim.src_textures.at(layer_idx)); + const auto& src = anim.src_textures.at(layer_idx); + if (src.is_anim_slot) { + set_up_opengl_for_fixed(layer_def, m_private_output_slots.at(src.idx)); + } else { + set_up_opengl_for_fixed(layer_def, src.idx); + } set_draw_data_from_interpolated(&draw_data, interpolated_values, anim.fbt->width(), anim.fbt->height()); diff --git a/game/graphics/opengl_renderer/TextureAnimator.h b/game/graphics/opengl_renderer/TextureAnimator.h index 114b85a32a..68d418f5af 100644 --- a/game/graphics/opengl_renderer/TextureAnimator.h +++ b/game/graphics/opengl_renderer/TextureAnimator.h @@ -77,6 +77,10 @@ class ClutBlender { GLuint texture() const { return m_texture; } bool at_default() const { return m_current_weights[0] == 1.f && m_current_weights[1] == 0.f; } + int w() const { return m_dest->w; } + int h() const { return m_dest->h; } + GpuTexture* pool_gpu_tex = nullptr; + private: const tfrag3::IndexTexture* m_dest; std::array, 256>*, 2> m_cluts; @@ -145,6 +149,7 @@ struct FixedLayerDef { bool clamp_v = false; bool blend_enable = true; bool channel_masks[4] = {true, true, true, true}; + bool disable = false; GsAlpha::BlendMode blend_modes[4]; // abcd u8 blend_fix = 0; @@ -208,14 +213,17 @@ struct DynamicLayerData { LayerVals start_vals, end_vals; }; +struct FixedAnimSource { + u64 idx = 0; + bool is_anim_slot = false; +}; + struct FixedAnim { FixedAnimDef def; std::vector dynamic_data; - // GLint dest_texture; std::optional fbt; int dest_slot; - std::vector src_textures; - + std::vector src_textures; GpuTexture* pool_gpu_tex = nullptr; }; @@ -392,6 +400,7 @@ class TextureAnimator { std::vector blenders; std::vector outputs; u64 last_updated_frame = 0; + bool move_to_pool = false; }; std::vector m_clut_blender_groups; @@ -404,13 +413,14 @@ class TextureAnimator { int create_clut_blender_group(const std::vector& textures, const std::string& suffix0, const std::string& suffix1, - const std::optional& dgo); + const std::optional& dgo, + bool send_to_pool = false); void add_to_clut_blender_group(int idx, const std::vector& textures, const std::string& suffix0, const std::string& suffix1, const std::optional& dgo); - void run_clut_blender_group(DmaTransfer& tf, int idx, u64 frame_idx); + void run_clut_blender_group(DmaTransfer& tf, int idx, u64 frame_idx, TexturePool* texture_pool); GLint run_clouds(const SkyInput& input, bool hires); void run_slime(const SlimeInput& input); @@ -528,6 +538,7 @@ class TextureAnimator { GpuTexture* m_slime_scroll_pool_gpu_tex = nullptr; int m_slime_output_slot = -1; int m_slime_scroll_output_slot = -1; + ShaderLibrary* m_shaders = nullptr; }; int output_slot_by_idx(GameVersion version, const std::string& name); @@ -535,4 +546,4 @@ int update_opengl_noise_texture(GLuint texture, u8* temp, Vector16ub* random_table, int dim, - int random_index_in); \ No newline at end of file + int random_index_in); diff --git a/game/graphics/opengl_renderer/TextureAnimatorDefs.cpp b/game/graphics/opengl_renderer/TextureAnimatorDefs.cpp index 26f2c91a04..c0890f4e8f 100644 --- a/game/graphics/opengl_renderer/TextureAnimatorDefs.cpp +++ b/game/graphics/opengl_renderer/TextureAnimatorDefs.cpp @@ -21,7 +21,7 @@ void TextureAnimator::setup_texture_anims_jak3() { "jakchires-facert", "jakchires-hair", }, - "-norm", "-dark", "MHCTYCST.DGO"); + "-norm", "-dark", "MHCTYCST.DGO", true); // default-water { @@ -199,14 +199,19 @@ void TextureAnimator::setup_texture_anims_jak3() { foam.tex_name = "splash-foam"; // :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) foam.set_no_z_write_no_z_test(); - foam.channel_masks[3] = false; // no alpha writes. + if (i == 16) { + // this layer is configured, but most of the settings do nothing because it uses + // set-alpha-texture-anim-layer-func + foam.disable = true; + } // :alpha (new 'static 'gs-alpha :b #x2 :d #x1) foam.set_clamp(); foam.set_blend_b2_d1(); } + dest2.set_alpha = true; dest2.set_times({ - {0.f, 25.f}, - {25.f, 150.f}, + {0.f, 25.f}, // 0 + {25.f, 150.f}, // 1 {25.f, 50.f}, {50.f, 150.f}, {0.f, 25.f}, @@ -1786,13 +1791,13 @@ void TextureAnimator::setup_texture_anims_jak2() { // MISSING FINGER m_jakb_oracle_clut_blender_idx = create_clut_blender_group( {"jakb-eyebrow", "jakb-eyelid", "jakb-facelft", "jakb-facert", "jakb-hairtrans"}, "-norm", - "-dark", "ORACLE.DGO"); + "-dark", "ORACLE.DGO", true); // NEST // MISSING FINGER m_jakb_nest_clut_blender_idx = create_clut_blender_group( {"jakb-eyebrow", "jakb-eyelid", "jakb-facelft", "jakb-facert", "jakb-hairtrans"}, "-norm", - "-dark", "NEB.DGO"); + "-dark", "NEB.DGO", true); // KOR (doesn't work??) m_kor_transform_clut_blender_idx = create_clut_blender_group( diff --git a/game/graphics/opengl_renderer/background/Tie3.cpp b/game/graphics/opengl_renderer/background/Tie3.cpp index 3bb689bec7..7ab938bd0e 100644 --- a/game/graphics/opengl_renderer/background/Tie3.cpp +++ b/game/graphics/opengl_renderer/background/Tie3.cpp @@ -6,8 +6,15 @@ #include "third-party/imgui/imgui.h" -Tie3::Tie3(const std::string& name, int my_id, int level_id, tfrag3::TieCategory category) - : BucketRenderer(name, my_id), m_level_id(level_id), m_default_category(category) { +Tie3::Tie3(const std::string& name, + int my_id, + int level_id, + const std::vector* anim_slot_array, + tfrag3::TieCategory category) + : BucketRenderer(name, my_id), + m_level_id(level_id), + m_default_category(category), + m_anim_slot_array(anim_slot_array) { // regardless of how many we use some fixed max // we won't actually interp or upload to gpu the unused ones, but we need a fixed maximum so // indexing works properly. @@ -108,6 +115,7 @@ void Tie3::load_from_fr3_data(const LevelData* loader_data) { // OpenGL index buffer (fixed index buffer for multidraw system) lod_tree[l_tree].index_buffer = loader_data->tie_data[l_geo][l_tree].index_buffer; lod_tree[l_tree].category_draw_indices = tree.category_draw_indices; + lod_tree[l_tree].draw_mode = tree.use_strips ? GL_TRIANGLE_STRIP : GL_TRIANGLES; // set up vertex attributes glBindBuffer(GL_ARRAY_BUFFER, lod_tree[l_tree].vertex_buffer); @@ -572,8 +580,12 @@ void Tie3::draw_matching_draws_for_tree(int idx, } } - if ((int)draw.tree_tex_id != last_texture) { - glBindTexture(GL_TEXTURE_2D, m_textures->at(draw.tree_tex_id)); + if (draw.tree_tex_id != last_texture) { + if (draw.tree_tex_id >= 0) { + glBindTexture(GL_TEXTURE_2D, m_textures->at(draw.tree_tex_id)); + } else { + glBindTexture(GL_TEXTURE_2D, m_anim_slot_array->at(-(draw.tree_tex_id + 1))); + } last_texture = draw.tree_tex_id; } @@ -586,11 +598,11 @@ void Tie3::draw_matching_draws_for_tree(int idx, prof.add_draw_call(); if (render_state->no_multidraw) { - glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT, + glDrawElements(tree.draw_mode, singledraw_indices.second, GL_UNSIGNED_INT, (void*)(singledraw_indices.first * sizeof(u32))); } else { glMultiDrawElements( - GL_TRIANGLE_STRIP, &tree.multidraw_count_buffer[multidraw_indices.first], GL_UNSIGNED_INT, + tree.draw_mode, &tree.multidraw_count_buffer[multidraw_indices.first], GL_UNSIGNED_INT, &tree.multidraw_index_offset_buffer[multidraw_indices.first], multidraw_indices.second); } @@ -606,13 +618,13 @@ void Tie3::draw_matching_draws_for_tree(int idx, double_draw.aref_second); glDepthMask(GL_FALSE); if (render_state->no_multidraw) { - glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT, + glDrawElements(tree.draw_mode, singledraw_indices.second, GL_UNSIGNED_INT, (void*)(singledraw_indices.first * sizeof(u32))); } else { - glMultiDrawElements( - GL_TRIANGLE_STRIP, &tree.multidraw_count_buffer[multidraw_indices.first], - GL_UNSIGNED_INT, &tree.multidraw_index_offset_buffer[multidraw_indices.first], - multidraw_indices.second); + glMultiDrawElements(tree.draw_mode, &tree.multidraw_count_buffer[multidraw_indices.first], + GL_UNSIGNED_INT, + &tree.multidraw_index_offset_buffer[multidraw_indices.first], + multidraw_indices.second); } break; default: @@ -664,8 +676,13 @@ void Tie3::envmap_second_pass_draw(const Tree& tree, } } - if ((int)draw.tree_tex_id != last_texture) { - glBindTexture(GL_TEXTURE_2D, m_textures->at(draw.tree_tex_id)); + if (draw.tree_tex_id != last_texture) { + if (draw.tree_tex_id >= 0) { + glBindTexture(GL_TEXTURE_2D, m_textures->at(draw.tree_tex_id)); + } else { + glBindTexture(GL_TEXTURE_2D, m_anim_slot_array->at(-(draw.tree_tex_id + 1))); + } + last_texture = draw.tree_tex_id; } @@ -674,11 +691,11 @@ void Tie3::envmap_second_pass_draw(const Tree& tree, prof.add_draw_call(); if (render_state->no_multidraw) { - glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT, + glDrawElements(tree.draw_mode, singledraw_indices.second, GL_UNSIGNED_INT, (void*)(singledraw_indices.first * sizeof(u32))); } else { glMultiDrawElements( - GL_TRIANGLE_STRIP, &tree.multidraw_count_buffer[multidraw_indices.first], GL_UNSIGNED_INT, + tree.draw_mode, &tree.multidraw_count_buffer[multidraw_indices.first], GL_UNSIGNED_INT, &tree.multidraw_index_offset_buffer[multidraw_indices.first], multidraw_indices.second); } @@ -921,8 +938,12 @@ void Tie3::render_tree_wind(int idx, for (size_t draw_idx = 0; draw_idx < tree.wind_draws->size(); draw_idx++) { const auto& draw = tree.wind_draws->operator[](draw_idx); - if ((int)draw.tree_tex_id != last_texture) { - glBindTexture(GL_TEXTURE_2D, m_textures->at(draw.tree_tex_id)); + if (draw.tree_tex_id != last_texture) { + if (draw.tree_tex_id >= 0) { + glBindTexture(GL_TEXTURE_2D, m_textures->at(draw.tree_tex_id)); + } else { + glBindTexture(GL_TEXTURE_2D, m_anim_slot_array->at(-(draw.tree_tex_id + 1))); + } last_texture = draw.tree_tex_id; } auto double_draw = setup_tfrag_shader(render_state, draw.mode, ShaderId::TFRAG3); @@ -941,7 +962,7 @@ void Tie3::render_tree_wind(int idx, prof.add_draw_call(); prof.add_tri(grp.num); - glDrawElements(GL_TRIANGLE_STRIP, grp.num, GL_UNSIGNED_INT, + glDrawElements(tree.draw_mode, grp.num, GL_UNSIGNED_INT, (void*)((off + tree.wind_vertex_index_offsets.at(draw_idx)) * sizeof(u32))); off += grp.num; @@ -958,7 +979,7 @@ void Tie3::render_tree_wind(int idx, glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3].id(), "alpha_max"), double_draw.aref_second); glDepthMask(GL_FALSE); - glDrawElements(GL_TRIANGLE_STRIP, draw.vertex_index_stream.size(), GL_UNSIGNED_INT, + glDrawElements(tree.draw_mode, draw.vertex_index_stream.size(), GL_UNSIGNED_INT, (void*)0); break; default: @@ -992,7 +1013,7 @@ void Tie3AnotherCategory::render(DmaFollower& dma, } Tie3WithEnvmapJak1::Tie3WithEnvmapJak1(const std::string& name, int my_id, int level_id) - : Tie3(name, my_id, level_id, tfrag3::TieCategory::NORMAL) {} + : Tie3(name, my_id, level_id, nullptr, tfrag3::TieCategory::NORMAL) {} void Tie3WithEnvmapJak1::render(DmaFollower& dma, SharedRenderState* render_state, diff --git a/game/graphics/opengl_renderer/background/Tie3.h b/game/graphics/opengl_renderer/background/Tie3.h index ba8ee5385d..cd1f49793d 100644 --- a/game/graphics/opengl_renderer/background/Tie3.h +++ b/game/graphics/opengl_renderer/background/Tie3.h @@ -30,6 +30,7 @@ class Tie3 : public BucketRenderer { Tie3(const std::string& name, int my_id, int level_id, + const std::vector* anim_slot_array, tfrag3::TieCategory category = tfrag3::TieCategory::NORMAL); void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override; void draw_debug_window() override; @@ -130,6 +131,7 @@ class Tie3 : public BucketRenderer { std::vector> multidraw_offset_per_stripdraw; std::vector multidraw_count_buffer; std::vector multidraw_index_offset_buffer; + u64 draw_mode = 0; // strip or not, GL enum }; void envmap_second_pass_draw(const Tree& tree, @@ -168,7 +170,7 @@ class Tie3 : public BucketRenderer { } m_uniforms; EtieUniforms m_etie_uniforms, m_etie_base_uniforms; - + const std::vector* m_anim_slot_array; static_assert(sizeof(WindWork) == 84 * 16); }; diff --git a/game/graphics/opengl_renderer/debug_gui.cpp b/game/graphics/opengl_renderer/debug_gui.cpp index ba865e7272..c1b4076212 100644 --- a/game/graphics/opengl_renderer/debug_gui.cpp +++ b/game/graphics/opengl_renderer/debug_gui.cpp @@ -166,7 +166,8 @@ void OpenGlDebugGui::draw(const DmaStats& dma_stats) { prof().set_enable(record_events); } ImGui::SameLine(); - ImGui::Text(fmt::format("({}/{})", prof().get_next_idx(), prof().get_max_events()).c_str()); + ImGui::Text("%s", + fmt::format("({}/{})", prof().get_next_idx(), prof().get_max_events()).c_str()); ImGui::InputInt("Event Buffer Size", &max_event_buffer_size); if (ImGui::Button("Resize")) { prof().update_event_buffer_size(max_event_buffer_size); diff --git a/game/graphics/opengl_renderer/foreground/Generic2_DMA.cpp b/game/graphics/opengl_renderer/foreground/Generic2_DMA.cpp index 45f8b662e3..67333f72d2 100644 --- a/game/graphics/opengl_renderer/foreground/Generic2_DMA.cpp +++ b/game/graphics/opengl_renderer/foreground/Generic2_DMA.cpp @@ -598,12 +598,12 @@ void Generic2::process_dma_prim(DmaFollower& dma, u32 next_bucket) { } if (up1.vifcode0().kind == VifCode::Kind::FLUSHA) { while (dma.current_tag_offset() != next_bucket) { - auto it = dma.read_and_advance(); + [[maybe_unused]] auto it = dma.read_and_advance(); } break; } auto up2 = dma.read_and_advance(); - auto call = dma.read_and_advance(); + [[maybe_unused]] auto call = dma.read_and_advance(); // up1 is a 12 qw upload for control: // up2 is vertex upload. diff --git a/game/graphics/opengl_renderer/foreground/Merc2.cpp b/game/graphics/opengl_renderer/foreground/Merc2.cpp index dd8bee66e8..e738448d3b 100644 --- a/game/graphics/opengl_renderer/foreground/Merc2.cpp +++ b/game/graphics/opengl_renderer/foreground/Merc2.cpp @@ -542,11 +542,11 @@ void Merc2::handle_pc_model(const DmaTransfer& setup, bool is_custom_model = model->effects.at(0).all_draws.at(0).no_strip; u64 current_ignore_alpha_bits = flags->ignore_alpha_mask; // shader settings u64 current_effect_enable_bits = flags->enable_mask; // mask for game to disable an effect - bool model_uses_mod = - flags->bitflags & 1 && !is_custom_model; // if we should update vertices from game. + bool model_uses_mod = flags->bitflags & 1; // if we should update vertices from game. bool model_disables_fog = flags->bitflags & 2; - bool model_uses_pc_blerc = flags->bitflags & 4 && !is_custom_model; + bool model_uses_pc_blerc = flags->bitflags & 4; bool model_disables_envmap = flags->bitflags & 8; + bool model_no_texture = flags->bitflags & 16; input_data += 32; float blerc_weights[kMaxBlerc]; @@ -568,9 +568,9 @@ void Merc2::handle_pc_model(const DmaTransfer& setup, // will hold opengl buffers for the updated vertices ModBuffers mod_opengl_buffers[kMaxEffect]; - if (model_uses_pc_blerc) { + if (model_uses_pc_blerc && !is_custom_model) { model_mod_blerc_draws(num_effects, model, lev, mod_opengl_buffers, blerc_weights, stats); - } else if (model_uses_mod) { // only if we've enabled, this path is slow. + } else if (model_uses_mod && !is_custom_model) { // only if we've enabled, this path is slow. model_mod_draws(num_effects, model, lev, input_data, setup, mod_opengl_buffers, stats); } @@ -612,13 +612,29 @@ void Merc2::handle_pc_model(const DmaTransfer& setup, u32 first_bone = alloc_bones(bone_count, skel_matrix_buffer); // allocate lights + if (current_lights.w1) { + if (render_state->version != GameVersion::Jak3) { + current_lights.w1 = 0; // force off merc fade in jak2/1 - a bunch of stuff uses this + } + } u32 lights = alloc_lights(current_lights); stats->num_lights++; u64 hash = fnv64(model->name); + DrawArgs args; + args.lev_bucket = lev_bucket; + args.jak1_water_mode = uses_water; + args.disable_fog = model_disables_fog; + args.hash = hash; + args.lights = lights; + args.first_bone = first_bone; + args.no_texture = render_state->version == GameVersion::Jak3 && model_no_texture; + // loop over effects, creating draws for each for (size_t ei = 0; ei < model->effects.size(); ei++) { + args.fade = fade_buffer + 4 * ei; + // game has disabled it? if (!(current_effect_enable_bits & (1ull << ei))) { continue; @@ -630,35 +646,32 @@ void Merc2::handle_pc_model(const DmaTransfer& setup, } bool ignore_alpha = !!(current_ignore_alpha_bits & (1ull << ei)); + args.ignore_alpha = ignore_alpha; auto& effect = model->effects[ei]; bool should_envmap = effect.has_envmap && !model_disables_envmap; - bool should_mod = (model_uses_pc_blerc || model_uses_mod) && effect.has_mod_draw; + bool should_mod = + !is_custom_model && ((model_uses_pc_blerc || model_uses_mod) && effect.has_mod_draw); if (should_mod) { // draw as two parts, fixed and mod // do fixed draws: for (auto& fdraw : effect.mod.fix_draw) { - alloc_normal_draw(fdraw, ignore_alpha, lev_bucket, first_bone, lights, uses_water, - model_disables_fog, hash); + alloc_normal_draw(fdraw, args); if (should_envmap) { - try_alloc_envmap_draw(fdraw, effect.envmap_mode, effect.envmap_texture, lev_bucket, - fade_buffer + 4 * ei, first_bone, lights, uses_water); + try_alloc_envmap_draw(fdraw, effect.envmap_mode, effect.envmap_texture, args); } } // do mod draws for (auto& mdraw : effect.mod.mod_draw) { - auto n = alloc_normal_draw(mdraw, ignore_alpha, lev_bucket, first_bone, lights, uses_water, - model_disables_fog, hash); + auto n = alloc_normal_draw(mdraw, args); // modify the draw, set the mod flag and point it to the opengl buffer n->flags |= MOD_VTX; n->mod_vtx_buffer = mod_opengl_buffers[ei]; if (should_envmap) { - auto e = - try_alloc_envmap_draw(mdraw, effect.envmap_mode, effect.envmap_texture, lev_bucket, - fade_buffer + 4 * ei, first_bone, lights, uses_water); + auto e = try_alloc_envmap_draw(mdraw, effect.envmap_mode, effect.envmap_texture, args); if (e) { e->flags |= MOD_VTX; e->mod_vtx_buffer = mod_opengl_buffers[ei]; @@ -669,11 +682,9 @@ void Merc2::handle_pc_model(const DmaTransfer& setup, // no mod, just do all_draws for (auto& draw : effect.all_draws) { if (should_envmap) { - try_alloc_envmap_draw(draw, effect.envmap_mode, effect.envmap_texture, lev_bucket, - fade_buffer + 4 * ei, first_bone, lights, uses_water); + try_alloc_envmap_draw(draw, effect.envmap_mode, effect.envmap_texture, args); } - alloc_normal_draw(draw, ignore_alpha, lev_bucket, first_bone, lights, uses_water, - model_disables_fog, hash); + alloc_normal_draw(draw, args); } } } @@ -722,8 +733,8 @@ void Merc2::init_shader_common(Shader& shader, Uniforms* uniforms, bool include_ auto id = shader.id(); shader.activate(); if (include_lights) { - uniforms->light_direction[0] = glGetUniformLocation(id, "light_dir0"); - uniforms->light_direction[1] = glGetUniformLocation(id, "light_dir1"); + uniforms->light_direction[0] = glGetUniformLocation(id, "light_dir0_fade"); + uniforms->light_direction[1] = glGetUniformLocation(id, "light_dir1_fade_en"); uniforms->light_direction[2] = glGetUniformLocation(id, "light_dir2"); uniforms->light_color[0] = glGetUniformLocation(id, "light_col0"); uniforms->light_color[1] = glGetUniformLocation(id, "light_col1"); @@ -1042,14 +1053,10 @@ Merc2::ModBuffers Merc2::alloc_mod_vtx_buffer(const LevelData* lev) { Merc2::Draw* Merc2::try_alloc_envmap_draw(const tfrag3::MercDraw& mdraw, const DrawMode& envmap_mode, u32 envmap_texture, - LevelDrawBucket* lev_bucket, - const u8* fade, - u32 first_bone, - u32 lights, - bool jak1_water_mode) { + const DrawArgs& args) { bool nonzero_fade = false; for (int i = 0; i < 4; i++) { - if (fade[i]) { + if (args.fade[i]) { nonzero_fade = true; break; } @@ -1058,58 +1065,55 @@ Merc2::Draw* Merc2::try_alloc_envmap_draw(const tfrag3::MercDraw& mdraw, return nullptr; } - Draw* draw = &lev_bucket->envmap_draws[lev_bucket->next_free_envmap_draw++]; + Draw* draw = &args.lev_bucket->envmap_draws[args.lev_bucket->next_free_envmap_draw++]; draw->flags = 0; draw->first_index = mdraw.first_index; draw->index_count = mdraw.index_count; draw->mode = envmap_mode; draw->hash = 0; - if (jak1_water_mode) { + if (args.jak1_water_mode) { draw->mode.enable_ab(); draw->mode.disable_depth_write(); } draw->texture = envmap_texture; - draw->first_bone = first_bone; - draw->light_idx = lights; + draw->first_bone = args.first_bone; + draw->light_idx = args.lights; draw->num_triangles = mdraw.num_triangles; + draw->no_strip = mdraw.no_strip; for (int i = 0; i < 4; i++) { - draw->fade[i] = fade[i]; + draw->fade[i] = args.fade[i]; } return draw; } -Merc2::Draw* Merc2::alloc_normal_draw(const tfrag3::MercDraw& mdraw, - bool ignore_alpha, - LevelDrawBucket* lev_bucket, - u32 first_bone, - u32 lights, - bool jak1_water_mode, - bool disable_fog, - u64 hash) { - Draw* draw = &lev_bucket->draws[lev_bucket->next_free_draw++]; +Merc2::Draw* Merc2::alloc_normal_draw(const tfrag3::MercDraw& mdraw, const DrawArgs& args) { + Draw* draw = &args.lev_bucket->draws[args.lev_bucket->next_free_draw++]; draw->flags = 0; draw->first_index = mdraw.first_index; draw->index_count = mdraw.index_count; draw->mode = mdraw.mode; - draw->hash = hash; - if (jak1_water_mode) { + draw->hash = args.hash; + if (args.jak1_water_mode) { draw->mode.set_ab(true); draw->mode.disable_depth_write(); } - if (disable_fog) { + if (args.disable_fog) { draw->mode.set_fog(false); // but don't toggle it the other way? } draw->texture = mdraw.eye_id == 0xff ? mdraw.tree_tex_id : (0xefffff00 | mdraw.eye_id); - draw->first_bone = first_bone; - draw->light_idx = lights; + draw->first_bone = args.first_bone; + draw->light_idx = args.lights; draw->num_triangles = mdraw.num_triangles; draw->no_strip = mdraw.no_strip; - if (ignore_alpha) { + if (args.ignore_alpha) { draw->flags |= IGNORE_ALPHA; } + if (args.no_texture) { + draw->flags |= NO_TEXTURE; + } for (int i = 0; i < 4; i++) { draw->fade[i] = 0; } @@ -1281,8 +1285,18 @@ void Merc2::do_draws(const Draw* draw_array, } if ((int)draw.light_idx != last_light && !set_fade) { - set_uniform(uniforms.light_direction[0], m_lights_buffer[draw.light_idx].direction0); - set_uniform(uniforms.light_direction[1], m_lights_buffer[draw.light_idx].direction1); + const auto& l0_dir = m_lights_buffer[draw.light_idx].direction0; + const auto& l1_dir = m_lights_buffer[draw.light_idx].direction1; + float fade = 1.f; + float fade_enable = 0.f; + if (m_lights_buffer[draw.light_idx].w1) { + fade = m_lights_buffer[draw.light_idx].w2 / 128.f; + fade_enable = 1.f; + } + math::Vector4f l0_dir_f(l0_dir.x(), l0_dir.y(), l0_dir.z(), fade); + set_uniform(uniforms.light_direction[0], l0_dir_f); + math::Vector4f l1_dir_f(l1_dir.x(), l1_dir.y(), l1_dir.z(), fade_enable); + set_uniform(uniforms.light_direction[1], l1_dir_f); set_uniform(uniforms.light_direction[2], m_lights_buffer[draw.light_idx].direction2); set_uniform(uniforms.light_color[0], m_lights_buffer[draw.light_idx].color0); set_uniform(uniforms.light_color[1], m_lights_buffer[draw.light_idx].color1); @@ -1290,24 +1304,52 @@ void Merc2::do_draws(const Draw* draw_array, set_uniform(uniforms.light_ambient, m_lights_buffer[draw.light_idx].ambient); last_light = draw.light_idx; } - setup_opengl_from_draw_mode(draw.mode, GL_TEXTURE0, use_mipmaps_for_filtering); glUniform1i(uniforms.decal, draw.mode.get_decal()); + glUniform1i(uniforms.gfx_hack_no_tex, (draw.flags & NO_TEXTURE) != 0); if (set_fade) { math::Vector4f fade = math::Vector4f(draw.fade[0], draw.fade[1], draw.fade[2], draw.fade[3]) / 255.f; set_uniform(uniforms.fade, fade); ASSERT(draw.mode.get_alpha_blend() == DrawMode::AlphaBlend::SRC_0_DST_DST); - // glBindTexture(GL_TEXTURE_2D, render_state->texture_pool->get_placeholder_texture()); } - prof.add_draw_call(); - prof.add_tri(draw.num_triangles); - glBindBufferRange(GL_UNIFORM_BUFFER, 1, m_bones_buffer, - sizeof(math::Vector4f) * draw.first_bone, 128 * sizeof(ShaderMercMat)); - glDrawElements(draw.no_strip ? GL_TRIANGLES : GL_TRIANGLE_STRIP, draw.index_count, - GL_UNSIGNED_INT, (void*)(sizeof(u32) * draw.first_index)); + if (m_lights_buffer[draw.light_idx].w1 && !set_fade) { + DrawMode mode = draw.mode; + mode.set_alpha_blend(DrawMode::AlphaBlend::SRC_DST_SRC_DST); + mode.set_ab(true); + setup_opengl_from_draw_mode(mode, GL_TEXTURE0, use_mipmaps_for_filtering); + + prof.add_draw_call(2); + prof.add_tri(draw.num_triangles * 2); + glBindBufferRange(GL_UNIFORM_BUFFER, 1, m_bones_buffer, + sizeof(math::Vector4f) * draw.first_bone, 128 * sizeof(ShaderMercMat)); + // draw rgb + const auto& l1_dir = m_lights_buffer[draw.light_idx].direction1; + math::Vector4f l1_dir_f(l1_dir.x(), l1_dir.y(), l1_dir.z(), 1); + set_uniform(uniforms.light_direction[1], l1_dir_f); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + glDrawElements(draw.no_strip ? GL_TRIANGLES : GL_TRIANGLE_STRIP, draw.index_count, + GL_UNSIGNED_INT, (void*)(sizeof(u32) * draw.first_index)); + // draw a + setup_opengl_from_draw_mode(draw.mode, GL_TEXTURE0, use_mipmaps_for_filtering); + math::Vector4f l1_dir_f_off(l1_dir.x(), l1_dir.y(), l1_dir.z(), -1); + set_uniform(uniforms.light_direction[1], l1_dir_f_off); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + glDrawElements(draw.no_strip ? GL_TRIANGLES : GL_TRIANGLE_STRIP, draw.index_count, + GL_UNSIGNED_INT, (void*)(sizeof(u32) * draw.first_index)); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + } else { + setup_opengl_from_draw_mode(draw.mode, GL_TEXTURE0, use_mipmaps_for_filtering); + prof.add_draw_call(); + prof.add_tri(draw.num_triangles); + glBindBufferRange(GL_UNIFORM_BUFFER, 1, m_bones_buffer, + sizeof(math::Vector4f) * draw.first_bone, 128 * sizeof(ShaderMercMat)); + glDrawElements(draw.no_strip ? GL_TRIANGLES : GL_TRIANGLE_STRIP, draw.index_count, + GL_UNSIGNED_INT, (void*)(sizeof(u32) * draw.first_index)); + } } if (!normal_vtx_buffer_bound) { diff --git a/game/graphics/opengl_renderer/foreground/Merc2.h b/game/graphics/opengl_renderer/foreground/Merc2.h index 9705907b66..b03ccef846 100644 --- a/game/graphics/opengl_renderer/foreground/Merc2.h +++ b/game/graphics/opengl_renderer/foreground/Merc2.h @@ -69,11 +69,11 @@ class Merc2 { struct VuLights { math::Vector3f direction0; - u32 w0; + u32 w0; // 12 math::Vector3f direction1; - u32 w1; + u32 w1; // 28 math::Vector3f direction2; - u32 w2; + u32 w2; // 44 math::Vector4f color0; math::Vector4f color1; math::Vector4f color2; @@ -177,6 +177,7 @@ class Merc2 { enum DrawFlags { IGNORE_ALPHA = 1, MOD_VTX = 2, + NO_TEXTURE = 4, }; struct Draw { @@ -208,23 +209,25 @@ class Merc2 { next_free_envmap_draw = 0; } }; - Draw* alloc_normal_draw(const tfrag3::MercDraw& mdraw, - bool ignore_alpha, - LevelDrawBucket* lev_bucket, - u32 first_bone, - u32 lights, - bool jak1_water_mode, - bool disable_fog, - u64 hash); + + struct DrawArgs { + LevelDrawBucket* lev_bucket; + const u8* fade; + bool jak1_water_mode; + bool ignore_alpha; + bool disable_fog; + bool no_texture; + u64 hash; + u32 lights; + u32 first_bone; + }; + + Draw* alloc_normal_draw(const tfrag3::MercDraw& mdraw, const DrawArgs& args); Draw* try_alloc_envmap_draw(const tfrag3::MercDraw& mdraw, const DrawMode& envmap_mode, u32 envmap_texture, - LevelDrawBucket* lev_bucket, - const u8* fade, - u32 first_bone, - u32 lights, - bool jak1_water_mode); + const DrawArgs& args); void do_draws(const Draw* draw_array, const LevelData* lev, diff --git a/game/graphics/opengl_renderer/loader/LoaderStages.cpp b/game/graphics/opengl_renderer/loader/LoaderStages.cpp index 0e3dfcab36..2a3ff372eb 100644 --- a/game/graphics/opengl_renderer/loader/LoaderStages.cpp +++ b/game/graphics/opengl_renderer/loader/LoaderStages.cpp @@ -344,6 +344,10 @@ class TieLoadStage : public LoaderStage { if (m_next_tree >= data.lev_data->level->tie_trees[m_next_geo].size()) { m_next_tree = 0; m_next_geo++; + while (m_next_geo < tfrag3::TIE_GEOS && + data.lev_data->level->tie_trees[m_next_geo].empty()) { + m_next_geo++; + } if (m_next_geo >= tfrag3::TIE_GEOS) { m_verts_done = true; m_next_tree = 0; @@ -448,6 +452,10 @@ class TieLoadStage : public LoaderStage { if (m_next_tree >= data.lev_data->level->tie_trees[m_next_geo].size()) { m_next_tree = 0; m_next_geo++; + while (m_next_geo < tfrag3::TIE_GEOS && + data.lev_data->level->tie_trees[m_next_geo].empty()) { + m_next_geo++; + } if (m_next_geo >= tfrag3::TIE_GEOS) { m_indices_done = true; m_next_tree = 0; diff --git a/game/graphics/opengl_renderer/shaders/merc2.frag b/game/graphics/opengl_renderer/shaders/merc2.frag index 962e6486e0..67a18f5a84 100644 --- a/game/graphics/opengl_renderer/shaders/merc2.frag +++ b/game/graphics/opengl_renderer/shaders/merc2.frag @@ -5,11 +5,12 @@ in vec4 vtx_color; in vec2 vtx_st; in float fog; - uniform sampler2D tex_T0; uniform vec4 fog_color; uniform int ignore_alpha; +uniform vec4 light_dir0_fade; +uniform vec4 light_dir1_fade_en; uniform int decal_enable; @@ -25,10 +26,20 @@ void main() { color = T0; } color.a *= 2; - //color.a = T0.a * 4; } else { color.rgb = vtx_color.rgb; - color.a = 1; + + if (decal_enable == 0) { + color.a = vtx_color.a * 2; + } else { + color.a = 1; + } + } + + if (light_dir1_fade_en.w > 0) { + color.a = light_dir0_fade.w; + } else if (light_dir1_fade_en.w < 0) { + color.a *= light_dir0_fade.w; } diff --git a/game/graphics/opengl_renderer/shaders/merc2.vert b/game/graphics/opengl_renderer/shaders/merc2.vert index 609803b5cc..fa591e5436 100644 --- a/game/graphics/opengl_renderer/shaders/merc2.vert +++ b/game/graphics/opengl_renderer/shaders/merc2.vert @@ -9,8 +9,8 @@ layout (location = 4) in vec4 rgba; layout (location = 5) in uvec3 mats; // light control -uniform vec3 light_dir0; -uniform vec3 light_dir1; +uniform vec4 light_dir0_fade; +uniform vec4 light_dir1_fade_en; uniform vec3 light_dir2; uniform vec4 light_col0; uniform vec4 light_col1; @@ -84,7 +84,7 @@ void main() { vec4 transformed = perspective_matrix * vtx_pos; rotated_nrm = normalize(rotated_nrm); - vec3 light_intensity = light_dir0 * rotated_nrm.x + light_dir1 * rotated_nrm.y + light_dir2 * rotated_nrm.z; + vec3 light_intensity = light_dir0_fade.xyz * rotated_nrm.x + light_dir1_fade_en.xyz * rotated_nrm.y + light_dir2 * rotated_nrm.z; light_intensity = max(light_intensity, vec3(0, 0, 0)); vec4 light_color = light_ambient diff --git a/game/graphics/opengl_renderer/shaders/plain_texture.frag b/game/graphics/opengl_renderer/shaders/plain_texture.frag new file mode 100644 index 0000000000..031b1c06d7 --- /dev/null +++ b/game/graphics/opengl_renderer/shaders/plain_texture.frag @@ -0,0 +1,9 @@ +#version 410 core + +uniform sampler2D tex_T0; +out vec4 color; +in vec2 tex_coord; + +void main() { + color = texture(tex_T0, tex_coord); +} diff --git a/game/graphics/opengl_renderer/shaders/plain_texture.vert b/game/graphics/opengl_renderer/shaders/plain_texture.vert new file mode 100644 index 0000000000..de2668ed7e --- /dev/null +++ b/game/graphics/opengl_renderer/shaders/plain_texture.vert @@ -0,0 +1,10 @@ +#version 410 core + +layout (location = 0) in vec2 position_in; + +out vec2 tex_coord; + +void main() { + gl_Position = vec4(position_in, 0, 1.0); + tex_coord = (position_in + vec2(1.0, 1.0)) * 0.5; +} diff --git a/game/graphics/opengl_renderer/shaders/sprite3_3d.vert b/game/graphics/opengl_renderer/shaders/sprite3_3d.vert index e79531a92d..819c921007 100644 --- a/game/graphics/opengl_renderer/shaders/sprite3_3d.vert +++ b/game/graphics/opengl_renderer/shaders/sprite3_3d.vert @@ -119,7 +119,7 @@ void main() { float sp_sin = sin(quat.z); float sp_cos = cos(quat.z); - vec4 xy0_vf19 = xy_array[vert_id + flags_matrix.x]; + vec4 xy0_vf19 = xy_array[vert_id + (flags_matrix.x & 15u)]; vec4 vf12_rotated = (basis_x * sp_cos) - (basis_y * sp_sin); vec4 vf13_rotated_trans = (basis_x * sp_sin) + (basis_y * sp_cos); @@ -141,7 +141,7 @@ void main() { float sp_sin = sin(quat.z); float sp_cos = cos(quat.z); - vec4 xy0_vf19 = xy_array[vert_id + flags_matrix.x]; + vec4 xy0_vf19 = xy_array[vert_id + (flags_matrix.x & 15u)]; vec4 vf12_rotated = (basis_x * sp_cos) - (basis_y * sp_sin); vec4 vf13_rotated_trans = (basis_x * sp_sin) + (basis_y * sp_cos); diff --git a/game/graphics/opengl_renderer/sprite/Sprite3.cpp b/game/graphics/opengl_renderer/sprite/Sprite3.cpp index 03cf5f1b7e..ebdbea0a31 100644 --- a/game/graphics/opengl_renderer/sprite/Sprite3.cpp +++ b/game/graphics/opengl_renderer/sprite/Sprite3.cpp @@ -837,6 +837,7 @@ void Sprite3::do_block_common(SpriteMode mode, if (render_state->version == GameVersion::Jak3) { auto flag = m_vec_data_2d[sprite_idx].flag(); + if ((flag & 0x10) || (flag & 0x20)) { // these flags mean we need to swap vertex order around - not yet implemented since it's too // hard to get right without this code running. @@ -868,6 +869,34 @@ void Sprite3::do_block_common(SpriteMode mode, m_vertices_3d.at(start_vtx_id + 2).info[2] = 3; m_vertices_3d.at(start_vtx_id + 3).info[2] = 2; + // note that PC swaps the last two vertices + if (render_state->version == GameVersion::Jak3) { + auto flag = m_vec_data_2d[sprite_idx].flag(); + switch (flag & 0x30) { + case 0x10: + // FLAG 16: 1, 0, 3, 2 + m_vertices_3d.at(start_vtx_id + 0).info[2] = 0; + m_vertices_3d.at(start_vtx_id + 1).info[2] = 1; + m_vertices_3d.at(start_vtx_id + 2).info[2] = 3; + m_vertices_3d.at(start_vtx_id + 3).info[2] = 2; + break; + case 0x20: + // FLAG 32: 3, 2, 1, 0 + m_vertices_3d.at(start_vtx_id + 0).info[2] = 3; + m_vertices_3d.at(start_vtx_id + 1).info[2] = 2; + m_vertices_3d.at(start_vtx_id + 2).info[2] = 0; + m_vertices_3d.at(start_vtx_id + 3).info[2] = 1; + break; + case 0x30: + // 2, 3, 0, 1 + m_vertices_3d.at(start_vtx_id + 0).info[2] = 2; + m_vertices_3d.at(start_vtx_id + 1).info[2] = 3; + m_vertices_3d.at(start_vtx_id + 2).info[2] = 1; + m_vertices_3d.at(start_vtx_id + 3).info[2] = 0; + break; + } + } + ++m_sprite_idx; } } diff --git a/game/graphics/pipelines/opengl.cpp b/game/graphics/pipelines/opengl.cpp index f1e1dbb9a8..83fd439afa 100644 --- a/game/graphics/pipelines/opengl.cpp +++ b/game/graphics/pipelines/opengl.cpp @@ -220,9 +220,10 @@ static std::shared_ptr gl_make_display(int width, // TODO - SDL2 doesn't seem to support HDR (and neither does windows) // Related - // https://answers.microsoft.com/en-us/windows/forum/all/hdr-monitor-low-brightness-after-exiting-full/999f7ee9-7ba3-4f9c-b812-bbeb9ff8dcc1 - SDL_Window* window = - SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, - SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_Window* window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + // TODO - rendering code on hiDPI/Retina displays is not adequate, solve it properly so that + // `SDL_WINDOW_ALLOW_HIGHDPI` can be added back to the window flags. prof().end_event(); if (!window) { sdl_util::log_error("gl_make_display failed - Could not create display window"); diff --git a/game/kernel/common/kmachine.cpp b/game/kernel/common/kmachine.cpp index 360865174f..eb86a91859 100644 --- a/game/kernel/common/kmachine.cpp +++ b/game/kernel/common/kmachine.cpp @@ -1,13 +1,37 @@ #include "kmachine.h" -#include -#include +#include #include +#include +#include #include -#include +#include #define MINIAUDIO_IMPLEMENTATION +// NOTE - this is needed, because on macOS, there is a file called `MacTypes.h` +// inside it, it defines something named `Ptr` +// Our `Ptr` is not namespaced, so there is ambiguity. +// +// Second fix is because miniaudio redefines functions in the stdlib based on bad pre-processor +// assumptions AppleClang apparently does not define POSIX macros, leading to future ambiguity +namespace MiniAudioLib { +#if defined(__APPLE__) +#if !defined(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 200809L +#include "third-party/miniaudio.h" +#undef _POSIX_C_SOURCE +#else +// It should work if it's defined, but for some reason it didn't this is the unlikely branch +// but lets maintain the original value +#define NOT_REAL_OLD_POSIX_C_SOURCE _POSIX_C_SOURCE #include "third-party/miniaudio.h" +#define _POSIX_C_SOURCE NOT_REAL_OLD_POSIX_C_SOURCE +#undef NOT_REAL_OLD_POSIX_C_SOURCE +#endif +#else +#include "third-party/miniaudio.h" +#endif +} // namespace MiniAudioLib #include "common/global_profiler/GlobalProfiler.h" #include "common/log/log.h" @@ -51,9 +75,9 @@ u32 vblank_interrupt_handler = 0; Timer ee_clock_timer; -ma_engine maEngine; -std::map maSoundMap; -ma_sound* mainMusicSound; +MiniAudioLib::ma_engine maEngine; +std::map> maSoundMap; +MiniAudioLib::ma_sound* mainMusicSound; void kmachine_init_globals_common() { memset(pad_dma_buf, 0, sizeof(pad_dma_buf)); @@ -63,10 +87,10 @@ void kmachine_init_globals_common() { vif1_interrupt_handler = 0; vblank_interrupt_handler = 0; ee_clock_timer = Timer(); - #ifdef _WIN32 // only do this on windows, because it only works on windows? - ma_engine_uninit(&maEngine); - #endif - ma_engine_init(NULL, &maEngine); +#ifdef _WIN32 // only do this on windows, because it only works on windows? + MiniAudioLib::ma_engine_uninit(&maEngine); +#endif + MiniAudioLib::ma_engine_init(NULL, &maEngine); } /*! @@ -119,10 +143,42 @@ u64 CPadOpen(u64 cpad_info, s32 pad_number) { return cpad_info; } +// Mutex to synchronize access to activeMusics +std::mutex activeMusicsMutex; + +// Declare a mutex for synchronizing access to mainMusicInstance +std::mutex mainMusicMutex; + +// Function to stop all instances of specific sound by filepath +void stopMP3(u32 filePathu32) { + std::string filePath = Ptr(filePathu32).c()->data(); + std::cout << "Trying to stop file: " << filePath << std::endl; + + std::lock_guard lock(activeMusicsMutex); + auto it = maSoundMap.find(filePath); + if (it == maSoundMap.end()) { + std::cerr << "Couldn't find sound to stop: " << filePath << std::endl; + } else { + // stop all instances of this sound + for (auto sound : it->second) { + if (MiniAudioLib::ma_sound_stop(&sound) != MiniAudioLib::MA_SUCCESS) { + std::cerr << "Failed to stop sound: " << filePath << std::endl; + } + // let the thread finish and handle ma_sound_uninit + } + // clear list of sounds for this filepath + it->second.clear(); + } +} + // Function to stop all currently playing sounds. void stopAllSounds() { for (auto& pair : maSoundMap) { - ma_sound_stop(&pair.second); + // stop all instances of this sound + for (auto sound : pair.second) { + MiniAudioLib::ma_sound_stop(&sound); + } + pair.second.clear(); } maSoundMap.clear(); } @@ -136,69 +192,81 @@ std::vector getPlayingFileNames() { return playingFileNames; } -std::mutex activeMusicsMutex; // Mutex to synchronize access to activeMusics - -// Declare a mutex for synchronizing access to mainMusicInstance -std::mutex mainMusicMutex; +u64 playMP3_internal(u32 filePathu32, u32 volume, bool isMainMusic) { + std::string filePath = Ptr(filePathu32).c()->data(); + std::string fullFilePath = fs::path(file_util::get_jak_project_dir() / "custom_assets" / + game_version_names[g_game_version] / "audio" / filePath).string(); + + if (!file_util::file_exists(fullFilePath)) { + // file doesn't exist, let GOAL side know we didn't find it + return bool_to_symbol(false); + } -void playMP3_internal(u32 filePathu32, u32 volume, bool isMainMusic) { std::thread thread([=]() { - std::string filePath = Ptr(filePathu32).c()->data(); + std::cout << "Playing file: " << filePath << std::endl; - ma_result result; - ma_sound sound; + MiniAudioLib::ma_result result; + MiniAudioLib::ma_sound sound; - result = ma_sound_init_from_file(&maEngine, filePath.c_str(), 0, NULL, NULL, &sound); - if (result != MA_SUCCESS) { + result = MiniAudioLib::ma_sound_init_from_file(&maEngine, fullFilePath.c_str(), 0, NULL, NULL, + &sound); + if (result != MiniAudioLib::MA_SUCCESS) { std::cout << "Failed to load: " << filePath << std::endl; return; } - ma_sound_set_volume(&sound, ((float)volume) / 100.0); + MiniAudioLib::ma_sound_set_volume(&sound, ((float)volume) / 100.0); if (isMainMusic) { - ma_sound_set_looping(&sound, MA_TRUE); + MiniAudioLib::ma_sound_set_looping(&sound, MA_TRUE); mainMusicMutex.lock(); mainMusicSound = &sound; mainMusicMutex.unlock(); } - ma_sound_start(&sound); + MiniAudioLib::ma_sound_start(&sound); - { + if (!isMainMusic) { std::lock_guard lock(activeMusicsMutex); - maSoundMap.insert(std::make_pair(filePath, sound)); + if (maSoundMap.find(filePath) == maSoundMap.end()) { + maSoundMap.insert(std::make_pair(filePath, std::list())); + } + maSoundMap[filePath].push_back(sound); } - // loop until we're no longer main music, or we reach the end of non-looping sound - while (mainMusicSound == &sound || !ma_sound_at_end(&sound)) { + // sleep/loop until we're no longer main music, or non-looping sound is stopped/ends + while (mainMusicSound == &sound || MiniAudioLib::ma_sound_is_playing(&sound)) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); } - ma_sound_stop(&sound); - ma_sound_uninit(&sound); + MiniAudioLib::ma_sound_stop(&sound); + MiniAudioLib::ma_sound_uninit(&sound); std::cout << "Finished playing file: " << filePath << std::endl; - { + if (!isMainMusic) { std::lock_guard lock(activeMusicsMutex); - maSoundMap.erase(filePath); + if (maSoundMap.find(filePath) != maSoundMap.end()) { + maSoundMap[filePath].remove_if( + [&](MiniAudioLib::ma_sound l_sound) { return &sound == &l_sound; }); + } } }); thread.detach(); + return bool_to_symbol(true); } -void playMP3(u32 filePathu32, u32 volume) { - playMP3_internal(filePathu32, volume, false); +u64 playMP3(u32 filePathu32, u32 volume) { + return playMP3_internal(filePathu32, volume, false); } // Function to stop the Main Music. void stopMainMusic() { mainMusicMutex.lock(); - if (mainMusicSound && ma_sound_is_playing(mainMusicSound)) { + if (mainMusicSound && MiniAudioLib::ma_sound_is_playing(mainMusicSound)) { std::cout << "Stopping Main Music..." << std::endl; - ma_sound_stop(mainMusicSound); + MiniAudioLib::ma_sound_stop(mainMusicSound); mainMusicSound = NULL; std::cout << "Stopped Main Music " << std::endl; } @@ -216,16 +284,16 @@ void playMainMusic(u32 filePathu32, u32 volume) { void pauseMainMusic() { mainMusicMutex.lock(); - if (mainMusicSound && ma_sound_is_playing(mainMusicSound)) { - ma_sound_stop(mainMusicSound); + if (mainMusicSound && MiniAudioLib::ma_sound_is_playing(mainMusicSound)) { + MiniAudioLib::ma_sound_stop(mainMusicSound); } mainMusicMutex.unlock(); } void resumeMainMusic() { mainMusicMutex.lock(); - if (mainMusicSound && !ma_sound_is_playing(mainMusicSound)) { - ma_sound_start(mainMusicSound); + if (mainMusicSound && !MiniAudioLib::ma_sound_is_playing(mainMusicSound)) { + MiniAudioLib::ma_sound_start(mainMusicSound); } mainMusicMutex.unlock(); } @@ -234,7 +302,7 @@ void resumeMainMusic() { void changeMainMusicVolume(u32 volume) { mainMusicMutex.lock(); if (mainMusicSound) { - ma_sound_set_volume(mainMusicSound, ((float)volume) / 100.0); + MiniAudioLib::ma_sound_set_volume(mainMusicSound, ((float)volume) / 100.0); } mainMusicMutex.unlock(); } @@ -721,16 +789,18 @@ void pc_set_window_size(u64 width, u64 height) { } } -s64 pc_get_num_resolutions() { +s64 pc_get_num_resolutions(u32 for_windowed) { if (Display::GetMainDisplay()) { - return Display::GetMainDisplay()->get_display_manager()->get_num_resolutions(); + return Display::GetMainDisplay()->get_display_manager()->get_num_resolutions( + symbol_to_bool(for_windowed)); } return 0; } -void pc_get_resolution(u32 id, u32 w_ptr, u32 h_ptr) { +void pc_get_resolution(u32 id, u32 for_windowed, u32 w_ptr, u32 h_ptr) { if (Display::GetMainDisplay()) { - auto res = Display::GetMainDisplay()->get_display_manager()->get_resolution(id); + auto res = Display::GetMainDisplay()->get_display_manager()->get_resolution( + id, symbol_to_bool(for_windowed)); auto w = Ptr(w_ptr).c(); if (w) { *w = res.width; @@ -1037,6 +1107,15 @@ void pc_register_screen_shot_settings(u32 ptr) { register_screen_shot_settings(Ptr(ptr).c()); } +void pc_encode_utf8_string(u32 src_str_ptr, u32 str_dest_ptr) { + auto str = std::string(Ptr(src_str_ptr).c()->data()); + std::string version = version_to_game_name(g_game_version); + const std::string font_bank_name = version == "jak1" ? "jak1-v2" : version; + std::string converted = + get_font_bank(get_text_version_from_name(font_bank_name))->convert_utf8_to_game(str); + strcpy(Ptr(str_dest_ptr).c()->data(), converted.c_str()); +} + /// Initializes all functions that are common across all game versions /// These functions have the same implementation and do not use any game specific functions (other /// than the one to create a function in the first place) @@ -1129,13 +1208,16 @@ void init_common_pc_port_functions( make_func_symbol_func("pc-filepath-exists?", (void*)pc_filepath_exists); make_func_symbol_func("pc-mkdir-file-path", (void*)pc_mkdir_filepath); - //Play sound file + // Play sound file make_func_symbol_func("play-sound-file", (void*)playMP3); - //Stop sound file - make_func_symbol_func("stop-sound-file", (void*)stopAllSounds); + // Stop sound file (all instances) + make_func_symbol_func("stop-sound-file", (void*)stopMP3); - //Main music stuff + // Stop all sounds + make_func_symbol_func("stop-all-sounds", (void*)stopAllSounds); + + // Main music stuff make_func_symbol_func("play-main-music", (void*)playMainMusic); make_func_symbol_func("pause-main-music", (void*)pauseMainMusic); make_func_symbol_func("stop-main-music", (void*)stopMainMusic); @@ -1152,6 +1234,9 @@ void init_common_pc_port_functions( // RNG make_func_symbol_func("pc-rand", (void*)pc_rand); + // text + make_func_symbol_func("pc-encode-utf8-string", (void*)pc_encode_utf8_string); + // debugging tools make_func_symbol_func("pc-filter-debug-string?", (void*)pc_filter_debug_string); make_func_symbol_func("pc-screen-shot", (void*)pc_screen_shot); diff --git a/game/kernel/common/kmachine.h b/game/kernel/common/kmachine.h index 010cf1f88e..d44b6e0501 100644 --- a/game/kernel/common/kmachine.h +++ b/game/kernel/common/kmachine.h @@ -85,7 +85,8 @@ struct CommonPCPortFunctionWrappers { extern CommonPCPortFunctionWrappers g_pc_port_funcs; -void playMP3(u32 filePath, u32 volume); +u64 playMP3(u32 filePath, u32 volume); +u64 bool_to_symbol(const bool); /// Initializes all common PC Port functions for all Jak games void init_common_pc_port_functions( diff --git a/game/kernel/common/kmemcard.h b/game/kernel/common/kmemcard.h index d5532210f4..2daa7c810e 100644 --- a/game/kernel/common/kmemcard.h +++ b/game/kernel/common/kmemcard.h @@ -11,9 +11,8 @@ void kmemcard_init_globals(); -// TODO: jak 3 stubs -constexpr PerGameVersion SAVE_SIZE(692, 1204, 0); // 691 for jak 1 v1 -constexpr PerGameVersion BANK_SIZE(0x10000, 0x20000, 0x0); +constexpr PerGameVersion SAVE_SIZE(692, 1204, 1060); // 691 for jak 1 v1 +constexpr PerGameVersion BANK_SIZE(0x10000, 0x20000, 0x1e000); // each card can be in one of these states: enum class MemoryCardState : u32 { diff --git a/game/kernel/jak2/kmachine.cpp b/game/kernel/jak2/kmachine.cpp index aa11bc7fde..6ad8fc7672 100644 --- a/game/kernel/jak2/kmachine.cpp +++ b/game/kernel/jak2/kmachine.cpp @@ -424,7 +424,7 @@ int InitMachine() { * Shutdown the runtime. */ int ShutdownMachine() { - Msg(6, "kernel: machine shutdown (reason %d)\n", MasterExit); + Msg(6, "kernel: machine shutdown (reason %d)\n", (int)MasterExit); StopIOP(); ShutdownSound(); @@ -541,7 +541,6 @@ void InitMachine_PCPort() { make_function_symbol_from_c("__pc-get-tex-remap", (void*)lookup_jak2_texture_dest_offset); make_function_symbol_from_c("pc-init-autosplitter-struct", (void*)kmachine_extras::init_autosplit_struct); - make_function_symbol_from_c("pc-encode-utf8-string", (void*)kmachine_extras::encode_utf8_string); // discord rich presence make_function_symbol_from_c("pc-discord-rpc-update", (void*)kmachine_extras::update_discord_rpc); diff --git a/game/kernel/jak2/kmachine_extras.cpp b/game/kernel/jak2/kmachine_extras.cpp index 0f8c2c1a69..7faf3d806d 100644 --- a/game/kernel/jak2/kmachine_extras.cpp +++ b/game/kernel/jak2/kmachine_extras.cpp @@ -196,13 +196,6 @@ inline bool symbol_to_bool(const u32 symptr) { return symptr != s7.offset; } -// TODO - move to common -void encode_utf8_string(u32 src_str_ptr, u32 str_dest_ptr) { - auto str = std::string(Ptr(src_str_ptr).c()->data()); - std::string converted = get_font_bank(GameTextVersion::JAK2)->convert_utf8_to_game(str); - strcpy(Ptr(str_dest_ptr).c()->data(), converted.c_str()); -} - void init_autosplit_struct() { g_auto_splitter_block_jak2.pointer_to_symbol = (u64)g_ee_main_mem + (u64)intern_from_c("*autosplit-info-jak2*")->value(); diff --git a/game/kernel/jak2/kmachine_extras.h b/game/kernel/jak2/kmachine_extras.h index f10c13d5a6..71893d3d06 100644 --- a/game/kernel/jak2/kmachine_extras.h +++ b/game/kernel/jak2/kmachine_extras.h @@ -11,8 +11,6 @@ void pc_set_levels(u32 lev_list); void pc_set_active_levels(u32 lev_list); u32 alloc_vagdir_names(u32 heap_sym); inline u64 bool_to_symbol(const bool val); -// TODO - move to common -void encode_utf8_string(u32 src_str_ptr, u32 str_dest_ptr); void init_autosplit_struct(); void callback_fetch_external_speedrun_times(bool success, const std::string& cache_id, diff --git a/game/kernel/jak3/kmachine.cpp b/game/kernel/jak3/kmachine.cpp index 64a48a14e6..3c185bb061 100644 --- a/game/kernel/jak3/kmachine.cpp +++ b/game/kernel/jak3/kmachine.cpp @@ -294,7 +294,7 @@ int InitMachine() { } int ShutdownMachine() { - Msg(6, "kernel: machine shutdown (reason %d)\n", MasterExit); + Msg(6, "kernel: machine shutdown (reason %d)\n", (int)MasterExit); StopIOP(); ShutdownSound(); @@ -369,14 +369,14 @@ void InitMachine_PCPort() { make_function_symbol_from_c("__pc-set-active-levels", (void*)kmachine_extras::pc_set_active_levels); make_function_symbol_from_c("__pc-get-tex-remap", (void*)lookup_jak3_texture_dest_offset); - // make_function_symbol_from_c("pc-init-autosplitter-struct", (void*)init_autosplit_struct); - make_function_symbol_from_c("pc-encode-utf8-string", (void*)kmachine_extras::encode_utf8_string); + make_function_symbol_from_c("pc-init-autosplitter-struct", + (void*)kmachine_extras::init_autosplit_struct); // discord rich presence make_function_symbol_from_c("pc-discord-rpc-update", (void*)kmachine_extras::update_discord_rpc); // debugging tools - // make_function_symbol_from_c("alloc-vagdir-names", (void*)alloc_vagdir_names); + make_function_symbol_from_c("alloc-vagdir-names", (void*)kmachine_extras::alloc_vagdir_names); // external RPCs /* @@ -396,6 +396,45 @@ void InitMachine_PCPort() { (void*)pc_get_num_external_highscores); */ + // speedrunning stuff + make_function_symbol_from_c("pc-sr-mode-get-practice-entries-amount", + (void*)kmachine_extras::pc_sr_mode_get_practice_entries_amount); + make_function_symbol_from_c("pc-sr-mode-get-practice-entry-name", + (void*)kmachine_extras::pc_sr_mode_get_practice_entry_name); + make_function_symbol_from_c("pc-sr-mode-get-practice-entry-continue-point", + (void*)kmachine_extras::pc_sr_mode_get_practice_entry_continue_point); + make_function_symbol_from_c( + "pc-sr-mode-get-practice-entry-history-success", + (void*)kmachine_extras::pc_sr_mode_get_practice_entry_history_success); + make_function_symbol_from_c( + "pc-sr-mode-get-practice-entry-history-attempts", + (void*)kmachine_extras::pc_sr_mode_get_practice_entry_history_attempts); + make_function_symbol_from_c( + "pc-sr-mode-get-practice-entry-session-success", + (void*)kmachine_extras::pc_sr_mode_get_practice_entry_session_success); + make_function_symbol_from_c( + "pc-sr-mode-get-practice-entry-session-attempts", + (void*)kmachine_extras::pc_sr_mode_get_practice_entry_session_attempts); + make_function_symbol_from_c("pc-sr-mode-get-practice-entry-avg-time", + (void*)kmachine_extras::pc_sr_mode_get_practice_entry_avg_time); + make_function_symbol_from_c("pc-sr-mode-get-practice-entry-fastest-time", + (void*)kmachine_extras::pc_sr_mode_get_practice_entry_fastest_time); + make_function_symbol_from_c("pc-sr-mode-record-practice-entry-attempt!", + (void*)kmachine_extras::pc_sr_mode_record_practice_entry_attempt); + make_function_symbol_from_c("pc-sr-mode-init-practice-info!", + (void*)kmachine_extras::pc_sr_mode_init_practice_info); + make_function_symbol_from_c("pc-sr-mode-get-custom-category-amount", + (void*)kmachine_extras::pc_sr_mode_get_custom_category_amount); + make_function_symbol_from_c("pc-sr-mode-get-custom-category-name", + (void*)kmachine_extras::pc_sr_mode_get_custom_category_name); + make_function_symbol_from_c( + "pc-sr-mode-get-custom-category-continue-point", + (void*)kmachine_extras::pc_sr_mode_get_custom_category_continue_point); + make_function_symbol_from_c("pc-sr-mode-init-custom-category-info!", + (void*)kmachine_extras::pc_sr_mode_init_custom_category_info); + make_function_symbol_from_c("pc-sr-mode-dump-new-custom-category", + (void*)kmachine_extras::pc_sr_mode_dump_new_custom_category); + // setup string constants auto user_dir_path = file_util::get_user_config_dir(); intern_from_c(-1, 0, "*pc-user-dir-base-path*")->value() = diff --git a/game/kernel/jak3/kmachine_extras.cpp b/game/kernel/jak3/kmachine_extras.cpp index 035bb10454..55a4e32b20 100644 --- a/game/kernel/jak3/kmachine_extras.cpp +++ b/game/kernel/jak3/kmachine_extras.cpp @@ -12,9 +12,11 @@ #include "game/kernel/common/Symbol4.h" #include "game/kernel/common/kmachine.h" #include "game/kernel/common/kscheme.h" +#include "game/overlord/jak3/iso_cd.h" namespace jak3 { namespace kmachine_extras { +AutoSplitterBlock g_auto_splitter_block_jak3; void update_discord_rpc(u32 discord_info) { if (gDiscordRpcEnabled) { @@ -175,6 +177,46 @@ void pc_set_active_levels(u32 lev_list) { Gfx::GetCurrentRenderer()->set_active_levels(levels); } +static std::string unpack_vag_name_jak3(u64 compressed) { + const char* char_map = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-"; + u32 chars = compressed & 0x1fffff; + std::array buf{}; + buf.fill(0); + for (int i = 0; i < 8; i++) { + if (i == 4) { + chars = (compressed >> 21) & 0x1fffff; + } + buf[7 - i] = char_map[chars % 38]; + chars /= 38; + } + + return {buf.data()}; +} + +u32 alloc_vagdir_names(u32 heap_sym) { + auto alloced_heap = (Ptr)alloc_heap_memory(heap_sym, g_VagDir.num_entries * 8 + 8); + if (alloced_heap.offset) { + *alloced_heap = g_VagDir.num_entries; + // use entry -1 to get the amount + alloced_heap = alloced_heap + 8; + for (size_t i = 0; i < g_VagDir.num_entries; ++i) { + char vagname_temp[9]; + u64 packed = *(u64*)g_VagDir.entries[i].words; + auto name = unpack_vag_name_jak3(packed); + memcpy(vagname_temp, name.data(), 8); + for (int j = 0; j < 8; ++j) { + vagname_temp[j] = tolower(vagname_temp[j]); + } + vagname_temp[8] = 0; + u64 vagname_val; + memcpy(&vagname_val, vagname_temp, 8); + *(alloced_heap + i * 8) = vagname_val; + } + return alloced_heap.offset; + } + return s7.offset; +} + inline u64 bool_to_symbol(const bool val) { return val ? static_cast(s7.offset) + true_symbol_offset(g_game_version) : s7.offset; } @@ -183,11 +225,736 @@ inline bool symbol_to_bool(const u32 symptr) { return symptr != s7.offset; } -// TODO - move to common -void encode_utf8_string(u32 src_str_ptr, u32 str_dest_ptr) { - auto str = std::string(Ptr(src_str_ptr).c()->data()); - std::string converted = get_font_bank(GameTextVersion::JAK3)->convert_utf8_to_game(str); - strcpy(Ptr(str_dest_ptr).c()->data(), converted.c_str()); +void init_autosplit_struct() { + g_auto_splitter_block_jak3.pointer_to_symbol = + (u64)g_ee_main_mem + (u64)intern_from_c(-1, 0, "*autosplit-info-jak3*")->value(); +} + +// TODO - currently using a single mutex for all background task synchronization +std::mutex background_task_lock; + +std::string last_rpc_error; + +// TODO - add a TTL to this +std::unordered_map>> + external_speedrun_time_cache = {}; +std::unordered_map>> + external_race_time_cache = {}; +std::unordered_map>> + external_highscores_cache = {}; + +// clang-format off +// TODO - eventually don't depend on SRC +const std::unordered_map external_speedrun_lookup_urls = { + {"any", "https://www.speedrun.com/api/v1/leaderboards/nj1nww1p/category/9d8p1qkn?embed=players&max=200"}, + {"nooob", "https://www.speedrun.com/api/v1/leaderboards/nj1nww1p/category/5dwj0n0k?embed=players&max=200"}, + {"allmissions", "https://www.speedrun.com/api/v1/leaderboards/nj1nww1p/category/xd1r98k8?embed=players&max=200"}, + {"100", "https://www.speedrun.com/api/v1/leaderboards/nj1nww1p/category/zd30nndn?embed=players&max=200"}, + {"anyorbs", "https://www.speedrun.com/api/v1/leaderboards/nj1nww1p/category/jdzw79vd?embed=players&max=200"}, + {"anyhero", "https://www.speedrun.com/api/v1/leaderboards/nj1nww1p/category/9kvp50kg?embed=players&max=200"}}; +const std::unordered_map external_race_lookup_urls = { + {"time-trial", "https://www.speedrun.com/api/v1/leaderboards/nj1nww1p/level/kwjvyzwg/jdr8onk6?embed=players&max=200"}, + {"rally", "https://www.speedrun.com/api/v1/leaderboards/nj1nww1p/level/owo3kyw6/jdr8onk6?embed=players&max=200"}}; +const std::unordered_map external_highscores_lookup_urls = { + {"was-pre-game", "https://api.jakspeedruns.workers.dev/v1/highscores/9"}, + {"air-time", "https://api.jakspeedruns.workers.dev/v1/highscores/10"}, + {"total-air-time", "https://api.jakspeedruns.workers.dev/v1/highscores/11"}, + {"jump-distance", "https://api.jakspeedruns.workers.dev/v1/highscores/12"}, + {"total-jump-distance", "https://api.jakspeedruns.workers.dev/v1/highscores/13"}, + {"roll-count", "https://api.jakspeedruns.workers.dev/v1/highscores/14"}, + {"wascity-gungame", "https://api.jakspeedruns.workers.dev/v1/highscores/15"}, + {"jetboard", "https://api.jakspeedruns.workers.dev/v1/highscores/16"}, + {"gungame-yellow-2", "https://api.jakspeedruns.workers.dev/v1/highscores/17"}, + {"gungame-red-2", "https://api.jakspeedruns.workers.dev/v1/highscores/18"}, + {"gungame-ratchet", "https://api.jakspeedruns.workers.dev/v1/highscores/19"}, + {"gungame-clank", "https://api.jakspeedruns.workers.dev/v1/highscores/20"}, + {"power-game", "https://api.jakspeedruns.workers.dev/v1/highscores/21"}, + {"destroy-interceptors", "https://api.jakspeedruns.workers.dev/v1/highscores/22"}}; +// clang-format on + +void callback_fetch_external_speedrun_times(bool success, + const std::string& cache_id, + std::optional result) { + std::scoped_lock lock{background_task_lock}; + + if (!success) { + intern_from_c(-1, 0, "*pc-rpc-error?*")->value() = bool_to_symbol(true); + if (result) { + last_rpc_error = result.value(); + } else { + last_rpc_error = "Unexpected Error Occurred"; + } + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(false); + return; + } + + // TODO - might be nice to have an error if we get an unexpected payload + if (!result) { + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(false); + return; + } + + // Parse the response + const auto data = safe_parse_json(result.value()); + if (!data || !data->contains("data") || !data->at("data").contains("players") || + !data->at("data").at("players").contains("data") || !data->at("data").contains("runs")) { + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(false); + return; + } + + auto& players = data->at("data").at("players").at("data"); + auto& runs = data->at("data").at("runs"); + std::vector> times = {}; + for (const auto& run_info : runs) { + std::pair time_info; + if (players.size() > times.size() && players.at(times.size()).contains("names") && + players.at(times.size()).at("names").contains("international")) { + time_info.first = players.at(times.size()).at("names").at("international"); + } else if (players.size() > times.size() && players.at(times.size()).contains("name")) { + time_info.first = players.at(times.size()).at("name"); + } else { + time_info.first = "Unknown"; + } + if (run_info.contains("run") && run_info.at("run").contains("times") && + run_info.at("run").at("times").contains("primary_t")) { + time_info.second = run_info.at("run").at("times").at("primary_t"); + times.push_back(time_info); + } + } + external_speedrun_time_cache[cache_id] = times; + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(false); +} + +// TODO - duplicate code, put it in a function +void callback_fetch_external_race_times(bool success, + const std::string& cache_id, + std::optional result) { + std::scoped_lock lock{background_task_lock}; + + if (!success) { + intern_from_c(-1, 0, "*pc-rpc-error?*")->value() = bool_to_symbol(true); + if (result) { + last_rpc_error = result.value(); + } else { + last_rpc_error = "Unexpected Error Occurred"; + } + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(false); + return; + } + + // TODO - might be nice to have an error if we get an unexpected payload + if (!result) { + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(false); + return; + } + + // Parse the response + const auto data = safe_parse_json(result.value()); + if (!data || !data->contains("data") || !data->at("data").contains("players") || + !data->at("data").at("players").contains("data") || !data->at("data").contains("runs")) { + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(false); + return; + } + + auto& players = data->at("data").at("players").at("data"); + auto& runs = data->at("data").at("runs"); + std::vector> times = {}; + for (const auto& run_info : runs) { + std::pair time_info; + if (players.size() > times.size() && players.at(times.size()).contains("names") && + players.at(times.size()).at("names").contains("international")) { + time_info.first = players.at(times.size()).at("names").at("international"); + } else if (players.size() > times.size() && players.at(times.size()).contains("name")) { + time_info.first = players.at(times.size()).at("name"); + } else { + time_info.first = "Unknown"; + } + if (run_info.contains("run") && run_info.at("run").contains("times") && + run_info.at("run").at("times").contains("primary_t")) { + time_info.second = run_info.at("run").at("times").at("primary_t"); + times.push_back(time_info); + } + } + external_race_time_cache[cache_id] = times; + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(false); +} + +// TODO - duplicate code, put it in a function +void callback_fetch_external_highscores(bool success, + const std::string& cache_id, + std::optional result) { + std::scoped_lock lock{background_task_lock}; + + if (!success) { + intern_from_c(-1, 0, "*pc-rpc-error?*")->value() = bool_to_symbol(true); + if (result) { + last_rpc_error = result.value(); + } else { + last_rpc_error = "Unexpected Error Occurred"; + } + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(false); + return; + } + + // TODO - might be nice to have an error if we get an unexpected payload + if (!result) { + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(false); + return; + } + + // Parse the response + const auto data = safe_parse_json(result.value()); + std::vector> times = {}; + for (const auto& highscore_info : data.value()) { + if (highscore_info.contains("playerName") && highscore_info.contains("score")) { + std::pair time_info; + time_info.first = highscore_info.at("playerName"); + time_info.second = highscore_info.at("score"); + times.push_back(time_info); + } + } + external_highscores_cache[cache_id] = times; + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(false); +} + +void pc_fetch_external_speedrun_times(u32 speedrun_id_ptr) { + std::scoped_lock lock{background_task_lock}; + auto speedrun_id = std::string(Ptr(speedrun_id_ptr).c()->data()); + if (external_speedrun_lookup_urls.find(speedrun_id) == external_speedrun_lookup_urls.end()) { + lg::error("No URL for speedrun_id: '{}'", speedrun_id); + return; + } + + // First check to see if we've already retrieved this info + if (external_speedrun_time_cache.find(speedrun_id) == external_speedrun_time_cache.end()) { + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(true); + intern_from_c(-1, 0, "*pc-rpc-error?*")->value() = bool_to_symbol(false); + // otherwise, hit the URL + WebRequestJobPayload req; + req.callback = callback_fetch_external_speedrun_times; + req.url = external_speedrun_lookup_urls.at(speedrun_id); + req.cache_id = speedrun_id; + g_background_worker.enqueue_webrequest(req); + } +} + +void pc_fetch_external_race_times(u32 race_id_ptr) { + std::scoped_lock lock{background_task_lock}; + auto race_id = std::string(Ptr(race_id_ptr).c()->data()); + if (external_race_lookup_urls.find(race_id) == external_race_lookup_urls.end()) { + lg::error("No URL for race_id: '{}'", race_id); + return; + } + + // First check to see if we've already retrieved this info + if (external_race_time_cache.find(race_id) == external_race_time_cache.end()) { + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(true); + intern_from_c(-1, 0, "*pc-rpc-error?*")->value() = bool_to_symbol(false); + // otherwise, hit the URL + WebRequestJobPayload req; + req.callback = callback_fetch_external_race_times; + req.url = external_race_lookup_urls.at(race_id); + req.cache_id = race_id; + g_background_worker.enqueue_webrequest(req); + } +} + +void pc_fetch_external_highscores(u32 highscore_id_ptr) { + std::scoped_lock lock{background_task_lock}; + auto highscore_id = std::string(Ptr(highscore_id_ptr).c()->data()); + if (external_highscores_lookup_urls.find(highscore_id) == external_highscores_lookup_urls.end()) { + lg::error("No URL for highscore_id: '{}'", highscore_id); + return; + } + + // First check to see if we've already retrieved this info + if (external_highscores_cache.find(highscore_id) == external_highscores_cache.end()) { + intern_from_c(-1, 0, "*pc-waiting-on-rpc?*")->value() = bool_to_symbol(true); + intern_from_c(-1, 0, "*pc-rpc-error?*")->value() = bool_to_symbol(false); + // otherwise, hit the URL + WebRequestJobPayload req; + req.callback = callback_fetch_external_highscores; + req.url = external_highscores_lookup_urls.at(highscore_id); + req.cache_id = highscore_id; + g_background_worker.enqueue_webrequest(req); + } +} + +void pc_get_external_speedrun_time(u32 speedrun_id_ptr, + s32 index, + u32 name_dest_ptr, + u32 time_dest_ptr) { + std::scoped_lock lock{background_task_lock}; + auto speedrun_id = std::string(Ptr(speedrun_id_ptr).c()->data()); + if (external_speedrun_time_cache.find(speedrun_id) != external_speedrun_time_cache.end()) { + const auto& runs = external_speedrun_time_cache.at(speedrun_id); + if (index < (int)runs.size()) { + const auto& run_info = external_speedrun_time_cache.at(speedrun_id).at(index); + std::string converted = + get_font_bank(GameTextVersion::JAK3)->convert_utf8_to_game(run_info.first); + strcpy(Ptr(name_dest_ptr).c()->data(), converted.c_str()); + *(Ptr(time_dest_ptr).c()) = run_info.second; + } else { + std::string converted = get_font_bank(GameTextVersion::JAK3)->convert_utf8_to_game(""); + strcpy(Ptr(name_dest_ptr).c()->data(), converted.c_str()); + *(Ptr(time_dest_ptr).c()) = -1.0; + } + } +} + +void pc_get_external_race_time(u32 race_id_ptr, s32 index, u32 name_dest_ptr, u32 time_dest_ptr) { + std::scoped_lock lock{background_task_lock}; + auto race_id = std::string(Ptr(race_id_ptr).c()->data()); + if (external_race_time_cache.find(race_id) != external_race_time_cache.end()) { + const auto& runs = external_race_time_cache.at(race_id); + if (index < (int)runs.size()) { + const auto& run_info = external_race_time_cache.at(race_id).at(index); + std::string converted = + get_font_bank(GameTextVersion::JAK3)->convert_utf8_to_game(run_info.first); + strcpy(Ptr(name_dest_ptr).c()->data(), converted.c_str()); + *(Ptr(time_dest_ptr).c()) = run_info.second; + } else { + std::string converted = get_font_bank(GameTextVersion::JAK3)->convert_utf8_to_game(""); + strcpy(Ptr(name_dest_ptr).c()->data(), converted.c_str()); + *(Ptr(time_dest_ptr).c()) = -1.0; + } + } +} + +void pc_get_external_highscore(u32 highscore_id_ptr, + s32 index, + u32 name_dest_ptr, + u32 time_dest_ptr) { + std::scoped_lock lock{background_task_lock}; + auto highscore_id = std::string(Ptr(highscore_id_ptr).c()->data()); + if (external_highscores_cache.find(highscore_id) != external_highscores_cache.end()) { + const auto& runs = external_highscores_cache.at(highscore_id); + if (index < (int)runs.size()) { + const auto& run_info = external_highscores_cache.at(highscore_id).at(index); + std::string converted = + get_font_bank(GameTextVersion::JAK3)->convert_utf8_to_game(run_info.first); + strcpy(Ptr(name_dest_ptr).c()->data(), converted.c_str()); + *(Ptr(time_dest_ptr).c()) = run_info.second; + } else { + std::string converted = get_font_bank(GameTextVersion::JAK3)->convert_utf8_to_game(""); + strcpy(Ptr(name_dest_ptr).c()->data(), converted.c_str()); + *(Ptr(time_dest_ptr).c()) = -1.0; + } + } +} + +s32 pc_get_num_external_speedrun_times(u32 speedrun_id_ptr) { + std::scoped_lock lock{background_task_lock}; + auto speedrun_id = std::string(Ptr(speedrun_id_ptr).c()->data()); + if (external_speedrun_time_cache.find(speedrun_id) != external_speedrun_time_cache.end()) { + return external_speedrun_time_cache.at(speedrun_id).size(); + } + return 0; +} + +s32 pc_get_num_external_race_times(u32 race_id_ptr) { + std::scoped_lock lock{background_task_lock}; + auto race_id = std::string(Ptr(race_id_ptr).c()->data()); + if (external_race_time_cache.find(race_id) != external_race_time_cache.end()) { + return external_race_time_cache.at(race_id).size(); + } + return 0; +} + +s32 pc_get_num_external_highscores(u32 highscore_id_ptr) { + std::scoped_lock lock{background_task_lock}; + auto highscore_id = std::string(Ptr(highscore_id_ptr).c()->data()); + if (external_highscores_cache.find(highscore_id) != external_highscores_cache.end()) { + return external_highscores_cache.at(highscore_id).size(); + } + return 0; +} + +void to_json(json& j, const SpeedrunPracticeEntryHistoryAttempt& obj) { + if (obj.time) { + j["time"] = obj.time.value(); + } else { + j["time"] = nullptr; + } +} + +void from_json(const json& j, SpeedrunPracticeEntryHistoryAttempt& obj) { + if (j["time"].is_null()) { + obj.time = {}; + } else { + obj.time = j["time"]; + } +} + +void to_json(json& j, const SpeedrunPracticeEntry& obj) { + json_serialize(name); + json_serialize(continue_point_name); + json_serialize(flags); + json_serialize(completed_task); + json_serialize(features); + json_serialize(secrets); + json_serialize(vehicles); + json_serialize(starting_position); + json_serialize(starting_rotation); + json_serialize(starting_camera_position); + json_serialize(starting_camera_rotation); + json_serialize(start_zone_v1); + json_serialize(start_zone_v2); + json_serialize_optional(end_zone_v1); + json_serialize_optional(end_zone_v2); + json_serialize_optional(end_task); + json_serialize(history); +} + +void from_json(const json& j, SpeedrunPracticeEntry& obj) { + json_deserialize_if_exists(name); + json_deserialize_if_exists(continue_point_name); + json_deserialize_if_exists(flags); + json_deserialize_if_exists(completed_task); + json_deserialize_if_exists(features); + json_deserialize_if_exists(secrets); + json_deserialize_if_exists(vehicles); + json_deserialize_if_exists(starting_position); + json_deserialize_if_exists(starting_rotation); + json_deserialize_if_exists(starting_camera_position); + json_deserialize_if_exists(starting_camera_rotation); + json_deserialize_if_exists(start_zone_v1); + json_deserialize_if_exists(start_zone_v2); + json_deserialize_optional_if_exists(end_zone_v1); + json_deserialize_optional_if_exists(end_zone_v2); + json_deserialize_optional_if_exists(end_task); + json_deserialize_if_exists(history); +} + +void to_json(json& j, const SpeedrunCustomCategoryEntry& obj) { + json_serialize(name); + json_serialize(secrets); + json_serialize(features); + json_serialize(vehicles); + json_serialize(forbidden_features); + json_serialize(cheats); + json_serialize(continue_point_name); + json_serialize(completed_task); +} + +void from_json(const json& j, SpeedrunCustomCategoryEntry& obj) { + json_deserialize_if_exists(name); + json_deserialize_if_exists(secrets); + json_deserialize_if_exists(features); + json_deserialize_if_exists(vehicles); + json_deserialize_if_exists(forbidden_features); + json_deserialize_if_exists(cheats); + json_deserialize_if_exists(continue_point_name); + json_deserialize_if_exists(completed_task); +} + +std::vector g_speedrun_practice_entries; +std::unordered_map g_speedrun_practice_state; + +s32 pc_sr_mode_get_practice_entries_amount() { + // load practice entries from the file + const auto file_path = + file_util::get_user_features_dir(g_game_version) / "speedrun-practice.json"; + if (!file_util::file_exists(file_path.string())) { + lg::info("speedrun-practice.json not found, no entries to return!"); + return 0; + } + const auto file_contents = safe_parse_json(file_util::read_text_file(file_path)); + if (!file_contents) { + lg::error("speedrun-practice.json could not be parsed!"); + return 0; + } + + g_speedrun_practice_entries = *file_contents; + + for (size_t i = 0; i < g_speedrun_practice_entries.size(); i++) { + const auto& entry = g_speedrun_practice_entries.at(i); + s32 last_session_id = -1; + s32 total_attempts = 0; + s32 total_successes = 0; + s32 session_attempts = 0; + s32 session_successes = 0; + double total_time = 0; + float average_time = 0; + float fastest_time = 0; + for (const auto& [history_session, times] : entry.history) { + s32 session_id = stoi(history_session); + if (session_id > last_session_id) { + last_session_id = session_id; + } + for (const auto& time : times) { + total_attempts++; + if (time.time) { + total_successes++; + total_time += *time.time; + if (fastest_time == 0 || *time.time < fastest_time) { + fastest_time = *time.time; + } + } + } + } + if (total_successes != 0) { + average_time = total_time / total_successes; + } + g_speedrun_practice_state[i] = {last_session_id + 1, total_attempts, total_successes, + session_attempts, session_successes, total_time, + average_time, fastest_time}; + } + + return g_speedrun_practice_entries.size(); +} + +void pc_sr_mode_get_practice_entry_name(s32 entry_index, u32 name_str_ptr) { + std::string name; + if (entry_index < (int)g_speedrun_practice_entries.size()) { + name = g_speedrun_practice_entries.at(entry_index).name; + } + strcpy(Ptr(name_str_ptr).c()->data(), name.c_str()); +} + +void pc_sr_mode_get_practice_entry_continue_point(s32 entry_index, u32 name_str_ptr) { + std::string name; + if (entry_index < (int)g_speedrun_practice_entries.size()) { + name = g_speedrun_practice_entries.at(entry_index).continue_point_name; + } + strcpy(Ptr(name_str_ptr).c()->data(), name.c_str()); +} + +s32 pc_sr_mode_get_practice_entry_history_success(s32 entry_index) { + return g_speedrun_practice_state.at(entry_index).total_successes; +} + +s32 pc_sr_mode_get_practice_entry_history_attempts(s32 entry_index) { + return g_speedrun_practice_state.at(entry_index).total_attempts; +} + +s32 pc_sr_mode_get_practice_entry_session_success(s32 entry_index) { + return g_speedrun_practice_state.at(entry_index).session_successes; +} + +s32 pc_sr_mode_get_practice_entry_session_attempts(s32 entry_index) { + return g_speedrun_practice_state.at(entry_index).session_attempts; +} + +void pc_sr_mode_get_practice_entry_avg_time(s32 entry_index, u32 time_str_ptr) { + const auto time = fmt::format("{:.2f}", g_speedrun_practice_state.at(entry_index).average_time); + strcpy(Ptr(time_str_ptr).c()->data(), time.c_str()); +} + +void pc_sr_mode_get_practice_entry_fastest_time(s32 entry_index, u32 time_str_ptr) { + const auto time = fmt::format("{:.2f}", g_speedrun_practice_state.at(entry_index).fastest_time); + strcpy(Ptr(time_str_ptr).c()->data(), time.c_str()); +} + +u64 pc_sr_mode_record_practice_entry_attempt(s32 entry_index, u32 success_bool, u32 time_ptr) { + auto& state = g_speedrun_practice_state.at(entry_index); + const auto was_successful = symbol_to_bool(success_bool); + state.total_attempts++; + state.session_attempts++; + bool ret = false; + SpeedrunPracticeEntryHistoryAttempt new_history_entry; + if (was_successful) { + auto time = Ptr(time_ptr).c(); + new_history_entry.time = *time; + state.total_successes++; + state.session_successes++; + state.total_time += *time; + state.average_time = state.total_time / state.total_successes; + if (*time < state.fastest_time) { + state.fastest_time = *time; + ret = true; + } + } + // persist to file + const auto file_path = + file_util::get_user_features_dir(g_game_version) / "speedrun-practice.json"; + if (!file_util::file_exists(file_path.string())) { + lg::info("speedrun-practice.json not found, not persisting!"); + } else { + auto& history = g_speedrun_practice_entries.at(entry_index).history; + if (history.find(fmt::format("{}", state.current_session_id)) == history.end()) { + history[fmt::format("{}", state.current_session_id)] = {}; + } + history[fmt::format("{}", state.current_session_id)].push_back(new_history_entry); + json data = g_speedrun_practice_entries; + file_util::write_text_file(file_path, data.dump(2)); + } + // return + return bool_to_symbol(ret); +} + +void pc_sr_mode_init_practice_info(s32 entry_index, u32 speedrun_practice_obj_ptr) { + if (entry_index >= (int)g_speedrun_practice_entries.size()) { + return; + } + + auto objective = speedrun_practice_obj_ptr + ? Ptr(speedrun_practice_obj_ptr).c() + : NULL; + if (objective) { + const auto& json_info = g_speedrun_practice_entries.at(entry_index); + + objective->index = entry_index; + objective->flags = json_info.flags; + objective->completed_task = json_info.completed_task; + objective->features = json_info.features; + objective->vehicles = json_info.vehicles; + objective->secrets = json_info.secrets; + auto starting_position = + objective->starting_position ? Ptr(objective->starting_position).c() : NULL; + if (starting_position) { + for (int i = 0; i < 4; i++) { + starting_position->data[i] = json_info.starting_position.at(i) * METER_LENGTH; + } + } + auto starting_rotation = + objective->starting_rotation ? Ptr(objective->starting_rotation).c() : NULL; + if (starting_rotation) { + for (int i = 0; i < 4; i++) { + starting_rotation->data[i] = json_info.starting_rotation.at(i); + } + } + auto starting_camera_position = objective->starting_camera_position + ? Ptr(objective->starting_camera_position).c() + : NULL; + if (starting_camera_position) { + for (int i = 0; i < 4; i++) { + starting_camera_position->data[i] = json_info.starting_camera_position.at(i) * 4096.0; + } + } + auto starting_camera_rotation = objective->starting_camera_rotation + ? Ptr(objective->starting_camera_rotation).c() + : NULL; + if (starting_camera_rotation) { + for (int i = 0; i < 16; i++) { + starting_camera_rotation->data[i] = json_info.starting_camera_rotation.at(i); + } + } + + if (json_info.end_task) { + objective->end_task = *json_info.end_task; + } else { + objective->end_task = 0; + } + + auto starting_zone = objective->start_zone_init_params + ? Ptr(objective->start_zone_init_params).c() + : NULL; + if (starting_zone) { + starting_zone->v1[0] = json_info.start_zone_v1.at(0) * METER_LENGTH; + starting_zone->v1[1] = json_info.start_zone_v1.at(1) * METER_LENGTH; + starting_zone->v1[2] = json_info.start_zone_v1.at(2) * METER_LENGTH; + starting_zone->v1[3] = json_info.start_zone_v1.at(3) * METER_LENGTH; + starting_zone->v2[0] = json_info.start_zone_v2.at(0) * METER_LENGTH; + starting_zone->v2[1] = json_info.start_zone_v2.at(1) * METER_LENGTH; + starting_zone->v2[2] = json_info.start_zone_v2.at(2) * METER_LENGTH; + starting_zone->v2[3] = json_info.start_zone_v2.at(3) * METER_LENGTH; + } + + if (json_info.end_zone_v1 && json_info.end_zone_v2) { + auto ending_zone = objective->end_zone_init_params + ? Ptr(objective->end_zone_init_params).c() + : NULL; + if (ending_zone) { + ending_zone->v1[0] = json_info.end_zone_v1->at(0) * METER_LENGTH; + ending_zone->v1[1] = json_info.end_zone_v1->at(1) * METER_LENGTH; + ending_zone->v1[2] = json_info.end_zone_v1->at(2) * METER_LENGTH; + ending_zone->v1[3] = json_info.end_zone_v1->at(3) * METER_LENGTH; + ending_zone->v2[0] = json_info.end_zone_v2->at(0) * METER_LENGTH; + ending_zone->v2[1] = json_info.end_zone_v2->at(1) * METER_LENGTH; + ending_zone->v2[2] = json_info.end_zone_v2->at(2) * METER_LENGTH; + ending_zone->v2[3] = json_info.end_zone_v2->at(3) * METER_LENGTH; + } + } + } +} + +std::vector g_speedrun_custom_categories; + +s32 pc_sr_mode_get_custom_category_amount() { + // load practice entries from the file + const auto file_path = + file_util::get_user_features_dir(g_game_version) / "speedrun-categories.json"; + if (!file_util::file_exists(file_path.string())) { + lg::info("speedrun-categories.json not found, no entries to return!"); + return 0; + } + const auto file_contents = safe_parse_json(file_util::read_text_file(file_path)); + if (!file_contents) { + lg::error("speedrun-categories.json could not be parsed!"); + return 0; + } + + g_speedrun_custom_categories = *file_contents; + + return g_speedrun_custom_categories.size(); +} + +void pc_sr_mode_get_custom_category_name(s32 entry_index, u32 name_str_ptr) { + std::string name; + if (entry_index < (int)g_speedrun_custom_categories.size()) { + name = g_speedrun_custom_categories.at(entry_index).name; + } + strcpy(Ptr(name_str_ptr).c()->data(), name.c_str()); +} + +void pc_sr_mode_get_custom_category_continue_point(s32 entry_index, u32 name_str_ptr) { + std::string name; + if (entry_index < (int)g_speedrun_custom_categories.size()) { + name = g_speedrun_custom_categories.at(entry_index).continue_point_name; + } + strcpy(Ptr(name_str_ptr).c()->data(), name.c_str()); +} + +void pc_sr_mode_init_custom_category_info(s32 entry_index, u32 speedrun_custom_category_ptr) { + if (entry_index >= (int)g_speedrun_custom_categories.size()) { + return; + } + + auto category = speedrun_custom_category_ptr + ? Ptr(speedrun_custom_category_ptr).c() + : NULL; + if (category) { + const auto& json_info = g_speedrun_custom_categories.at(entry_index); + category->index = entry_index; + category->secrets = json_info.secrets; + category->features = json_info.features; + category->vehicles = json_info.vehicles; + category->forbidden_features = json_info.forbidden_features; + category->cheats = json_info.cheats; + category->completed_task = json_info.completed_task; + } +} + +void pc_sr_mode_dump_new_custom_category(u32 speedrun_custom_category_ptr) { + const auto file_path = + file_util::get_user_features_dir(g_game_version) / "speedrun-categories.json"; + if (file_util::file_exists(file_path.string())) { + // read current categories from file + const auto file_contents = safe_parse_json(file_util::read_text_file(file_path)); + if (file_contents) { + g_speedrun_custom_categories = *file_contents; + } + } + + auto category = speedrun_custom_category_ptr + ? Ptr(speedrun_custom_category_ptr).c() + : NULL; + if (category) { + SpeedrunCustomCategoryEntry new_category; + new_category.name = fmt::format("custom-category-{}", g_speedrun_custom_categories.size()); + new_category.secrets = category->secrets; + new_category.features = category->features; + new_category.vehicles = category->vehicles; + new_category.forbidden_features = category->forbidden_features; + new_category.cheats = category->cheats; + new_category.completed_task = category->completed_task; + new_category.continue_point_name = ""; + g_speedrun_custom_categories.push_back(new_category); + // convert to json and write file + json data = g_speedrun_custom_categories; + file_util::write_text_file(file_path, data.dump(2)); + } } } // namespace kmachine_extras diff --git a/game/kernel/jak3/kmachine_extras.h b/game/kernel/jak3/kmachine_extras.h index 71a84cf904..ebbbc9ce36 100644 --- a/game/kernel/jak3/kmachine_extras.h +++ b/game/kernel/jak3/kmachine_extras.h @@ -12,8 +12,47 @@ void pc_set_levels(u32 lev_list); void pc_set_active_levels(u32 lev_list); u32 alloc_vagdir_names(u32 heap_sym); inline u64 bool_to_symbol(const bool val); -// TODO - move to common -void encode_utf8_string(u32 src_str_ptr, u32 str_dest_ptr); +void init_autosplit_struct(); +void callback_fetch_external_speedrun_times(bool success, + const std::string& cache_id, + std::optional result); +void callback_fetch_external_race_times(bool success, + const std::string& cache_id, + std::optional result); +void callback_fetch_external_highscores(bool success, + const std::string& cache_id, + std::optional result); +void pc_fetch_external_speedrun_times(u32 speedrun_id_ptr); +void pc_fetch_external_race_times(u32 race_id_ptr); +void pc_fetch_external_highscores(u32 highscore_id_ptr); +void pc_get_external_speedrun_time(u32 speedrun_id_ptr, + s32 index, + u32 name_dest_ptr, + u32 time_dest_ptr); +void pc_get_external_race_time(u32 race_id_ptr, s32 index, u32 name_dest_ptr, u32 time_dest_ptr); +void pc_get_external_highscore(u32 highscore_id_ptr, + s32 index, + u32 name_dest_ptr, + u32 time_dest_ptr); +s32 pc_get_num_external_speedrun_times(u32 speedrun_id_ptr); +s32 pc_get_num_external_race_times(u32 race_id_ptr); +s32 pc_get_num_external_highscores(u32 highscore_id_ptr); +s32 pc_sr_mode_get_practice_entries_amount(); +void pc_sr_mode_get_practice_entry_name(s32 entry_index, u32 name_str_ptr); +void pc_sr_mode_get_practice_entry_continue_point(s32 entry_index, u32 name_str_ptr); +s32 pc_sr_mode_get_practice_entry_history_success(s32 entry_index); +s32 pc_sr_mode_get_practice_entry_history_attempts(s32 entry_index); +s32 pc_sr_mode_get_practice_entry_session_success(s32 entry_index); +s32 pc_sr_mode_get_practice_entry_session_attempts(s32 entry_index); +void pc_sr_mode_get_practice_entry_avg_time(s32 entry_index, u32 time_str_ptr); +void pc_sr_mode_get_practice_entry_fastest_time(s32 entry_index, u32 time_str_ptr); +u64 pc_sr_mode_record_practice_entry_attempt(s32 entry_index, u32 success_bool, u32 time); +void pc_sr_mode_init_practice_info(s32 entry_index, u32 speedrun_practice_obj_ptr); +s32 pc_sr_mode_get_custom_category_amount(); +void pc_sr_mode_get_custom_category_name(s32 entry_index, u32 name_str_ptr); +void pc_sr_mode_get_custom_category_continue_point(s32 entry_index, u32 name_str_ptr); +void pc_sr_mode_init_custom_category_info(s32 entry_index, u32 speedrun_custom_category_ptr); +void pc_sr_mode_dump_new_custom_category(u32 speedrun_custom_category_ptr); struct DiscordInfo { float orb_count; // float @@ -113,5 +152,110 @@ enum class FocusStatus : u64 { #define FOCUS_TEST(status, foc) (status.test(static_cast(foc))) +// To speed up finding the auto-splitter block in GOAL memory +// all this has is a marker for LiveSplit to find, and then the pointer +// to the symbol +struct AutoSplitterBlock { + const char marker[20] = "UnLiStEdStRaTs_JaK3"; + u64 pointer_to_symbol = 0; +}; + +extern AutoSplitterBlock g_auto_splitter_block_jak3; + +struct SpeedrunPracticeEntryHistoryAttempt { + std::optional time; +}; +void to_json(json& j, const SpeedrunPracticeEntryHistoryAttempt& obj); +void from_json(const json& j, SpeedrunPracticeEntryHistoryAttempt& obj); + +struct SpeedrunPracticeEntry { + std::string name; + std::string continue_point_name; + u64 flags; + u64 completed_task; + u64 features; + u64 secrets; + u64 vehicles; + std::vector starting_position; + std::vector starting_rotation; + std::vector starting_camera_position; + std::vector starting_camera_rotation; + std::vector start_zone_v1; + std::vector start_zone_v2; + std::optional> end_zone_v1; + std::optional> end_zone_v2; + std::optional end_task; + std::map> history; +}; +void to_json(json& j, const SpeedrunPracticeEntry& obj); +void from_json(const json& j, SpeedrunPracticeEntry& obj); + +struct SpeedrunPracticeState { + s32 current_session_id; + s32 total_attempts; + s32 total_successes; + s32 session_attempts; + s32 session_successes; + double total_time; + float average_time; + float fastest_time; +}; + +struct ObjectiveZoneInitParams { + float v1[4]; + float v2[4]; +}; + +struct Vector { + float data[4]; +}; + +struct Matrix { + float data[16]; +}; + +struct SpeedrunPracticeObjective { + s32 index; + u8 pad1[4]; + u64 flags; + u8 completed_task; + u8 pad2[7]; + u64 features; + u64 secrets; + u64 vehicles; + u32 starting_position; // Vector + u32 starting_rotation; // Vector + u32 starting_camera_position; // Vector + u32 starting_camera_rotation; // Matrix + u8 end_task; + u32 start_zone_init_params; // ObjectiveZoneInitParams + u32 start_zone; // irrelevant for cpp + u32 end_zone_init_params; // ObjectiveZoneInitParams + u32 end_zone; // irrelevant for cpp +}; + +struct SpeedrunCustomCategoryEntry { + std::string name; + u64 secrets; + u64 features; + u64 vehicles; + u64 forbidden_features; + u64 cheats; + std::string continue_point_name; + u64 completed_task; +}; +void to_json(json& j, const SpeedrunCustomCategoryEntry& obj); +void from_json(const json& j, SpeedrunCustomCategoryEntry& obj); + +struct SpeedrunCustomCategory { + s32 index; + u64 secrets; + u64 features; + u64 vehicles; + u64 forbidden_features; + u64 cheats; + u8 completed_task; +}; + } // namespace kmachine_extras } // namespace jak3 diff --git a/game/kernel/jak3/kscheme.cpp b/game/kernel/jak3/kscheme.cpp index 634d617ffb..7a9d7c1efa 100644 --- a/game/kernel/jak3/kscheme.cpp +++ b/game/kernel/jak3/kscheme.cpp @@ -1085,8 +1085,6 @@ u64 type_typep(Ptr t1, Ptr t2) { u64 method_set(u32 type_, u32 method_id, u32 method) { Ptr type(type_); - if (method_id > 255) - printf("[METHOD SET ERROR] tried to set method %d\n", method_id); auto existing_method = type->get_method(method_id).offset; diff --git a/game/kernel/jak3/kscheme.h b/game/kernel/jak3/kscheme.h index ef76389c4d..776a598555 100644 --- a/game/kernel/jak3/kscheme.h +++ b/game/kernel/jak3/kscheme.h @@ -60,6 +60,7 @@ Ptr intern_type_from_c(int a, int b, const char* name, u64 methods); u64 alloc_heap_object(u32 heap, u32 type, u32 size, u32 pp); int InitHeapAndSymbol(); u64 call_method_of_type_arg2(u32 arg, Ptr type, u32 method_id, u32 a1, u32 a2); +u64 alloc_heap_memory(u32 heap, u32 size); template Ptr> sym_to_string_ptr(Ptr> in) { return Ptr>(SymbolString.offset + in.offset - s7.offset); diff --git a/game/main.cpp b/game/main.cpp index 32e982783c..3322e468a3 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -179,10 +179,26 @@ int main(int argc, char** argv) { setup_cpu_info(); // If the CPU doesn't have AVX, GOAL code won't work and we exit. if (!get_cpu_info().has_avx) { +// Check if we are on a modern enough version of macOS so that AVX can be +// emulated via rosetta +#ifdef __APPLE__ + auto macos_version = get_macos_version(); + if (macos_version < 15.0) { + lg::info( + "Your CPU does not support AVX. But the newer version of Rosetta supports it, update to " + "atleast Sequoia to run OpenGOAL!"); + dialogs::create_error_message_dialog( + "Unmet Requirements", + "Your CPU does not support AVX. But the newer version of Rosetta supports it, update to " + "atleast Sequoia to run OpenGOAL!"); + return -1; + } +#else lg::info("Your CPU does not support AVX, which is required for OpenGOAL."); dialogs::create_error_message_dialog( "Unmet Requirements", "Your CPU does not support AVX, which is required for OpenGOAL."); return -1; +#endif } // set up file paths for resources. This is the full repository when developing, and the data diff --git a/game/mips2c/jak3_functions/foreground.cpp b/game/mips2c/jak3_functions/foreground.cpp index dca45f55f0..75aa5c610e 100644 --- a/game/mips2c/jak3_functions/foreground.cpp +++ b/game/mips2c/jak3_functions/foreground.cpp @@ -1544,6 +1544,11 @@ u64 execute(void* ctxt) { block_16: c->gprs[t0].du64[0] = 0; // or t0, r0, r0 // Unknown instr: ld t0, L217(fp) + // L217: + // .word 0x80808080 + // .word 0x0 + c->gprs[t0].du32[0] = 0x80808080; + c->gprs[t0].du32[1] = 0x0; c->dsll(t1, a3, 3); // dsll t1, a3, 3 c->daddu(t1, v1, t1); // daddu t1, v1, t1 c->sw(t0, 124, t1); // sw t0, 124(t1) diff --git a/game/mips2c/jak3_functions/shadow.cpp b/game/mips2c/jak3_functions/shadow.cpp index d64b773e5b..6638ae5ac8 100644 --- a/game/mips2c/jak3_functions/shadow.cpp +++ b/game/mips2c/jak3_functions/shadow.cpp @@ -219,7 +219,6 @@ namespace shadow_xform_verts { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; // nop // sll r0, r0, 0 c->lw(v1, 68, a1); // lw v1, 68(a1) // nop // sll r0, r0, 0 @@ -382,7 +381,6 @@ namespace shadow_calc_dual_verts { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; // nop // sll r0, r0, 0 c->lw(v1, 16, a1); // lw v1, 16(a1) // nop // sll r0, r0, 0 @@ -596,7 +594,6 @@ struct Cache { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; get_fake_spad_addr2(v1, cache.fake_scratchpad_data, 0, c);// lui v1, 28672 c->lw(a3, 44, a1); // lw a3, 44(a1) // nop // sll r0, r0, 0 @@ -687,7 +684,6 @@ namespace shadow_scissor_top { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; // nop // sll r0, r0, 0 c->lw(a2, 44, a1); // lw a2, 44(a1) // nop // sll r0, r0, 0 @@ -770,8 +766,6 @@ struct Cache { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; - bool bc = false; - u32 call_addr = 0; c->load_symbol2(v1, cache.math_camera); // lw v1, *math-camera*(s7) c->mov64(v1, v1); // or v1, v1, r0 c->lqc2(vf7, 364, v1); // lqc2 vf7, 364(v1) @@ -838,7 +832,6 @@ namespace shadow_find_facing_single_tris { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; c->daddiu(sp, sp, -64); // daddiu sp, sp, -64 c->sd(ra, 0, sp); // sd ra, 0(sp) c->sq(s4, 16, sp); // sq s4, 16(sp) @@ -1146,7 +1139,6 @@ namespace shadow_find_single_edges { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; c->lw(a2, 16, a1); // lw a2, 16(a1) c->lh(a3, 14, a0); // lh a3, 14(a0) c->mov64(v1, a2); // or v1, a2, r0 @@ -1250,7 +1242,6 @@ namespace shadow_find_facing_double_tris { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; c->daddiu(sp, sp, -16); // daddiu sp, sp, -16 c->sd(ra, 0, sp); // sd ra, 0(sp) c->lh(a2, 16, a0); // lh a2, 16(a0) @@ -1536,7 +1527,6 @@ namespace shadow_find_double_edges { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; c->lw(a2, 16, a1); // lw a2, 16(a1) c->lh(a3, 18, a0); // lh a3, 18(a0) c->mov64(v1, a2); // or v1, a2, r0 @@ -1650,7 +1640,6 @@ struct Cache { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; c->load_symbol2(v1, cache.shadow_data); // lw v1, *shadow-data*(s7) c->mov64(v1, v1); // or v1, v1, r0 c->lh(a0, 8, a0); // lh a0, 8(a0) @@ -1841,7 +1830,6 @@ struct Cache { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; c->load_symbol2(v1, cache.shadow_data); // lw v1, *shadow-data*(s7) c->mov64(a3, v1); // or a3, v1, r0 c->lw(v1, 20, a1); // lw v1, 20(a1) @@ -1924,7 +1912,6 @@ struct Cache { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; c->load_symbol2(v1, cache.shadow_data); // lw v1, *shadow-data*(s7) c->mov64(a3, v1); // or a3, v1, r0 c->lw(v1, 24, a1); // lw v1, 24(a1) @@ -2011,7 +1998,6 @@ struct Cache { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; c->load_symbol2(v1, cache.shadow_data); // lw v1, *shadow-data*(s7) c->mov64(a3, v1); // or a3, v1, r0 c->lh(a1, 12, a0); // lh a1, 12(a0) @@ -2094,7 +2080,6 @@ struct Cache { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; c->load_symbol2(v1, cache.shadow_data); // lw v1, *shadow-data*(s7) c->mov64(a3, v1); // or a3, v1, r0 c->lh(v1, 16, a0); // lh v1, 16(a0) @@ -2175,7 +2160,6 @@ struct Cache { u64 execute(void* ctxt) { auto* c = (ExecutionContext*)ctxt; bool bc = false; - u32 call_addr = 0; c->load_symbol2(v1, cache.shadow_data); // lw v1, *shadow-data*(s7) c->mov64(a3, v1); // or a3, v1, r0 c->lw(v1, 28, a1); // lw v1, 28(a1) diff --git a/game/overlord/common/ssound.cpp b/game/overlord/common/ssound.cpp index 7f4532907e..77bfbd7642 100644 --- a/game/overlord/common/ssound.cpp +++ b/game/overlord/common/ssound.cpp @@ -7,7 +7,8 @@ s32 gMusicFade = 0; s32 gSema; -Sound gSounds[64]; +constexpr int kNumSounds = 64; +Sound gSounds[kNumSounds]; Vec3w gEarTrans[2]; Vec3w gCamTrans; s32 gMusicFadeDir = 0; @@ -15,6 +16,7 @@ Curve gCurves[16]; s32 gCamAngle; u8 gMirrorMode = 0; u32 sLastTick = 0; +s64 gAddIndex = 0; static s32 sqrt_table[256] = { 0, 4096, 5793, 7094, 8192, 9159, 10033, 10837, 11585, 12288, 12953, 13585, 14189, @@ -56,6 +58,7 @@ static s32 atan_table[257] = { void ssound_init_globals() { gMusicFade = 0; gSema = 0; + gAddIndex = 0; } Sound* LookupSound(s32 id) { @@ -268,9 +271,66 @@ void UpdateVolume(Sound* sound) { } } -Sound* AllocateSound() { +void RemoveOldSounds() { + int unique_sounds = 0; + struct Entry { + u32 id; + u32 count; + Sound* info; + }; + Entry entries[kNumSounds]; + Entry* best_entry = nullptr; + + for (auto& sound : gSounds) { + if (sound.id) { + Entry* existing_entry = nullptr; + u32 uid = snd_GetSoundID(sound.sound_handle); + + // look for entry: + for (int i = 0; i < unique_sounds; i++) { + if (entries[i].id == uid) { + existing_entry = &entries[i]; + break; + } + } + + // if none found, create + if (!existing_entry) { + existing_entry = &entries[unique_sounds]; + unique_sounds++; + existing_entry->id = uid; + existing_entry->count = 0; + existing_entry->info = &sound; + } + + // update + existing_entry->count++; + // pick oldest sound + if (sound.add_index < existing_entry->info->add_index) { + existing_entry->info = &sound; + } + + // se if we're best + if (!best_entry) { + best_entry = existing_entry; + } else { + if (best_entry->count < existing_entry->count) { + best_entry = existing_entry; + } + } + } + } + + if (best_entry) { + snd_StopSound(best_entry->info->sound_handle); + best_entry->info->id = 0; + } +} + +Sound* AllocateSound(bool remove_old_sounds) { for (auto& s : gSounds) { if (s.id == 0) { + s.add_index = gAddIndex++; return &s; } } @@ -278,10 +338,21 @@ Sound* AllocateSound() { CleanSounds(); for (auto& s : gSounds) { if (s.id == 0) { + s.add_index = gAddIndex++; return &s; } } + if (remove_old_sounds) { + RemoveOldSounds(); + for (auto& s : gSounds) { + if (s.id == 0) { + s.add_index = gAddIndex++; + return &s; + } + } + } + return nullptr; } diff --git a/game/overlord/common/ssound.h b/game/overlord/common/ssound.h index 4732779f95..edb1664de4 100644 --- a/game/overlord/common/ssound.h +++ b/game/overlord/common/ssound.h @@ -41,6 +41,8 @@ struct Sound { s32 auto_time; SoundParams params; SoundRecord* bank_entry; + + s64 add_index = 0; }; struct Curve { @@ -61,7 +63,7 @@ extern u32 sLastTick; void ssound_init_globals(); Sound* LookupSound(s32 id); -Sound* AllocateSound(); +Sound* AllocateSound(bool remove_old_sounds); s32 GetVolume(Sound* sound); void UpdateVolume(Sound* sound); s32 CalculateFalloffVolume(Vec3w* pos, s32 volume, s32 fo_curve, s32 fo_min, s32 fo_max); diff --git a/game/overlord/jak1/srpc.cpp b/game/overlord/jak1/srpc.cpp index a52bc63cc7..6b14a5e757 100644 --- a/game/overlord/jak1/srpc.cpp +++ b/game/overlord/jak1/srpc.cpp @@ -93,7 +93,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) { if (!PollSema(gSema)) { if (gMusic) { if (!gMusicPause && !LookupSound(666)) { - Sound* music = AllocateSound(); + Sound* music = AllocateSound(false); if (music != nullptr) { gMusicFade = 0; gMusicFadeDir = 1; @@ -183,7 +183,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) { break; } - sound = AllocateSound(); + sound = AllocateSound(false); if (!sound) { break; } diff --git a/game/overlord/jak2/srpc.cpp b/game/overlord/jak2/srpc.cpp index 5991b511a1..fd9547416f 100644 --- a/game/overlord/jak2/srpc.cpp +++ b/game/overlord/jak2/srpc.cpp @@ -40,7 +40,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) { if (!PollSema(gSema)) { if (gMusic) { if (!gMusicPause && !LookupSound(666)) { - Sound* music = AllocateSound(); + Sound* music = AllocateSound(true); if (music != nullptr) { gMusicFade = 0; gMusicFadeDir = 1; @@ -117,7 +117,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) { } else { // new sound - sound = AllocateSound(); + sound = AllocateSound(true); if (sound == nullptr) { // no free sounds break; diff --git a/game/overlord/jak3/iso.cpp b/game/overlord/jak3/iso.cpp index 6ba18eb2f4..e9aacb4fa5 100644 --- a/game/overlord/jak3/iso.cpp +++ b/game/overlord/jak3/iso.cpp @@ -1738,7 +1738,7 @@ EIsoStatus CopyData(ISO_LoadCommon* cmd, CopyKind kind) { snd_BankLoadFromIOPPartialEx(buffer->m_pCurrentData, len, bank_info->m_nSpuMemLoc, bank_info->m_nSpuMemSize); if (cmd->progress_bytes + len == cmd->length_to_copy) { - snd_BankLoadFromIOPPartialEx_Completion(); + bank_info->snd_handle = snd_BankLoadFromIOPPartialEx_Completion(); snd_ResolveBankXREFS(); // TODO: this also set field_0x28... is that needed?? } diff --git a/game/overlord/jak3/rpc_interface.h b/game/overlord/jak3/rpc_interface.h index 4b2d4d49aa..e13a31c409 100644 --- a/game/overlord/jak3/rpc_interface.h +++ b/game/overlord/jak3/rpc_interface.h @@ -157,7 +157,7 @@ enum class SoundCommand : u16 { SET_REVERB = 23, SET_EAR_TRANS = 24, SHUTDOWN = 25, - // LIST_SOUNDS = 26, + LIST_SOUNDS = 26, UNLOAD_MUSIC = 27, SET_FPS = 28, // BOOT_LOAD = 29, diff --git a/game/overlord/jak3/sbank.cpp b/game/overlord/jak3/sbank.cpp index dbbf3e9896..442a255072 100644 --- a/game/overlord/jak3/sbank.cpp +++ b/game/overlord/jak3/sbank.cpp @@ -26,6 +26,15 @@ void jak3_overlord_init_globals_sbank() { gBanks[7] = &gLevel2hBank; } +// added +void PrintBanks() { + printf("Loaded Banks\n"); + for (int i = 0; i < kNumBanks; i++) { + printf(" [%d] %s %s (%d/%d)\n", i, gBanks[i]->m_name1, gBanks[i]->m_name2, gBanks[i]->in_use, + gBanks[i]->loaded); + } +} + void InitBanks() { for (int i = 0; i < kNumBanks; i++) { auto* bank = gBanks[i]; diff --git a/game/overlord/jak3/sbank.h b/game/overlord/jak3/sbank.h index 6882e78950..44e527c36e 100644 --- a/game/overlord/jak3/sbank.h +++ b/game/overlord/jak3/sbank.h @@ -25,5 +25,6 @@ void jak3_overlord_init_globals_sbank(); void InitBanks(); SoundBankInfo* LookupBank(const char* name); SoundBankInfo* AllocateBankName(const char* name, u32 mode); +void PrintBanks(); extern SoundBankInfo* gBanks[8]; } // namespace jak3 \ No newline at end of file diff --git a/game/overlord/jak3/srpc.cpp b/game/overlord/jak3/srpc.cpp index 3df21824d4..9a9253acf0 100644 --- a/game/overlord/jak3/srpc.cpp +++ b/game/overlord/jak3/srpc.cpp @@ -578,6 +578,12 @@ void* RPC_Loader(unsigned int, void* msg, int size) { } } break; + // added + case SoundCommand::LIST_SOUNDS: { + PrintBanks(); + PrintSounds(); + } break; + default: ovrld_log(LogCategory::WARN, "[RPC Loader] Unsupported Loader {}", (int)((const Rpc_Player_Base_Cmd*)m_ptr)->command); diff --git a/game/overlord/jak3/ssound.cpp b/game/overlord/jak3/ssound.cpp index b1f21aef0e..8891c30e5d 100644 --- a/game/overlord/jak3/ssound.cpp +++ b/game/overlord/jak3/ssound.cpp @@ -245,6 +245,13 @@ void InitSound() { InitVagStreamList(&g_NewStreamsList, 4, "new"); } +void PrintSounds() { + for (auto& sound : gSounds) { + printf("SOUND %d %s\n", sound.id, sound.name.data); + printf(" still playing? %d\n", snd_SoundIsStillPlaying(sound.sound_handle)); + } +} + SoundInfo* LookupSound(int id) { if (id == 0) { return nullptr; diff --git a/game/overlord/jak3/ssound.h b/game/overlord/jak3/ssound.h index 420fd65ac2..e6b4ca2cc0 100644 --- a/game/overlord/jak3/ssound.h +++ b/game/overlord/jak3/ssound.h @@ -43,6 +43,7 @@ void SetPlaybackMode(s32 mode); void SetCurve(int curve_idx, u32, u32, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t); u32 CalculateFalloffVolume(s32* trans, u32 vol, u32 fo_curve, u32 fo_min, u32 fo_max, u32*, u32*); s32 CalculateAngle(s32* trans, u32 fo_curve, u32); +void PrintSounds(); extern u32 g_anStreamVoice[6]; extern VolumePair g_aPanTable[361]; diff --git a/game/sound/sndshim.cpp b/game/sound/sndshim.cpp index c52f2e2f83..15185956a3 100644 --- a/game/sound/sndshim.cpp +++ b/game/sound/sndshim.cpp @@ -241,11 +241,12 @@ void snd_BankLoadFromIOPPartialEx_Start() { void snd_BankLoadFromIOPPartialEx(const u8* data, u32 length, u32 spu_mem_loc, u32 spu_mem_size) { sbk_data.insert(sbk_data.end(), data, data + length); } -void snd_BankLoadFromIOPPartialEx_Completion() { +snd::BankHandle snd_BankLoadFromIOPPartialEx_Completion() { ASSERT(started); started = false; - player->LoadBank(std::span(sbk_data)); + auto ret = player->LoadBank(std::span(sbk_data)); sbk_data.clear(); + return ret; } s32 snd_GetVoiceStatus(s32 voice) { diff --git a/game/sound/sndshim.h b/game/sound/sndshim.h index bb0f07e5f1..3de1eea2b1 100644 --- a/game/sound/sndshim.h +++ b/game/sound/sndshim.h @@ -73,7 +73,7 @@ snd::BankHandle snd_BankLoadEx(const char* filepath, void snd_BankLoadFromIOPPartialEx_Start(); void snd_BankLoadFromIOPPartialEx(const u8* data, u32 length, u32 spu_mem_loc, u32 spu_mem_size); -void snd_BankLoadFromIOPPartialEx_Completion(); +snd::BankHandle snd_BankLoadFromIOPPartialEx_Completion(); s32 snd_GetVoiceStatus(s32 voice); s32 snd_GetFreeSPUDMA(); diff --git a/game/system/hid/display_manager.cpp b/game/system/hid/display_manager.cpp index cef01758ec..f74a2c26bf 100644 --- a/game/system/hid/display_manager.cpp +++ b/game/system/hid/display_manager.cpp @@ -179,8 +179,17 @@ int DisplayManager::get_screen_height() { return 480; } -Resolution DisplayManager::get_resolution(int id) { - if (id < (int)m_available_resolutions.size()) { +int DisplayManager::get_num_resolutions(bool for_window_size) { + if (for_window_size) { + return m_available_window_sizes.size(); + } + return m_available_resolutions.size(); +} + +Resolution DisplayManager::get_resolution(int id, bool for_window_size) { + if (for_window_size && id < (int)m_available_window_sizes.size()) { + return m_available_window_sizes.at(id); + } else if (id < (int)m_available_resolutions.size()) { return m_available_resolutions.at(id); } return {0, 0, 0.0}; @@ -380,6 +389,8 @@ void DisplayManager::update_resolutions() { fmt::format("unable to get display mode for display {}, index {}", active_display_id, i)); continue; } + Resolution new_res = {curr_mode.w, curr_mode.h, + static_cast(curr_mode.w) / static_cast(curr_mode.h)}; // Skip resolutions that aren't using the current refresh rate, they won't work. // For example if your monitor is currently set to `60hz` and the monitor _could_ support // resolution X but only at `30hz`...then there's no reason for us to consider it as an option. @@ -387,12 +398,13 @@ void DisplayManager::update_resolutions() { lg::debug( "[DISPLAY]: Skipping {}x{} as it requires {}hz but the monitor is currently set to {}hz", curr_mode.w, curr_mode.h, curr_mode.refresh_rate, active_refresh_rate); + // Allow it for windowed mode though + m_available_window_sizes.push_back(new_res); continue; } - Resolution new_res = {curr_mode.w, curr_mode.h, - static_cast(curr_mode.w) / static_cast(curr_mode.h)}; lg::info("[DISPLAY]: {}x{} is supported", new_res.width, new_res.height); m_available_resolutions.push_back(new_res); + m_available_window_sizes.push_back(new_res); } // Sort by area @@ -400,11 +412,22 @@ void DisplayManager::update_resolutions() { [](const Resolution& a, const Resolution& b) -> bool { return a.width * a.height > b.width * b.height; }); + std::sort(m_available_window_sizes.begin(), m_available_window_sizes.end(), + [](const Resolution& a, const Resolution& b) -> bool { + return a.width * a.height > b.width * b.height; + }); // Remove duplicate resolutions - auto last = std::unique(m_available_resolutions.begin(), m_available_resolutions.end(), - [](const Resolution& a, const Resolution& b) -> bool { - return (a.width == b.width && a.height == b.height); - }); - m_available_resolutions.erase(last, m_available_resolutions.end()); + m_available_resolutions.erase( + std::unique(m_available_resolutions.begin(), m_available_resolutions.end(), + [](const Resolution& a, const Resolution& b) -> bool { + return (a.width == b.width && a.height == b.height); + }), + m_available_resolutions.end()); + m_available_window_sizes.erase( + std::unique(m_available_window_sizes.begin(), m_available_window_sizes.end(), + [](const Resolution& a, const Resolution& b) -> bool { + return (a.width == b.width && a.height == b.height); + }), + m_available_window_sizes.end()); } diff --git a/game/system/hid/display_manager.h b/game/system/hid/display_manager.h index 23f0c3c82c..fa5118723e 100644 --- a/game/system/hid/display_manager.h +++ b/game/system/hid/display_manager.h @@ -80,8 +80,8 @@ class DisplayManager { game_settings::DisplaySettings::DisplayMode get_display_mode() { return m_display_settings.display_mode; } - int get_num_resolutions() { return m_available_resolutions.size(); } - Resolution get_resolution(int id); + int get_num_resolutions(bool for_window_size); + Resolution get_resolution(int id, bool for_window_size); bool is_supported_resolution(int width, int height); // Mutators @@ -123,6 +123,7 @@ class DisplayManager { // ie. allowing someone to set 150fps on a monitor set to 60hz is not correct std::unordered_map m_current_display_modes; std::vector m_available_resolutions; + std::vector m_available_window_sizes; void initialize_window_position_from_settings(); void update_curr_display_info(); diff --git a/game/tools/subtitle_editor/subtitle_editor.cpp b/game/tools/subtitle_editor/subtitle_editor.cpp index 687bebdb4b..c500c28be1 100644 --- a/game/tools/subtitle_editor/subtitle_editor.cpp +++ b/game/tools/subtitle_editor/subtitle_editor.cpp @@ -402,6 +402,10 @@ void SubtitleEditor::draw_subtitle_options(GameSubtitleSceneInfo& scene, bool cu } else { bool play = false; bool save_and_reload_text = false; + if (ImGui::Button("Save")) { + save_and_reload_text = true; + } + ImGui::SameLine(); if (ImGui::Button("Play")) { play = true; } @@ -410,11 +414,11 @@ void SubtitleEditor::draw_subtitle_options(GameSubtitleSceneInfo& scene, bool cu play = true; save_and_reload_text = true; } + if (save_and_reload_text) { + m_subtitle_db.write_subtitle_db_to_files(g_game_version); + m_repl.rebuild_text(); + } if (play) { - if (save_and_reload_text) { - m_subtitle_db.write_subtitle_db_to_files(g_game_version); - m_repl.rebuild_text(); - } if (g_game_version == GameVersion::Jak1) { m_jak1_editor_db.update(); if (scene.is_cutscene) { diff --git a/goal_src/jak1/engine/anim/joint.gc b/goal_src/jak1/engine/anim/joint.gc index 71d216530d..92ced4858d 100644 --- a/goal_src/jak1/engine/anim/joint.gc +++ b/goal_src/jak1/engine/anim/joint.gc @@ -693,8 +693,12 @@ ((not (file-info-correct-version? (-> this info) (file-kind art-group) 0)) (the-as art-group #f)) (else (let ((s5-1 (-> *level* loading-level))) - (if (or (not s5-1) (= (-> s5-1 name) 'default)) + (when (or (not s5-1) (= (-> s5-1 name) 'default)) (login this) ;; not part of level load, just normal login. + (when (needs-link? this) + (format 0 "bonus link~%") + (link-art! this) + ) ) (if s5-1 (set-loaded-art (-> s5-1 art-group) this) ;; part of level load, add to level's ag, but don't log in yet. diff --git a/goal_src/jak1/engine/camera/cam-layout.gc b/goal_src/jak1/engine/camera/cam-layout.gc index 0153b4e0a5..e2bedad6cf 100644 --- a/goal_src/jak1/engine/camera/cam-layout.gc +++ b/goal_src/jak1/engine/camera/cam-layout.gc @@ -556,7 +556,7 @@ (if (cpad-hold? arg2 r1) (set! (-> arg1 y) (+ 0.5 - (analog-input (the-as int (-> *cpad-list* cpads arg2 abutton 9)) + (analog-input (the-as int (-> *cpad-list* cpads arg2 abutton (abutton-idx r1))) ;; og:preserve-this abutton indexing (the-as float 0.0) (the-as float 32.0) (the-as float 230.0) @@ -567,7 +567,7 @@ (set! (-> arg1 y) (- (-> arg1 y) (+ 0.5 - (analog-input (the-as int (-> *cpad-list* cpads arg2 abutton 8)) + (analog-input (the-as int (-> *cpad-list* cpads arg2 abutton (abutton-idx l1))) ;; og:preserve-this abutton indexing (the-as float 0.0) (the-as float 32.0) (the-as float 230.0) diff --git a/goal_src/jak1/engine/camera/cam-states-dbg.gc b/goal_src/jak1/engine/camera/cam-states-dbg.gc index 34071eb3a2..3ee90c81ef 100644 --- a/goal_src/jak1/engine/camera/cam-states-dbg.gc +++ b/goal_src/jak1/engine/camera/cam-states-dbg.gc @@ -72,35 +72,59 @@ (set! (-> arg0 x) (- (-> arg0 x) (+ (-> *CAM_FREE-bank* rot-speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 6)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* rot-speed))))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx x))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (-> *CAM_FREE-bank* rot-speed))))))) (when *camera-read-buttons* (if (cpad-hold? arg3 triangle) (+! (-> arg0 x) (+ (-> *CAM_FREE-bank* rot-speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 4)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* rot-speed)))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx triangle))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (-> *CAM_FREE-bank* rot-speed)))))) (when *camera-read-buttons* (if (cpad-hold? arg3 square) (+! (-> arg0 y) (+ (-> *CAM_FREE-bank* rot-speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 7)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* rot-speed)))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx square))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (-> *CAM_FREE-bank* rot-speed)))))) (when *camera-read-buttons* (if (cpad-hold? arg3 circle) (set! (-> arg0 y) (- (-> arg0 y) (+ (-> *CAM_FREE-bank* rot-speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 5)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* rot-speed)))))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx circle))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (-> *CAM_FREE-bank* rot-speed)))))))) (when arg2 (when *camera-read-buttons* (if (cpad-hold? arg3 l2) (+! (-> arg0 z) (+ (-> *CAM_FREE-bank* rot-speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 10)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* rot-speed)))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx l2))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (-> *CAM_FREE-bank* rot-speed)))))) (when *camera-read-buttons* (if (cpad-hold? arg3 r2) (set! (-> arg0 z) (- (-> arg0 z) (+ (-> *CAM_FREE-bank* rot-speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 11)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* rot-speed)))))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx r2))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (-> *CAM_FREE-bank* rot-speed)))))))) (cond ((not *cam-free-move-along-z*)) ((not *camera-read-analog*)) @@ -109,48 +133,80 @@ (if (cpad-hold? arg3 r1) (+! (-> arg1 y) (+ (* 0.2 (-> *CAM_FREE-bank* speed)) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 9)) 0.0 32.0 230.0 (* 0.2 (-> *CAM_FREE-bank* speed))))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx r1))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (* 0.2 (-> *CAM_FREE-bank* speed))))))) (when *camera-read-buttons* (if (cpad-hold? arg3 l1) (set! (-> arg1 y) (- (-> arg1 y) (+ (* 0.2 (-> *CAM_FREE-bank* speed)) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 8)) 0.0 32.0 230.0 (* 0.2 (-> *CAM_FREE-bank* speed))))))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx l1))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (* 0.2 (-> *CAM_FREE-bank* speed))))))))) (else (when *camera-read-buttons* (if (cpad-hold? arg3 r1) (+! (-> arg1 y) (+ (-> *CAM_FREE-bank* speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 9)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx r1))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (-> *CAM_FREE-bank* speed)))))) (when *camera-read-buttons* (if (cpad-hold? arg3 l1) (set! (-> arg1 y) (- (-> arg1 y) (+ (-> *CAM_FREE-bank* speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 8)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed))))))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx l1))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (-> *CAM_FREE-bank* speed))))))))) (when (and (!= *master-mode* 'menu) (not *cam-layout*)) (when *camera-read-buttons* (if (cpad-hold? arg3 left) (+! (-> arg1 x) (+ (-> *CAM_FREE-bank* speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 1)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx left))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (-> *CAM_FREE-bank* speed)))))) (when *camera-read-buttons* (if (cpad-hold? arg3 right) (set! (-> arg1 x) (- (-> arg1 x) (+ (-> *CAM_FREE-bank* speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 0)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed))))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx right))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (-> *CAM_FREE-bank* speed))))))) (when *camera-read-buttons* (if (cpad-hold? arg3 up) (+! (-> arg1 z) (+ (-> *CAM_FREE-bank* speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 2)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx up))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (-> *CAM_FREE-bank* speed)))))) (when *camera-read-buttons* (if (cpad-hold? arg3 down) (set! (-> arg1 z) (- (-> arg1 z) (+ (-> *CAM_FREE-bank* speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 3)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)))))))) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx down))) ;; og:preserve-this abutton indexing + 0.0 + 32.0 + 230.0 + (-> *CAM_FREE-bank* speed)))))))) (when *camera-read-analog* (let ((f28-14 (analog-input (the-as int (-> *cpad-list* cpads arg3 leftx)) 128.0 48.0 110.0 -1.0)) (f30-14 (analog-input (the-as int (-> *cpad-list* cpads arg3 lefty)) 128.0 48.0 110.0 -1.0)) diff --git a/goal_src/jak1/engine/common-obs/crates.gc b/goal_src/jak1/engine/common-obs/crates.gc index a41cbf0ceb..a3ca881f16 100644 --- a/goal_src/jak1/engine/common-obs/crates.gc +++ b/goal_src/jak1/engine/common-obs/crates.gc @@ -61,6 +61,7 @@ (COLLIDE_RADIUS float) (DARKECO_EXPLODE_RADIUS float))) + (define *CRATE-bank* (new 'static 'crate-bank :COLLIDE_YOFF 4096.0 :COLLIDE_RADIUS 4915.2 :DARKECO_EXPLODE_RADIUS 16384.0)) @@ -87,6 +88,7 @@ (check-dead (_type_) none) (smush-update! (_type_) none))) + (method-set! crate 12 (method-of-type process run-logic?)) (defbehavior crate-post crate () @@ -635,7 +637,7 @@ (not arg0))) (logior! (-> self fact options) (fact-options instant-collect))) (when (not arg0) - (let ((s5-1 (current-time))) (until (time-elapsed? s5-1 (seconds 0.04)) (suspend))) + (suspend-for (seconds 0.04)) (logior! (-> self draw status) (draw-status hidden)) (case (-> self look) (('iron) (sound-play "icrate-break")) @@ -702,7 +704,7 @@ (drop-pickup (-> self fact) #t *entity-pool* (the-as fact-info #f) arg1) (process-entity-status! self (entity-perm-status dead) #t) (process-entity-status! self (entity-perm-status complete) #t) - (let ((gp-1 (current-time))) (until (time-elapsed? gp-1 (seconds 5)) (suspend))))) + (suspend-for (seconds 5)))) (defstate special-contents-die (crate) :virtual #t @@ -868,6 +870,7 @@ (deftype barrel (crate) ()) + (defmethod params-init ((this barrel) (arg0 entity)) (let ((t9-0 (method-of-type crate params-init))) (t9-0 this arg0)) (set! (-> this look) 'barrel) @@ -875,6 +878,7 @@ (deftype bucket (crate) ()) + (defmethod params-init ((this bucket) (arg0 entity)) (let ((t9-0 (method-of-type crate params-init))) (t9-0 this arg0)) (set! (-> this look) 'bucket) @@ -912,6 +916,7 @@ (deftype crate-buzzer (crate) ()) + (defmethod art-init ((this crate-buzzer)) (let ((t9-0 (method-of-type crate art-init))) (t9-0 this)) (set! (-> this part) (create-launch-control (-> *part-group-id-table* 74) this)) @@ -969,6 +974,7 @@ (deftype pickup-spawner (crate) ((blocker entity-actor))) + (defmethod params-init ((this pickup-spawner) (arg0 entity)) (let ((t9-0 (method-of-type crate params-init))) (t9-0 this arg0)) (set! (-> this look) 'none) diff --git a/goal_src/jak1/engine/common-obs/generic-obs.gc b/goal_src/jak1/engine/common-obs/generic-obs.gc index 4069830869..fff7c6ae8e 100644 --- a/goal_src/jak1/engine/common-obs/generic-obs.gc +++ b/goal_src/jak1/engine/common-obs/generic-obs.gc @@ -96,7 +96,7 @@ (suspend) (while (and *target* (= (handle->process (-> *target* control unknown-handle10)) self)) (suspend)) - (let ((gp-0 (current-time))) (until (time-elapsed? gp-0 (seconds 0.5)) (suspend))) + (suspend-for (seconds 0.5)) (go swingpole-stance))) (defmethod init-from-entity! ((this swingpole) (arg0 entity-actor)) @@ -127,8 +127,10 @@ (deftype target-start (process-hidden) ()) + (deftype camera-start (process-hidden) ()) + (defstate manipy-idle (manipy) :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block)) @@ -365,10 +367,7 @@ (vector+! (-> self root trans) (-> (the-as process-drawable gp-0) root trans) (-> self offset))))) (let ((gp-1 (-> self root trans))) (if (-> self callback) ((-> self callback) self)) (spawn (-> self part) gp-1)) (suspend)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (-> self linger-duration)) - (if (-> self linger-callback) ((-> self linger-callback) self)) - (suspend))) + (suspend-for (-> self linger-duration) (if (-> self linger-callback) ((-> self linger-callback) self))) (if (-> self linger-callback) ((-> self linger-callback) self)) (part-tracker-notify) (suspend) @@ -551,11 +550,7 @@ (set! s2-1 (cdr s2-1)) (set! a1-5 (car s2-1))))))) (('not) (set! gp-0 (not (eval this (the-as pair (car s4-0)))))) - (('wait-for 'wait 'suspend) - (let ((s5-1 (command-get-time (car s4-0) 1)) - (s4-1 (current-time))) - (until (time-elapsed? s4-1 s5-1) - (suspend)))) + (('wait-for 'wait 'suspend) (let ((s5-1 (command-get-time (car s4-0) 1))) (suspend-for s5-1))) (('message?) (when (= (-> this message) (car s4-0)) (set! gp-0 (-> this message)) (set! (-> this message) #f))) (('send-event) (let ((s5-2 (command-get-process (car s4-0) *target*)) @@ -688,6 +683,7 @@ (:states med-res-level-idle)) + (defstate med-res-level-idle (med-res-level) :code (behavior () @@ -836,6 +832,7 @@ launcher-deactivated launcher-idle)) + (defpartgroup group-beach-launcher :id 37 :bounds (static-bspherem 0 3 0 5) diff --git a/goal_src/jak1/engine/common-obs/linear-plat.gc b/goal_src/jak1/engine/common-obs/linear-plat.gc new file mode 100644 index 0000000000..7050fc62ab --- /dev/null +++ b/goal_src/jak1/engine/common-obs/linear-plat.gc @@ -0,0 +1,126 @@ +;;-*-Lisp-*- +(in-package goal) +(bundles "GAME.CGO") +(require "engine/common-obs/generic-obs.gc") +(require "engine/geometry/path.gc") +(require "engine/util/sync-info.gc") +(require "engine/common-obs/plat.gc") + +#| custom platform for complex animations + + define path array of vector4m as usual, probably you want first and last positions to be the same + "path": ["vector4m", + [0.0, 50.0, 10.0, 1.0], + [0.0, 50.0, 10.0, 1.0], + [0.0, 60.0, 10.0, 1.0], + [0.0, 50.0, 10.0, 1.0], + [0.0, 50.0, 10.0, 1.0], + [0.0, 60.0, 10.0, 1.0], + [0.0, 50.0, 10.0, 1.0] + ], + + define timings array, which says how long in seconds it should take to transition between path positions + "timings": ["float", + 0.0, // offset before starting + 2.0, // down to up (out) + 2.0, // up to down (out) + 6.0, // stay down + 2.0, // down to up (back) + 2.0, // up to down (back) + 0.0 // immediately start back up + ], + + define sync with proper period (duration of the whole path). offset is ignored + "sync": ["float", 14, 0.0] +|# +(deftype linear-plat (plat) + ((timings float 64))) ;; inline array of floats + +(defun get-current-phase-linear-plat ((this linear-plat)) + (let* ((cur-time (mod (the-as uint (current-time)) (-> this sync period))) + (pos 0)) + (while (< pos (-> this path curve num-cverts)) + (let ((timing (fsec (-> this timings pos)))) + (when (< cur-time timing) + ;; we should be between pos and pos+1 + (return (+ (the float pos) (/ (the float cur-time) (the float timing))))) + + ;; we are at least at next position + (+! pos 1) + (-! cur-time timing)))) + 0.0 ;; default + ) + +(defun eval-linear-path! ((path path-control) (basetrans vector) (path-pos float)) + (let* ((pos0 (the int path-pos)) + (pos1 (if (>= (+ pos0 1) (-> path curve num-cverts)) 0 (+ pos0 1))) + (partial (- path-pos pos0)) + (dir (new-stack-vector0))) + ;; vector from pos0 to pos1 + (vector-! dir (-> path curve cverts pos1) (-> path curve cverts pos0)) + ;; partial vector based on path-pos decimal + (vector-float*! dir dir partial) + ;; update basetrans + (vector+! basetrans (-> path curve cverts pos0) dir) + ) + ) + +(defstate plat-path-active (linear-plat) + :virtual #t + :event plat-event + :exit + (behavior () + (sound-stop (-> self sound-id))) + :trans + (behavior () + (set! (-> self path-pos) + (get-current-phase-linear-plat self)) + (eval-linear-path! (-> self path) (-> self basetrans) (-> self path-pos)) + (if (< (vector-vector-distance (-> self root trans) (ear-trans)) 81920.0) + (sound-play "eco-plat-hover" :id (-> self sound-id) :position (the-as symbol (-> self root trans)))) + (plat-trans)) + :code + (the-as (function plat object) + anim-loop) + :post plat-post) + +(defmethod init-from-entity! ((this linear-plat) (arg0 entity-actor)) + (logior! (-> this mask) (process-mask platform)) + (baseplat-method-24 this) + (process-drawable-from-entity! this arg0) + (initialize-skeleton this (get-unlit-skel this) '()) + (logior! (-> this skel status) (janim-status inited)) + (update-transforms! (-> this root)) + (baseplat-method-21 this) + (baseplat-method-25 this) + (load-params! (-> this sync) this (the-as uint 0) 0.0 0.15 0.15) + (set! (-> this fact) (new 'process 'fact-info this (pickup-type eco-pill-random) (-> *FACT-bank* default-pill-inc))) + (set! (-> this path) (new 'process 'curve-control this 'path -1000000000.0)) + + ;; read path timing data from res-lump + ;; look up the curve data + (let* ((tag (new 'static 'res-tag)) + (data (res-lump-data arg0 'timings pointer :tag-ptr (& tag) :time -1000000000.0))) + (when data + ;; success, we got some data + (dotimes (idx (-> this path curve num-cverts)) + (set! (-> this timings idx) (-> (the-as (pointer float) data) idx))))) + + (logior! (-> this path flags) (path-control-flag display draw-line draw-point draw-text)) + (set! (-> this sound-id) (new-sound-id)) + (cond + ((logtest? (-> this path flags) (path-control-flag not-found)) + (set! (-> this path-pos) 0.0) + (let ((a0-14 this)) (baseplat-method-26 a0-14) (go (method-of-object this plat-startup) a0-14))) + ((> (-> this sync period) 0) + (set! (-> this path-pos) + (if (logtest? (-> this fact options) (fact-options wrap-phase)) + (get-current-phase (-> this sync)) + (get-current-phase-with-mirror (-> this sync)))) + (eval-path-curve! (-> this path) (-> this root trans) (-> this path-pos) 'interp) + (let ((a0-18 this)) (baseplat-method-26 a0-18) (go (method-of-object this plat-startup) a0-18))) + (else + (set! (-> this path-pos) 0.0) + (eval-path-curve! (-> this path) (-> this root trans) (-> this path-pos) 'interp) + (let ((a0-20 this)) (baseplat-method-26 a0-20) (go (method-of-object this plat-startup) a0-20)))) + (none)) diff --git a/goal_src/jak1/engine/common-obs/nav-enemy.gc b/goal_src/jak1/engine/common-obs/nav-enemy.gc index 5d3f7b7012..440d53fce2 100644 --- a/goal_src/jak1/engine/common-obs/nav-enemy.gc +++ b/goal_src/jak1/engine/common-obs/nav-enemy.gc @@ -35,11 +35,11 @@ (+! (-> result y) (* 0.5 time time (-> this gravity))) result) -(defmethod relocate ((this nav-enemy) (arg0 int)) - (if (nonzero? (-> this neck)) (set! (-> this neck) (the-as joint-mod (+ (the-as int (-> this neck)) arg0)))) +(defmethod relocate ((this nav-enemy) (offset int)) + (if (nonzero? (-> this neck)) (set! (-> this neck) (the-as joint-mod (+ (the-as int (-> this neck)) offset)))) (if (nonzero? (-> this rand-gen)) - (set! (-> this rand-gen) (the-as random-generator (+ (the-as int (-> this rand-gen)) arg0)))) - (call-parent-method this arg0)) + (set! (-> this rand-gen) (the-as random-generator (+ (the-as int (-> this rand-gen)) offset)))) + (call-parent-method this offset)) (defmethod new-patrol-point! ((this nav-enemy)) (local-vars (v1-11 symbol)) @@ -1060,11 +1060,7 @@ nav-enemy-default-event-handler (ja :num! (loop! f30-0))) (ja-channel-push! 1 (seconds 0.1)) (nav-enemy-turn-to-face-point (-> self event-param-point) 910.2222) - (let ((gp-0 (nav-enemy-rnd-int-range 0 150)) - (s5-0 (current-time))) - (until (time-elapsed? s5-0 gp-0) - (ja :num! (loop! f30-0)) - (suspend)))) + (let ((gp-0 (nav-enemy-rnd-int-range 0 150))) (suspend-for gp-0 (ja :num! (loop! f30-0))))) (go-virtual nav-enemy-jump-to-point)) :post nav-enemy-simple-post) diff --git a/goal_src/jak1/engine/common-obs/water-anim.gc b/goal_src/jak1/engine/common-obs/water-anim.gc index ec0fd32abf..5397ebfc38 100644 --- a/goal_src/jak1/engine/common-obs/water-anim.gc +++ b/goal_src/jak1/engine/common-obs/water-anim.gc @@ -353,6 +353,57 @@ (anim int32) (ambient-sound-spec sound-spec))) +;; og:preserve-this added +(defenum water-look + (water-anim-sunken-big-room 0) + (water-anim-sunken-first-room-from-entrance 1) + (water-anim-sunken-qbert-room 2) + (water-anim-sunken-first-right-branch 3) + (water-anim-sunken-circular-with-bullys 4) + (water-anim-sunken-hall-with-one-whirlpool 5) + (water-anim-sunken-hall-with-three-whirlpools 6) + (water-anim-sunken-start-of-helix-slide 7) + (water-anim-sunken-room-above-exit-chamber 8) + (water-anim-sunken-hall-before-big-room 9) + (water-anim-sunken-dark-eco-qbert 10) + (water-anim-sunken-short-piece 11) + (water-anim-sunken-big-room-upper-water 12) + (water-anim-sunken-dark-eco-platform-room 13) + (water-anim-maincave-water-with-crystal 14) + (water-anim-maincave-center-pool 15) + (water-anim-maincave-lower-right-pool 16) + (water-anim-maincave-mid-right-pool 17) + (water-anim-maincave-lower-left-pool 18) + (water-anim-maincave-mid-left-pool 19) + (water-anim-robocave-main-pool 20) + (water-anim-misty-mud-by-arena 21) + (water-anim-misty-mud-above-skeleton 22) + (water-anim-misty-mud-behind-skeleton 23) + (water-anim-misty-mud-above-skull-back 24) + (water-anim-misty-mud-above-skull-front 25) + (water-anim-misty-mud-other-near-skull 26) + (water-anim-misty-mud-near-skull 27) + (water-anim-misty-mud-under-spine 28) + (water-anim-misty-mud-by-dock 29) + (water-anim-misty-mud-island-near-dock 30) + (water-anim-misty-mud-lonely-island 31) + (water-anim-misty-dark-eco-pool 32) + (water-anim-ogre-lava 33) + (water-anim-jungle-river 34) + (water-anim-village3-lava 35) + (water-anim-training-lake 36) + (water-anim-darkcave-water-with-crystal 37) + (water-anim-rolling-water-back 38) + (water-anim-rolling-water-front 39) + (water-anim-sunken-dark-eco-helix-room 40) + (water-anim-finalboss-dark-eco-pool 41) + (water-anim-lavatube-energy-lava 42) + (water-anim-village1-rice-paddy 43) + (water-anim-village1-fountain 44) + (water-anim-village1-rice-paddy-mid 45) + (water-anim-village1-rice-paddy-top 46) + (water-anim-village2-bucket 47)) + (define *water-anim-look* (new 'static 'boxed-array diff --git a/goal_src/jak1/engine/debug/default-menu.gc b/goal_src/jak1/engine/debug/default-menu.gc index 9f9e34f00c..8de974620c 100644 --- a/goal_src/jak1/engine/debug/default-menu.gc +++ b/goal_src/jak1/engine/debug/default-menu.gc @@ -2403,6 +2403,7 @@ (debug-menu-append-item s5-0 (debug-menu-make-from-template arg0 '(menu "Display" + (flag "Input Display" *show-input-display* dm-boolean-toggle-pick-func) (flag "Profile" *display-profile* dm-boolean-toggle-pick-func) (flag "Ticks" *profile-ticks* dm-boolean-toggle-pick-func) (flag "File Info" *display-file-info* dm-boolean-toggle-pick-func) @@ -2533,6 +2534,7 @@ (menu "Mode" (function "normal" #f ,(lambda () (send-event *target* 'end-mode))) (function "racing" #f ,(lambda () (send-event *target* 'change-mode 'racing #f))) + (function "flut" #f ,(lambda () (send-event *target* 'change-mode 'flut #f))) (function "snowball" #f ,(lambda () (send-event *target* 'change-mode 'snowball #f)))) (flag "Slow Frame Rate" *slow-frame-rate* dm-boolean-toggle-pick-func) (function "Print Pos" diff --git a/goal_src/jak1/engine/entity/ambient.gc b/goal_src/jak1/engine/entity/ambient.gc index 355b248e7a..e374dc8bda 100644 --- a/goal_src/jak1/engine/entity/ambient.gc +++ b/goal_src/jak1/engine/entity/ambient.gc @@ -11,21 +11,21 @@ ;; DECOMP BEGINS -(defmethod mem-usage ((this drawable-ambient) (arg0 memory-usage-block) (arg1 int)) - (set! (-> arg0 length) (max 50 (-> arg0 length))) - (set! (-> arg0 data 49 name) "ambient") - (+! (-> arg0 data 49 count) 1) - (let ((v1-6 (asize-of this))) (+! (-> arg0 data 49 used) v1-6) (+! (-> arg0 data 49 total) (logand -16 (+ v1-6 15)))) - (mem-usage (-> this ambient) arg0 (logior arg1 128)) +(defmethod mem-usage ((this drawable-ambient) (usage memory-usage-block) (flags int)) + (set! (-> usage length) (max 50 (-> usage length))) + (set! (-> usage data 49 name) "ambient") + (+! (-> usage data 49 count) 1) + (let ((v1-6 (asize-of this))) (+! (-> usage data 49 used) v1-6) (+! (-> usage data 49 total) (logand -16 (+ v1-6 15)))) + (mem-usage (-> this ambient) usage (logior flags 128)) (the-as drawable-ambient 0)) -(defmethod mem-usage ((this drawable-inline-array-ambient) (arg0 memory-usage-block) (arg1 int)) - (set! (-> arg0 length) (max 1 (-> arg0 length))) - (set! (-> arg0 data 0 name) (symbol->string 'drawable-group)) - (+! (-> arg0 data 0 count) 1) - (let ((v1-7 32)) (+! (-> arg0 data 0 used) v1-7) (+! (-> arg0 data 0 total) (logand -16 (+ v1-7 15)))) +(defmethod mem-usage ((this drawable-inline-array-ambient) (usage memory-usage-block) (flags int)) + (set! (-> usage length) (max 1 (-> usage length))) + (set! (-> usage data 0 name) (symbol->string 'drawable-group)) + (+! (-> usage data 0 count) 1) + (let ((v1-7 32)) (+! (-> usage data 0 used) v1-7) (+! (-> usage data 0 total) (logand -16 (+ v1-7 15)))) (dotimes (s3-0 (-> this length)) - (mem-usage (-> this data s3-0) arg0 arg1)) + (mem-usage (-> this data s3-0) usage flags)) (the-as drawable-inline-array-ambient 0)) (define *hint-semaphore* (the-as (pointer level-hint) #f)) @@ -368,15 +368,13 @@ :code (behavior ((arg0 string) (arg1 string)) (remove-setting! 'hint) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 (seconds 1)) - (when (and *debug-segment* (not (paused?)) (not (str-is-playing?)) (bottom-hud-hidden?)) - (let ((s3-0 (new 'stack 'font-context *font-default-matrix* 56 160 0.0 (font-color default) (font-flags shadow kerning)))) - (let ((v1-7 s3-0)) (set! (-> v1-7 width) (the float 400))) - (let ((v1-8 s3-0)) (set! (-> v1-8 height) (the float 96))) - (set! (-> s3-0 flags) (font-flags shadow kerning middle)) - (let ((s2-0 print-game-text)) (format (clear *temp-string*) "~S~S" arg0 arg1) (s2-0 *temp-string* s3-0 #f 128 22)))) - (suspend))) + (suspend-for (seconds 1) + (when (and *debug-segment* (not (paused?)) (not (str-is-playing?)) (bottom-hud-hidden?)) + (let ((s3-0 (new 'stack 'font-context *font-default-matrix* 56 160 0.0 (font-color default) (font-flags shadow kerning)))) + (let ((v1-7 s3-0)) (set! (-> v1-7 width) (the float 400))) + (let ((v1-8 s3-0)) (set! (-> v1-8 height) (the float 96))) + (set! (-> s3-0 flags) (font-flags shadow kerning middle)) + (let ((s2-0 print-game-text)) (format (clear *temp-string*) "~S~S" arg0 arg1) (s2-0 *temp-string* s3-0 #f 128 22))))) (go level-hint-exit))) (defstate level-hint-exit (level-hint) diff --git a/goal_src/jak1/engine/entity/entity.gc b/goal_src/jak1/engine/entity/entity.gc index 3ea0f27174..6942b78766 100644 --- a/goal_src/jak1/engine/entity/entity.gc +++ b/goal_src/jak1/engine/entity/entity.gc @@ -828,36 +828,55 @@ (defun custom-nav-mesh-check-and-setup ((this entity-actor)) (case (-> this aid) ((40000) ;; test-babak - (set! (-> this nav-mesh) - (new 'static 'nav-mesh - :custom-hacky? #t ;; Our hack. This will neutralize the function that caused trouble. - :origin (new 'static 'vector :x (meters -7.2681) :y (meters 1.0468) :z (meters 16.3255) :w 1.0000) ;; Location of the navmesh. - :bounds (new 'static 'sphere :x (meters -7.2681) :y (meters 1.0468) :z (meters 16.3255) :w (meters 20.0)) ;; Some kind of boundary. It should cover the whole navmesh. Enemies won't go to parts it doesn't cover. - :vertex-count 4 ;; If this is missing, then debug drawing of the vertexes will not be possible. - :vertex (new 'static 'inline-array nav-vertex 4 ;; The vertexes, we can use these to form our triangles. - (new 'static 'nav-vertex :x (meters 5.8046) :y (meters 0.1945) :z (meters 6.6462) :w 1.0000) ;; All coordinates are relative to the origin of the navmesh... - (new 'static 'nav-vertex :x (meters 5.5363) :y (meters 0.4561) :z (meters -6.1448) :w 1.0000) ;; ...which is good news for us, we can easily copy navmeshes and just change the origin (and bounds). - (new 'static 'nav-vertex :x (meters -4.8047) :y (meters -0.1945) :z (meters -6.6463) :w 1.0000) - (new 'static 'nav-vertex :x (meters -4.5910) :y (meters -0.5481) :z (meters 6.0990) :w 1.0000) - ) - :poly-count 2 ;; For some weird reason, you need to define this, otherwise it will think that there are 0 polys. Even though it could just tell from the array below... - :poly (new 'static 'inline-array nav-poly 2 ;; Here we define our polygons (only triangles). - (new 'static 'nav-poly - :id #x0 ;; It needs a unique ID, because we need to refer to it at some places. It is possible that this gets assigned automatically if you don't write it here. But it is better to have it here for clarity. - :vertex (new 'static 'array uint8 3 #x0 #x1 #x3) ;; You pick your 3 vertexes here, from among the ones we defined earlier. You need to pick them in an okay order. Because of the normals. Logs will warn you if it is wrong. - :adj-poly (new 'static 'array uint8 3 #xff #x1 #xff) ;; You can (or should) define any adjecent triangles here. I am sure this is important. The order may or may not matter - I tried to respect the order here. - ;;:pat 0 ;; This is 0 by default. The so called "gap triangles" have it set to 1. But to get gap triangles working properly, you need proper route data. Which we have in existing navmeshes, but not in fully custom ones. - ) - (new 'static 'nav-poly - :id #x1 - :vertex (new 'static 'array uint8 3 #x1 #x2 #x3) - :adj-poly (new 'static 'array uint8 3 #xff #xff #x0) - ) - ) - ;; Optional. I don't understand this. It might impact enemy behaviour/movement on the navmesh, but not sure how. Even the smallest navmesh has at least one of these. - ;; Commenting it out, but leaving it here because it may be useful for something. - ;; Also I probably have redundancy among the properties (for example I am not sure if radius-x is needed if we have radius, and vice-versa). - #|:nodes (new 'static 'inline-array nav-node 1 + (set! (-> this nav-mesh) + (new 'static + 'nav-mesh + :custom-hacky? #t + ;; Our hack. This will neutralize the function that caused trouble. + :origin + (new 'static 'vector :x (meters -7.2681) :y (meters 1.0468) :z (meters 16.3255) :w 1.0000) ;; Location of the navmesh. + :bounds + (new 'static 'sphere :x (meters -7.2681) :y (meters 1.0468) :z (meters 16.3255) :w (meters 20.0)) ;; Some kind of boundary. It should cover the whole navmesh. Enemies won't go to parts it doesn't cover. + :vertex-count 4 + ;; If this is missing, then debug drawing of the vertexes will not be possible. + :vertex + (new 'static + 'inline-array + nav-vertex + 4 ;; The vertexes, we can use these to form our triangles. + (new 'static 'nav-vertex :x (meters 5.8046) :y (meters 0.1945) :z (meters 6.6462) :w 1.0000) ;; All coordinates are relative to the origin of the navmesh... + (new 'static 'nav-vertex :x (meters 5.5363) :y (meters 0.4561) :z (meters -6.1448) :w 1.0000) ;; ...which is good news for us, we can easily copy navmeshes and just change the origin (and bounds). + (new 'static 'nav-vertex :x (meters -4.8047) :y (meters -0.1945) :z (meters -6.6463) :w 1.0000) + (new 'static 'nav-vertex :x (meters -4.5910) :y (meters -0.5481) :z (meters 6.0990) :w 1.0000)) + :poly-count 2 + ;; For some weird reason, you need to define this, otherwise it will think that there are 0 polys. Even though it could just tell from the array below... + :poly + (new 'static + 'inline-array + nav-poly + 2 ;; Here we define our polygons (only triangles). + (new 'static + 'nav-poly + :id #x0 + ;; It needs a unique ID, because we need to refer to it at some places. It is possible that this gets assigned automatically if you don't write it here. But it is better to have it here for clarity. + :vertex + (new 'static 'array uint8 3 #x0 #x1 #x3) ;; You pick your 3 vertexes here, from among the ones we defined earlier. You need to pick them in an okay order. Because of the normals. Logs will warn you if it is wrong. + :adj-poly + (new 'static 'array uint8 3 #xff #x1 #xff) ;; You can (or should) define any adjecent triangles here. I am sure this is important. The order may or may not matter - I tried to respect the order here. + ;;:pat 0 ;; This is 0 by default. The so called "gap triangles" have it set to 1. But to get gap triangles working properly, you need proper route data. Which we have in existing navmeshes, but not in fully custom ones. + ) + (new 'static + 'nav-poly + :id #x1 + :vertex + (new 'static 'array uint8 3 #x1 #x2 #x3) + :adj-poly + (new 'static 'array uint8 3 #xff #xff #x0))) + ;; Optional. I don't understand this. It might impact enemy behaviour/movement on the navmesh, but not sure how. Even the smallest navmesh has at least one of these. + ;; Commenting it out, but leaving it here because it may be useful for something. + ;; Also I probably have redundancy among the properties (for example I am not sure if radius-x is needed if we have radius, and vice-versa). + #| +:nodes (new 'static 'inline-array nav-node 1 (new 'static 'nav-node :center-x (meters 0.4020) :center-y (meters -0.2929) :center-z (meters -0.0592) :type 1 :parent-offset 0 @@ -874,22 +893,22 @@ :scale (new 'static 'vector :x (meters 30.1309) :y 0.0000 :z (meters 3.1157) :w 0.0000) :first-tris (new 'static 'array uint8 4 #x0 #x1 #x0 #x0) :last-tris (new 'static 'array uint8 4 #x0 #x0 #x0 #x0)) - )|# - ;; Route is essential (game crashes without it), Not sure how it works exactly. Also not sure how to determine the array length. Seems to be poly-count*2? - ;; It is needed if you want the gap triangles to work. But it seems gibberish even in existing navmeshes. Maybe the type is wrong? - ;; The simplest navmeshese have this exact same route data as seen below, so I am using it in our example. - :route (new 'static 'inline-array vector4ub 4 - (new 'static 'vector4ub :data (new 'static 'array uint8 4 #xff #x0 #x0 #x0)) - (new 'static 'vector4ub :data (new 'static 'array uint8 4 #x0 #x0 #x0 #x0)) - (new 'static 'vector4ub :data (new 'static 'array uint8 4 #x0 #x0 #x0 #x0)) - (new 'static 'vector4ub :data (new 'static 'array uint8 4 #x0 #x0 #x0 #x0)) ) - ) - ) - (entity-nav-login this) ;; I don't need to know what this does, all I know is that this is needed - the navmesh won't be okay without it. - ) - ) -) + |# + ;; Route is essential (game crashes without it), Not sure how it works exactly. Also not sure how to determine the array length. Seems to be poly-count*2? + ;; It is needed if you want the gap triangles to work. But it seems gibberish even in existing navmeshes. Maybe the type is wrong? + ;; The simplest navmeshese have this exact same route data as seen below, so I am using it in our example. + :route + (new 'static + 'inline-array + vector4ub + 4 + (new 'static 'vector4ub :data (new 'static 'array uint8 4 #xff #x0 #x0 #x0)) + (new 'static 'vector4ub :data (new 'static 'array uint8 4 #x0 #x0 #x0 #x0)) + (new 'static 'vector4ub :data (new 'static 'array uint8 4 #x0 #x0 #x0 #x0)) + (new 'static 'vector4ub :data (new 'static 'array uint8 4 #x0 #x0 #x0 #x0))))) + (entity-nav-login this) ;; I don't need to know what this does, all I know is that this is needed - the navmesh won't be okay without it. + ))) (defmethod birth! ((this entity-actor)) "Create a process for this entity and start it." @@ -905,9 +924,7 @@ ;; (return this) ;; ) ;;(birth-log "call to birth! on ~A~%" this) - (custom-nav-mesh-check-and-setup this) - (let* ((entity-type (-> this etype)) (info (entity-info-lookup entity-type)) (entity-process (get-process *default-dead-pool* entity-type (if info (-> info heap-size) #x4000)))) diff --git a/goal_src/jak1/engine/game/game-info.gc b/goal_src/jak1/engine/game/game-info.gc index 60c73d41bf..7f119c61cf 100644 --- a/goal_src/jak1/engine/game/game-info.gc +++ b/goal_src/jak1/engine/game/game-info.gc @@ -22,9 +22,6 @@ (define-extern runs-on-jak-death (function symbol none)) -;;Forward declaration Variable for mod base settings -(define-extern startingDebugContinuePoint (string)) - ;; DECOMP BEGINS ;;;;;;;;;;;;;;;;;; @@ -185,7 +182,6 @@ (cond (continue-point-override (empty) continue-point-override) ((!= *kernel-boot-message* 'play) "demo-start") - ((and *debug-segment* (not (string= startingDebugContinuePoint "village1-hut"))) startingDebugContinuePoint) ;; mod-base-change (*debug-segment* "village1-hut") (else "title-start"))) (set! (-> this auto-save-count) 0) diff --git a/goal_src/jak1/engine/game/main-h.gc b/goal_src/jak1/engine/game/main-h.gc index dc7dfcdc83..f8c24668b5 100644 --- a/goal_src/jak1/engine/game/main-h.gc +++ b/goal_src/jak1/engine/game/main-h.gc @@ -127,7 +127,9 @@ (define *display-strip-lines* 0) (define *display-nav-marks* #f) + (define *display-nav-marks-extras* #f) + (define *display-path-marks* #f) (define *display-vol-marks* #f) diff --git a/goal_src/jak1/engine/game/main.gc b/goal_src/jak1/engine/game/main.gc index 100094b078..0381ae9cd0 100644 --- a/goal_src/jak1/engine/game/main.gc +++ b/goal_src/jak1/engine/game/main.gc @@ -357,9 +357,7 @@ ;; collide dma (suspend) (while *run* - (runs-every-frame) ;; trigger hook for mod base mod-base-change entry point - ;; start immediately after all process updates finish. (profiler-instant-event "display-loop-top") ;; drawing effects to be used in foreground drawing. diff --git a/goal_src/jak1/engine/game/powerups.gc b/goal_src/jak1/engine/game/powerups.gc index 16c4fade94..8ef508e857 100644 --- a/goal_src/jak1/engine/game/powerups.gc +++ b/goal_src/jak1/engine/game/powerups.gc @@ -16,24 +16,20 @@ (change-parent self arg0) (let ((s1-1 (process->handle arg0)) (s2-1 (process->handle arg1))) - (let ((s0-0 (current-time))) - (until (time-elapsed? s0-0 (+ arg3 arg4)) - (let ((v1-8 (or (not (handle->process s1-1)) (not (handle->process s2-1))))) (if v1-8 (deactivate self))) - (let* ((f0-1 (fmax 0.0 (fmin 1.0 (/ (- (the float (- (current-time) s0-0)) (the float arg3)) (the float arg4))))) - (a0-18 (process-drawable-pair-random-point! (the-as process-drawable (-> s1-1 process 0)) - (the-as process-drawable (-> s2-1 process 0)) - (new-stack-vector0) - f0-1))) - (arg2 a0-18)) - (suspend))) + (suspend-for (+ arg3 arg4) + (let ((v1-8 (or (not (handle->process s1-1)) (not (handle->process s2-1))))) (if v1-8 (deactivate self))) + (let* ((f0-1 (fmax 0.0 (fmin 1.0 (/ (- (the float (- (current-time) time)) (the float arg3)) (the float arg4))))) + (a0-18 (process-drawable-pair-random-point! (the-as process-drawable (-> s1-1 process 0)) + (the-as process-drawable (-> s2-1 process 0)) + (new-stack-vector0) + f0-1))) + (arg2 a0-18))) (cond ((zero? arg5) (loop (suspend))) (else - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 arg5) - (let ((a0-21 (process-drawable-random-point! (the-as process-drawable (-> s2-1 process 0)) (new-stack-vector0)))) - (arg2 a0-21)) - (suspend)))))) + (suspend-for arg5 + (let ((a0-21 (process-drawable-random-point! (the-as process-drawable (-> s2-1 process 0)) (new-stack-vector0)))) + (arg2 a0-21)))))) (none)) (defpart 255 diff --git a/goal_src/jak1/engine/gfx/sprite/sparticle/sparticle-launcher.gc b/goal_src/jak1/engine/gfx/sprite/sparticle/sparticle-launcher.gc index df210160b4..55ab80f150 100644 --- a/goal_src/jak1/engine/gfx/sprite/sparticle/sparticle-launcher.gc +++ b/goal_src/jak1/engine/gfx/sprite/sparticle/sparticle-launcher.gc @@ -224,14 +224,18 @@ ;;;;;;;;;;;;;;;;;;; ;; launch ;;;;;;;;;;;;;;;;;;; - +(define *last-particle-error-log-time* (the time-frame #f)) (defun sp-queue-launch ((arg0 sparticle-system) (arg1 sparticle-launcher) (arg2 vector)) "Queue a launch from the given launcher, at the given position." (let ((v1-0 *sp-launch-queue*)) ;; og:preserve-this constant ;; make sure we have room in the queue (when (= (-> v1-0 in-use) SPARTICLE_QUEUE_SIZE) - (format 0 "ERROR: sp-launch-particles called during processing, and queue is full~%") + ;; og:mod-base suppress particle log spam a bit + (when (or (not *last-particle-error-log-time*) + (time-elapsed? *last-particle-error-log-time* (seconds 10))) + (format 0 "ERROR: sp-launch-particles called during processing, and queue is full~%") + (set-time! *last-particle-error-log-time*)) (return 0)) ;; make a new entry in the queue (let ((a3-5 (-> v1-0 queue (-> v1-0 in-use)))) diff --git a/goal_src/jak1/engine/gfx/tie/tie-methods.gc b/goal_src/jak1/engine/gfx/tie/tie-methods.gc index 1c5399c144..d3e58b6f84 100644 --- a/goal_src/jak1/engine/gfx/tie/tie-methods.gc +++ b/goal_src/jak1/engine/gfx/tie/tie-methods.gc @@ -299,12 +299,12 @@ (set! (-> a1-7 generic-next-clear) (the-as uint128 0))) 0) (let* ((s1-0 (-> (the-as drawable-inline-array-instance-tie v1-16) data)) ;; the inline array of instances - (s0-0 (&-> (scratchpad-object terrain-context) work background vis-list (/ (-> s1-0 0 id) 8))) ;; vis for first. + ;; (s0-0 (&-> (scratchpad-object terrain-context) work background vis-list (if (zero? (-> arg0 length)) 0 (/ (-> s1-0 0 id) 8)))) ;; vis for first. (s3-1 (-> *display* frames (-> *display* on-screen) frame global-buf)) ;; dma buf to write to ) - (set! sv-16 (-> (the-as drawable-inline-array-node v1-16) length)) ;; number of instances + ;; (set! sv-16 (-> (the-as drawable-inline-array-node v1-16) length)) ;; number of instances ;; if we actually have things to draw - (when (nonzero? sv-16) + (when #t ;; (nonzero? sv-16) ;; this is some buffer for the generic renderer (let* ((v1-21 (logand (the-as int *gsf-buffer*) 8191)) (v1-23 (logand (the-as int (&- (logand (the-as int (&-> (-> s4-1 data) -512)) 8191) (the-as uint v1-21))) 8191))) @@ -325,9 +325,9 @@ ;; note: this is a bit wasteful because we only care about generic ties. ;; non-generics are drawn fully in C++, but we're computing unused stuff here. ;; This ends up being so fast it's probably not worth worrying about yet. - (when (not *use-etie*) - (with-profiler "tie-instance" - (draw-inline-array-instance-tie s0-0 s1-0 sv-16 s3-1))) + ;; (when (not *use-etie*) + ;; (with-profiler "tie-instance" + ;; (draw-inline-array-instance-tie s0-0 s1-0 sv-16 s3-1))) ;; finish perf stats (read! (-> *perf-stats* data 9)) (update-wait-stats (-> *perf-stats* data 9) @@ -558,34 +558,47 @@ ;;;;;;;;;;;;;;;;; ;; note: the first three methods appear twice in the original code. +;; modified for PC: check length before colliding. (defmethod collide-with-box ((this drawable-tree-instance-tie) (arg0 int) (arg1 collide-list)) - (collide-with-box (-> this data 0) (-> this length) arg1) + (when (nonzero? (-> this length)) + (collide-with-box (-> this data 0) (-> this length) arg1) + ) 0 (none)) (defmethod collide-y-probe ((this drawable-tree-instance-tie) (arg0 int) (arg1 collide-list)) - (collide-y-probe (-> this data 0) (-> this length) arg1) + (when (nonzero? (-> this length)) + (collide-y-probe (-> this data 0) (-> this length) arg1) + ) 0 (none)) (defmethod collide-ray ((this drawable-tree-instance-tie) (arg0 int) (arg1 collide-list)) - (collide-ray (-> this data 0) (-> this length) arg1) + (when (nonzero? (-> this length)) + (collide-ray (-> this data 0) (-> this length) arg1) + ) 0 (none)) (defmethod collide-with-box ((this drawable-inline-array-instance-tie) (arg0 int) (arg1 collide-list)) - (collide-with-box (the-as instance-tie (-> this data)) (-> this length) arg1) + (when (nonzero? (-> this length)) + (collide-with-box (the-as instance-tie (-> this data)) (-> this length) arg1) + ) 0 (none)) (defmethod collide-y-probe ((this drawable-inline-array-instance-tie) (arg0 int) (arg1 collide-list)) - (collide-y-probe (the-as instance-tie (-> this data)) (-> this length) arg1) + (when (nonzero? (-> this length)) + (collide-y-probe (the-as instance-tie (-> this data)) (-> this length) arg1) + ) 0 (none)) (defmethod collide-ray ((this drawable-inline-array-instance-tie) (arg0 int) (arg1 collide-list)) - (collide-ray (the-as instance-tie (-> this data)) (-> this length) arg1) + (when (nonzero? (-> this length)) + (collide-ray (the-as instance-tie (-> this data)) (-> this length) arg1) + ) 0 (none)) diff --git a/goal_src/jak1/engine/level/level-info.gc b/goal_src/jak1/engine/level/level-info.gc index f3f2958f80..8a6ff4b8ee 100644 --- a/goal_src/jak1/engine/level/level-info.gc +++ b/goal_src/jak1/engine/level/level-info.gc @@ -2485,10 +2485,11 @@ :music-bank #f :ambient-sounds '() - :mood '*default-mood* - :mood-func 'update-mood-default - :ocean #f + :mood '*village1-mood* + :mood-func 'update-mood-village1 + :ocean '*ocean-map-village1* :sky #t + :sun-fade 1.0 :continues '((new 'static 'continue-point @@ -2507,8 +2508,8 @@ :vis-nick 'none :lev0 'test-zone :disp0 'display - :lev1 'village1 - :disp1 'display)) + :lev1 #f + :disp1 #f)) :tasks '() :priority 100 diff --git a/goal_src/jak1/engine/level/level.gc b/goal_src/jak1/engine/level/level.gc index 913b2a1292..e99c4baf01 100644 --- a/goal_src/jak1/engine/level/level.gc +++ b/goal_src/jak1/engine/level/level.gc @@ -623,6 +623,12 @@ ;; copy data from the level to the game-info storage. This will remember permanent level stuff, like ;; what you collected/completed. (copy-perms-from-level! *game-info* this) + ;; og:preserve-this fully clear entity perm status in the level itself (based on reset-actors) + ;; it should be copied back out of game-info on birth to prevent "NG+ glitch" + (let ((lev-ents (-> this entity))) + (dotimes (idx (-> lev-ents length)) + (let ((ent (-> lev-ents data idx entity))) + (update-perm! (-> ent extra perm) 'game (the-as entity-perm-status 1919))))) (send-event *camera* 'level-deactivate (-> this name)) (send-event *target* 'level-deactivate (-> this name)) ;; remove this BSP from the engine. This will stop us from being drawn. @@ -706,20 +712,37 @@ (defmethod is-object-visible? ((this level) (arg0 int)) "Is arg0 visible? Note that this will return #f if the visibility data is not loaded." ;; og:mod-base anything thats not a vanilla level -> always show actors - (case (-> this name) :comp name= - (('intro 'title 'demo - 'training 'village1 'beach 'jungle 'jungleb 'misty 'firecanyon - 'village2 'sunken 'sunkenb 'rolling 'swamp 'ogre - 'village3 'snow 'maincave 'darkcave 'robocave 'lavatube - 'citadel 'finalboss) - ;; vanilla level -> fall through to normal checks - ) - (else - ;; some custom level -> return true - (return #t) - ) - ) - + (case (-> this name) + :comp + name= + (('intro 'title + 'demo + 'training + 'village1 + 'beach + 'jungle + 'jungleb + 'misty + 'firecanyon + 'village2 + 'sunken + 'sunkenb + 'rolling + 'swamp + 'ogre + 'village3 + 'snow + 'maincave + 'darkcave + 'robocave + 'lavatube + 'citadel + 'finalboss) + ;; vanilla level -> fall through to normal checks + ) + (else + ;; some custom level -> return true + (return #t))) ;; og:preserve-this pc port added option to show every actor regardless (with-pc (if (not (-> *pc-settings* ps2-actor-vis?)) (return #t))) @@ -984,6 +1007,8 @@ (set! *print-login* #f) 0) +(define-extern *debug-continue-point* string) + (defun play ((use-vis symbol) (init-game symbol)) "The entry point to the actual game! This allocates the level heaps, loads some data, sets some default parameters and sets the startup level." ;; temp @@ -991,9 +1016,13 @@ (format 0 "(play :use-vis ~A :init-game ~A) has been called!~%" use-vis init-game) (format 0 "*kernel-boot-message*: ~A~%" *kernel-boot-message*) ;;(kernel-shutdown) - (let ((startup-level (case *kernel-boot-message* - (('play) (if *debug-segment* 'village1 'title)) - (else 'demo)))) + ;; og:mod-base use custom continue point + (let* ((debug-cont (if (and *debug-segment* (nonzero? *debug-continue-point*)) (get-continue-by-name *game-info* *debug-continue-point*))) + (startup-level (if debug-cont + (-> debug-cont level) + (case *kernel-boot-message* + (('play) (if *debug-segment* 'village1 'title)) + (else 'demo))))) (stop 'play) (set! (-> *level* vis?) use-vis) (set! (-> *level* want-level) #f) @@ -1025,7 +1054,11 @@ (on #t) (load-dbg "Display started: ~A~%" *dproc*) (when init-game - (initialize! *game-info* 'game (the-as game-save #f) (the-as string #f))) + ;; og:mod-base use custom continue point + (initialize! *game-info* + 'game + (the-as game-save #f) + (if (and *debug-segment* (nonzero? *debug-continue-point*)) *debug-continue-point* (the string #f)))) 0) (defun update-sound-banks () diff --git a/goal_src/jak1/engine/mods/input-display.gc b/goal_src/jak1/engine/mods/input-display.gc index cf54d94b23..fab08d6e34 100644 --- a/goal_src/jak1/engine/mods/input-display.gc +++ b/goal_src/jak1/engine/mods/input-display.gc @@ -26,23 +26,46 @@ Down lets you edit buttons, left lets you edit the sticks, right for dpad, up to ; ;Button center coordinates (define button-origin (new 'static 'vector4w :x 90 :y 208 :z 0 :w 0)) + ;Face buttons (define triangle-offset (new 'static 'vector4w :x -12 :y -18 :z 0 :w 0)) -(define x-offset (new 'static 'vector4w :x -12 :y 2 :z 0 :w 0)) -(define circle-offset (new 'static 'vector4w :x 6 :y -8 :z 0 :w 0)) -(define square-offset (new 'static 'vector4w :x -30 :y -8 :z 0 :w 0)) + +(define x-offset (new 'static 'vector4w :x -12 :y 2 :z 0 :w 0)) + +(define circle-offset (new 'static 'vector4w :x 6 :y -8 :z 0 :w 0)) + +(define square-offset (new 'static 'vector4w :x -30 :y -8 :z 0 :w 0)) (defun draw-face-buttons ((arg0 dma-buffer)) - ;Face buttons. Each button needed added to text-h.gc and english texts - (when (cpad-hold? 0 triangle) - (draw-string-xy (lookup-text! *common-text* (text-id pad-triangle) #f) arg0 (+ (-> button-origin x) (-> triangle-offset x)) (+ (-> button-origin y) (-> triangle-offset y)) (font-color green) (font-flags shadow kerning large)) ) - (when (cpad-hold? 0 circle) - (draw-string-xy (lookup-text! *common-text* (text-id pad-circle) #f) arg0 (+ (-> button-origin x) (-> circle-offset x)) (+ (-> button-origin y) (-> circle-offset y)) (font-color green) (font-flags shadow kerning large)) ) - (when (cpad-hold? 0 x) - (draw-string-xy (lookup-text! *common-text* (text-id pad-x) #f) arg0 (+ (-> button-origin x) (-> x-offset x)) (+ (-> button-origin y) (-> x-offset y)) (font-color green) (font-flags shadow kerning large)) ) - (when (cpad-hold? 0 square) - (draw-string-xy (lookup-text! *common-text* (text-id pad-square) #f) arg0 (+ (-> button-origin x) (-> square-offset x)) (+ (-> button-origin y) (-> square-offset y)) (font-color green) (font-flags shadow kerning large)) ) -) + ;Face buttons. Each button needed added to text-h.gc and english texts + (when (cpad-hold? 0 triangle) + (draw-string-xy (lookup-text! *common-text* (text-id pad-triangle) #f) + arg0 + (+ (-> button-origin x) (-> triangle-offset x)) + (+ (-> button-origin y) (-> triangle-offset y)) + (font-color green) + (font-flags shadow kerning large))) + (when (cpad-hold? 0 circle) + (draw-string-xy (lookup-text! *common-text* (text-id pad-circle) #f) + arg0 + (+ (-> button-origin x) (-> circle-offset x)) + (+ (-> button-origin y) (-> circle-offset y)) + (font-color green) + (font-flags shadow kerning large))) + (when (cpad-hold? 0 x) + (draw-string-xy (lookup-text! *common-text* (text-id pad-x) #f) + arg0 + (+ (-> button-origin x) (-> x-offset x)) + (+ (-> button-origin y) (-> x-offset y)) + (font-color green) + (font-flags shadow kerning large))) + (when (cpad-hold? 0 square) + (draw-string-xy (lookup-text! *common-text* (text-id pad-square) #f) + arg0 + (+ (-> button-origin x) (-> square-offset x)) + (+ (-> button-origin y) (-> square-offset y)) + (font-color green) + (font-flags shadow kerning large)))) ; ;Other buttons (LRs, select, start) @@ -54,266 +77,352 @@ Down lets you edit buttons, left lets you edit the sticks, right for dpad, up to ;(define RL3-y-offset 8) (define r1-offset (new 'static 'vector4w :x 13 :y -16 :z 0 :w 0)) + (define r2-offset (new 'static 'vector4w :x 13 :y -23 :z 0 :w 0)) + (define r3-offset (new 'static 'vector4w :x 13 :y 8 :z 0 :w 0)) + (define l1-offset (new 'static 'vector4w :x -28 :y -16 :z 0 :w 0)) + (define l2-offset (new 'static 'vector4w :x -28 :y -23 :z 0 :w 0)) + (define l3-offset (new 'static 'vector4w :x -28 :y 8 :z 0 :w 0)) + ; select uses l3 offset ; start uses r3 offset (defun draw-other-buttons ((arg0 dma-buffer)) - ;LR/Shoulder buttons - (when (cpad-hold? 0 r1) - (draw-string-xy "R1" arg0 (+ (-> button-origin x) (-> r1-offset x)) (+ (-> button-origin y) (-> r1-offset y)) (the font-color 13) (font-flags shadow kerning)) ) - (when (cpad-hold? 0 r2) - (draw-string-xy "R2" arg0 (+ (-> button-origin x) (-> r2-offset x)) (+ (-> button-origin y) (-> r2-offset y)) (the font-color 13) (font-flags shadow kerning)) ) - (when (cpad-hold? 0 r3) - (draw-string-xy "R3" arg0 (+ (-> button-origin x) (-> r3-offset x)) (+ (-> button-origin y) (-> r3-offset y)) (the font-color 13) (font-flags shadow kerning)) ) - (when (cpad-hold? 0 l1) - (draw-string-xy "L1" arg0 (+ (-> button-origin x) (-> l1-offset x)) (+ (-> button-origin y) (-> l1-offset y)) (the font-color 13) (font-flags shadow kerning)) ) - (when (cpad-hold? 0 l2) - (draw-string-xy "L2" arg0 (+ (-> button-origin x) (-> l2-offset x)) (+ (-> button-origin y) (-> l2-offset y)) (the font-color 13) (font-flags shadow kerning)) ) - (when (cpad-hold? 0 l3) - (draw-string-xy "L3" arg0 (+ (-> button-origin x) (-> l3-offset x)) (+ (-> button-origin y) (-> l3-offset y)) (the font-color 13) (font-flags shadow kerning)) ) - - ;Select/Start, aligned with L3/R3 - (when (cpad-hold? 0 start) - (draw-string-xy "Start" arg0 (+ (-> button-origin x) (-> r3-offset x)) (+ (-> button-origin y) (-> r3-offset y)) (the font-color 13) (font-flags shadow kerning)) ) - (when (cpad-hold? 0 select) - (draw-string-xy "Select" arg0 (+ (-> button-origin x) (-> l3-offset x)) (+ (-> button-origin y) (-> l3-offset y)) (the font-color 13) (font-flags shadow kerning)) ) - -) - - + ;LR/Shoulder buttons + (when (cpad-hold? 0 r1) + (draw-string-xy "R1" + arg0 + (+ (-> button-origin x) (-> r1-offset x)) + (+ (-> button-origin y) (-> r1-offset y)) + (the font-color 13) + (font-flags shadow kerning))) + (when (cpad-hold? 0 r2) + (draw-string-xy "R2" + arg0 + (+ (-> button-origin x) (-> r2-offset x)) + (+ (-> button-origin y) (-> r2-offset y)) + (the font-color 13) + (font-flags shadow kerning))) + (when (cpad-hold? 0 r3) + (draw-string-xy "R3" + arg0 + (+ (-> button-origin x) (-> r3-offset x)) + (+ (-> button-origin y) (-> r3-offset y)) + (the font-color 13) + (font-flags shadow kerning))) + (when (cpad-hold? 0 l1) + (draw-string-xy "L1" + arg0 + (+ (-> button-origin x) (-> l1-offset x)) + (+ (-> button-origin y) (-> l1-offset y)) + (the font-color 13) + (font-flags shadow kerning))) + (when (cpad-hold? 0 l2) + (draw-string-xy "L2" + arg0 + (+ (-> button-origin x) (-> l2-offset x)) + (+ (-> button-origin y) (-> l2-offset y)) + (the font-color 13) + (font-flags shadow kerning))) + (when (cpad-hold? 0 l3) + (draw-string-xy "L3" + arg0 + (+ (-> button-origin x) (-> l3-offset x)) + (+ (-> button-origin y) (-> l3-offset y)) + (the font-color 13) + (font-flags shadow kerning))) + ;Select/Start, aligned with L3/R3 + (when (cpad-hold? 0 start) + (draw-string-xy "Start" + arg0 + (+ (-> button-origin x) (-> r3-offset x)) + (+ (-> button-origin y) (-> r3-offset y)) + (the font-color 13) + (font-flags shadow kerning))) + (when (cpad-hold? 0 select) + (draw-string-xy "Select" + arg0 + (+ (-> button-origin x) (-> l3-offset x)) + (+ (-> button-origin y) (-> l3-offset y)) + (the font-color 13) + (font-flags shadow kerning)))) ; ;D-Pad inputs ; (define dpad-origin (new 'static 'vector4w :x 90 :y 208 :z 0 :w 0)) + (define up-offset (new 'static 'vector4w :x -12 :y -18 :z 0 :w 0)) + (define down-offset (new 'static 'vector4w :x -12 :y 2 :z 0 :w 0)) -(define left-offset (new 'static 'vector4w :x -30 :y -8 :z 0 :w 0)) -(define right-offset (new 'static 'vector4w :x 6 :y -8 :z 0 :w 0)) - -(defun draw-dpad ((arg0 dma-buffer)) - (when (cpad-hold? 0 up) - (draw-string-xy "up" arg0 (+ (-> dpad-origin x) (-> up-offset x)) (+ (-> dpad-origin y) (-> up-offset y)) (the font-color 13) (font-flags shadow kerning)) ) - (when (cpad-hold? 0 down) - (draw-string-xy "down" arg0 (+ (-> dpad-origin x) (-> down-offset x)) (+ (-> dpad-origin y) (-> down-offset y)) (the font-color 13) (font-flags shadow kerning)) ) - (when (cpad-hold? 0 left) - (draw-string-xy "left" arg0 (+ (-> dpad-origin x) (-> left-offset x)) (+ (-> dpad-origin y) (-> left-offset y)) (the font-color 13) (font-flags shadow kerning)) ) - (when (cpad-hold? 0 right) - (draw-string-xy "right" arg0 (+ (-> dpad-origin x) (-> right-offset x)) (+ (-> dpad-origin y) (-> right-offset y)) (the font-color 13) (font-flags shadow kerning)) ) -) +(define left-offset (new 'static 'vector4w :x -30 :y -8 :z 0 :w 0)) +(define right-offset (new 'static 'vector4w :x 6 :y -8 :z 0 :w 0)) + +(defun draw-dpad ((arg0 dma-buffer)) + (when (cpad-hold? 0 up) + (draw-string-xy "up" + arg0 + (+ (-> dpad-origin x) (-> up-offset x)) + (+ (-> dpad-origin y) (-> up-offset y)) + (the font-color 13) + (font-flags shadow kerning))) + (when (cpad-hold? 0 down) + (draw-string-xy "down" + arg0 + (+ (-> dpad-origin x) (-> down-offset x)) + (+ (-> dpad-origin y) (-> down-offset y)) + (the font-color 13) + (font-flags shadow kerning))) + (when (cpad-hold? 0 left) + (draw-string-xy "left" + arg0 + (+ (-> dpad-origin x) (-> left-offset x)) + (+ (-> dpad-origin y) (-> left-offset y)) + (the font-color 13) + (font-flags shadow kerning))) + (when (cpad-hold? 0 right) + (draw-string-xy "right" + arg0 + (+ (-> dpad-origin x) (-> right-offset x)) + (+ (-> dpad-origin y) (-> right-offset y)) + (the font-color 13) + (font-flags shadow kerning)))) ; ;Joystick stuff ; (define show-stick1? #t) + (define stick-origin (new 'static 'vector4w :x 30 :y 210 :z 0 :w 0)) + (define stick-text-offset (new 'static 'vector4w :x -20 :y -20 :z 0 :w 0)) ;no idea how the draw scaling works, this seems good enough ;length of axes lines, started with 128 and adjusted until it looked good (define height-idk (/ 128 5)) + (define width-idk (/ 128 3)) (defun draw-stick ((arg0 dma-buffer)) - (when show-stick1? + (when show-stick1? ;up/down axis - (draw-sprite2d-xy arg0 - (-> stick-origin x) ;the vertical line's x coordinate = stick center x coordinate - (- (-> stick-origin y) (/ height-idk 2)) ;we shift the line up, by half its height, so that the line midpoint = center y coordinate - 2 - height-idk - *color-black*) - ;left/right axis - (draw-sprite2d-xy arg0 - (- (-> stick-origin x) (/ width-idk 2)) - (-> stick-origin y) - width-idk - 1 - *color-gray*) - - ;Text for stick values - (draw-string-xy-scaled (string-format "~d ~d" (-> *cpad-list* cpads 0 leftx) (-> *cpad-list* cpads 0 lefty)) arg0 - (+ (-> stick-origin x) (-> stick-text-offset x)) - (+ (-> stick-origin y) (-> stick-text-offset y)) - (font-color green) (font-flags shadow kerning ) 0.75) - - ;raw stick location, nice for locating screen coordinates - ;(draw-sprite2d-xy testbuf (the int (-> *cpad-list* cpads 0 leftx)) (the int(-> *cpad-list* cpads 0 lefty)) 5 3 *color-red*) - - ;stick location scaled to picture - (draw-sprite2d-xy arg0 - ;analog-input takes left stick x int value and maps its min/max to negative/positive of the last argument - ;in our case we scale to half of the picture's width, so the stick can go full + (right) or full - (left) - (+ (-> stick-origin x) - (analog-input (the int (-> *cpad-list* cpads 0 leftx)) 128.0 0.0 128.0 (the float (/ width-idk 2)))) - ;repeat for y coordinate - (+ (-> stick-origin y) - (analog-input (the int (-> *cpad-list* cpads 0 lefty)) 128.0 0.0 128.0 (the float (/ height-idk 2)))) - 3 - 2 - *color-cyan*) - ) -) + (draw-sprite2d-xy arg0 + (-> stick-origin x) ;the vertical line's x coordinate = stick center x coordinate + (- (-> stick-origin y) (/ height-idk 2)) ;we shift the line up, by half its height, so that the line midpoint = center y coordinate + 2 + height-idk + *color-black*) + ;left/right axis + (draw-sprite2d-xy arg0 (- (-> stick-origin x) (/ width-idk 2)) (-> stick-origin y) width-idk 1 *color-gray*) + ;Text for stick values + (draw-string-xy-scaled (string-format "~d ~d" (-> *cpad-list* cpads 0 leftx) (-> *cpad-list* cpads 0 lefty)) + arg0 + (+ (-> stick-origin x) (-> stick-text-offset x)) + (+ (-> stick-origin y) (-> stick-text-offset y)) + (font-color green) + (font-flags shadow kerning) + 0.75) + ;raw stick location, nice for locating screen coordinates + ;(draw-sprite2d-xy testbuf (the int (-> *cpad-list* cpads 0 leftx)) (the int(-> *cpad-list* cpads 0 lefty)) 5 3 *color-red*) + ;stick location scaled to picture + (draw-sprite2d-xy arg0 + ;analog-input takes left stick x int value and maps its min/max to negative/positive of the last argument + ;in our case we scale to half of the picture's width, so the stick can go full + (right) or full - (left) + (+ (-> stick-origin x) + (analog-input (the int (-> *cpad-list* cpads 0 leftx)) 128.0 0.0 128.0 (the float (/ width-idk 2)))) + ;repeat for y coordinate + (+ (-> stick-origin y) + (analog-input (the int (-> *cpad-list* cpads 0 lefty)) 128.0 0.0 128.0 (the float (/ height-idk 2)))) + 3 + 2 + *color-cyan*))) ; ;Second stick ; (define show-stick2? #f) + (define stick2-origin (new 'static 'vector4w :x 150 :y 210 :z 0 :w 0)) + (define stick2-text-offset (new 'static 'vector4w :x -20 :y -20 :z 0 :w 0)) (defun draw-stick2 ((arg0 dma-buffer)) - (when show-stick2? - ;up/down axis - (draw-sprite2d-xy arg0 - (-> stick2-origin x) - (- (-> stick2-origin y) (/ height-idk 2)) - 2 - height-idk - *color-black*) - ;left/right axis - (draw-sprite2d-xy arg0 - (- (-> stick2-origin x) (/ width-idk 2)) - (-> stick2-origin y) - width-idk - 1 - *color-gray*) - - ;Text for stick values - (draw-string-xy-scaled (string-format "~d ~d" (-> *cpad-list* cpads 0 rightx) (-> *cpad-list* cpads 0 righty)) arg0 - (+ (-> stick2-origin x) (-> stick2-text-offset x)) - (+ (-> stick2-origin y) (-> stick2-text-offset y)) - (font-color cyan) (font-flags shadow kerning ) 0.75) - - ;stick location scaled to picture - (draw-sprite2d-xy arg0 - (+ (-> stick2-origin x) - (analog-input (the int (-> *cpad-list* cpads 0 rightx)) 128.0 0.0 128.0 (the float (/ width-idk 2)))) - (+ (-> stick2-origin y) - (analog-input (the int (-> *cpad-list* cpads 0 righty)) 128.0 0.0 128.0 (the float (/ height-idk 2)))) - 3 - 2 - *color-green*) - ) -) + (when show-stick2? + ;up/down axis + (draw-sprite2d-xy arg0 (-> stick2-origin x) (- (-> stick2-origin y) (/ height-idk 2)) 2 height-idk *color-black*) + ;left/right axis + (draw-sprite2d-xy arg0 (- (-> stick2-origin x) (/ width-idk 2)) (-> stick2-origin y) width-idk 1 *color-gray*) + ;Text for stick values + (draw-string-xy-scaled (string-format "~d ~d" (-> *cpad-list* cpads 0 rightx) (-> *cpad-list* cpads 0 righty)) + arg0 + (+ (-> stick2-origin x) (-> stick2-text-offset x)) + (+ (-> stick2-origin y) (-> stick2-text-offset y)) + (font-color cyan) + (font-flags shadow kerning) + 0.75) + ;stick location scaled to picture + (draw-sprite2d-xy arg0 + (+ (-> stick2-origin x) + (analog-input (the int (-> *cpad-list* cpads 0 rightx)) 128.0 0.0 128.0 (the float (/ width-idk 2)))) + (+ (-> stick2-origin y) + (analog-input (the int (-> *cpad-list* cpads 0 righty)) 128.0 0.0 128.0 (the float (/ height-idk 2)))) + 3 + 2 + *color-green*))) ; ;edit mode ; (define button-edit-mode 0) -(define button-edit-strings (new 'static 'boxed-array :type string - "" - "Hold a button and use dpad to move" - "Editing Sticks" - "Editing Dpad" - )) - -(defun edit-mode-controls () - ;Hold L2 + L3 + dpad to change the edit mode - (when (and (cpad-hold? 0 l2) (cpad-hold? 0 l3)) - (when (cpad-pressed? 0 up) (set! button-edit-mode 0)) - (when (cpad-pressed? 0 down) (set! button-edit-mode 1)) - (when (cpad-pressed? 0 left) (set! button-edit-mode 2)) - (when (cpad-pressed? 0 right) (set! button-edit-mode 3)) - ) - - ;moves individual face buttons with dpad - (when (= button-edit-mode 1) - (when (cpad-hold? 0 triangle) ;when you hold triangle, you can move triangle's offset vector with the dpad - (when (cpad-hold? 0 up) (+! (-> triangle-offset y) -1)) - (when (cpad-hold? 0 down) (+! (-> triangle-offset y) 1)) - (when (cpad-hold? 0 left) (+! (-> triangle-offset x) -1)) - (when (cpad-hold? 0 right) (+! (-> triangle-offset x) 1)) - ) - (when (cpad-hold? 0 circle) - (when (cpad-hold? 0 up) (+! (-> circle-offset y) -1)) - (when (cpad-hold? 0 down) (+! (-> circle-offset y) 1)) - (when (cpad-hold? 0 left) (+! (-> circle-offset x) -1)) - (when (cpad-hold? 0 right) (+! (-> circle-offset x) 1)) - ) - (when (cpad-hold? 0 x) - (when (cpad-hold? 0 up) (+! (-> x-offset y) -1)) - (when (cpad-hold? 0 down) (+! (-> x-offset y) 1)) - (when (cpad-hold? 0 left) (+! (-> x-offset x) -1)) - (when (cpad-hold? 0 right) (+! (-> x-offset x) 1)) - ) - (when (cpad-hold? 0 square) - (when (cpad-hold? 0 up) (+! (-> square-offset y) -1)) - (when (cpad-hold? 0 down) (+! (-> square-offset y) 1)) - (when (cpad-hold? 0 left) (+! (-> square-offset x) -1)) - (when (cpad-hold? 0 right) (+! (-> square-offset x) 1)) - ) - ;LR buttons - (when (cpad-hold? 0 r1) - (when (cpad-hold? 0 up) (+! (-> r1-offset y) -1)) - (when (cpad-hold? 0 down) (+! (-> r1-offset y) 1)) - (when (cpad-hold? 0 left) (+! (-> r1-offset x) -1)) - (when (cpad-hold? 0 right) (+! (-> r1-offset x) 1)) - ) - (when (cpad-hold? 0 r2) - (when (cpad-hold? 0 up) (+! (-> r2-offset y) -1)) - (when (cpad-hold? 0 down) (+! (-> r2-offset y) 1)) - (when (cpad-hold? 0 left) (+! (-> r2-offset x) -1)) - (when (cpad-hold? 0 right) (+! (-> r2-offset x) 1)) - ) - (when (or (cpad-hold? 0 r3) (cpad-hold? 0 start)) ;use an or here since start/r3 share coords - (when (cpad-hold? 0 up) (+! (-> r3-offset y) -1)) - (when (cpad-hold? 0 down) (+! (-> r3-offset y) 1)) - (when (cpad-hold? 0 left) (+! (-> r3-offset x) -1)) - (when (cpad-hold? 0 right) (+! (-> r3-offset x) 1)) - ) - (when (cpad-hold? 0 l1) - (when (cpad-hold? 0 up) (+! (-> l1-offset y) -1)) - (when (cpad-hold? 0 down) (+! (-> l1-offset y) 1)) - (when (cpad-hold? 0 left) (+! (-> l1-offset x) -1)) - (when (cpad-hold? 0 right) (+! (-> l1-offset x) 1)) - ) - (when (cpad-hold? 0 l2) - (when (cpad-hold? 0 up) (+! (-> l2-offset y) -1)) - (when (cpad-hold? 0 down) (+! (-> l2-offset y) 1)) - (when (cpad-hold? 0 left) (+! (-> l2-offset x) -1)) - (when (cpad-hold? 0 right) (+! (-> l2-offset x) 1)) - ) - (when (or (cpad-hold? 0 l3) (cpad-hold? 0 select)) ;use an or here since select/l3 share coords - (when (cpad-hold? 0 up) (+! (-> l3-offset y) -1)) - (when (cpad-hold? 0 down) (+! (-> l3-offset y) 1)) - (when (cpad-hold? 0 left) (+! (-> l3-offset x) -1)) - (when (cpad-hold? 0 right) (+! (-> l3-offset x) 1)) - ) - ) - ;moves joysticks - (when (= button-edit-mode 2) - ;stick1 with dpad - (when (cpad-hold? 0 up) (+! (-> stick-origin y) -1)) - (when (cpad-hold? 0 down) (+! (-> stick-origin y) 1)) - (when (cpad-hold? 0 left) (+! (-> stick-origin x) -1)) - (when (cpad-hold? 0 right) (+! (-> stick-origin x) 1)) - (when (cpad-pressed? 0 l3) (not! show-stick1?)) - ;stick2 with face buttons - (when (cpad-hold? 0 triangle) (+! (-> stick2-origin y) -1)) - (when (cpad-hold? 0 x) (+! (-> stick2-origin y) 1)) - (when (cpad-hold? 0 square) (+! (-> stick2-origin x) -1)) - (when (cpad-hold? 0 circle) (+! (-> stick2-origin x) 1)) - (when (cpad-pressed? 0 r3) (not! show-stick2?)) - ) - ;moves dpad - (when (= button-edit-mode 3) - ;dpad-origin with dpad - (when (cpad-hold? 0 up) (+! (-> dpad-origin y) -1)) - (when (cpad-hold? 0 down) (+! (-> dpad-origin y) 1)) - (when (cpad-hold? 0 left) (+! (-> dpad-origin x) -1)) - (when (cpad-hold? 0 right) (+! (-> dpad-origin x) 1)) - ) -) +(define button-edit-strings + (new 'static 'boxed-array :type string "" "Hold a button and use dpad to move" "Editing Sticks" "Editing Dpad")) +(defun edit-mode-controls () + ;Hold L2 + L3 + dpad to change the edit mode + (when (and (cpad-hold? 0 l2) (cpad-hold? 0 l3)) + (when (cpad-pressed? 0 up) + (set! button-edit-mode 0)) + (when (cpad-pressed? 0 down) + (set! button-edit-mode 1)) + (when (cpad-pressed? 0 left) + (set! button-edit-mode 2)) + (when (cpad-pressed? 0 right) + (set! button-edit-mode 3))) + ;moves individual face buttons with dpad + (when (= button-edit-mode 1) + (when (cpad-hold? 0 triangle) ;when you hold triangle, you can move triangle's offset vector with the dpad + (when (cpad-hold? 0 up) + (+! (-> triangle-offset y) -1)) + (when (cpad-hold? 0 down) + (+! (-> triangle-offset y) 1)) + (when (cpad-hold? 0 left) + (+! (-> triangle-offset x) -1)) + (when (cpad-hold? 0 right) + (+! (-> triangle-offset x) 1))) + (when (cpad-hold? 0 circle) + (when (cpad-hold? 0 up) + (+! (-> circle-offset y) -1)) + (when (cpad-hold? 0 down) + (+! (-> circle-offset y) 1)) + (when (cpad-hold? 0 left) + (+! (-> circle-offset x) -1)) + (when (cpad-hold? 0 right) + (+! (-> circle-offset x) 1))) + (when (cpad-hold? 0 x) + (when (cpad-hold? 0 up) + (+! (-> x-offset y) -1)) + (when (cpad-hold? 0 down) + (+! (-> x-offset y) 1)) + (when (cpad-hold? 0 left) + (+! (-> x-offset x) -1)) + (when (cpad-hold? 0 right) + (+! (-> x-offset x) 1))) + (when (cpad-hold? 0 square) + (when (cpad-hold? 0 up) + (+! (-> square-offset y) -1)) + (when (cpad-hold? 0 down) + (+! (-> square-offset y) 1)) + (when (cpad-hold? 0 left) + (+! (-> square-offset x) -1)) + (when (cpad-hold? 0 right) + (+! (-> square-offset x) 1))) + ;LR buttons + (when (cpad-hold? 0 r1) + (when (cpad-hold? 0 up) + (+! (-> r1-offset y) -1)) + (when (cpad-hold? 0 down) + (+! (-> r1-offset y) 1)) + (when (cpad-hold? 0 left) + (+! (-> r1-offset x) -1)) + (when (cpad-hold? 0 right) + (+! (-> r1-offset x) 1))) + (when (cpad-hold? 0 r2) + (when (cpad-hold? 0 up) + (+! (-> r2-offset y) -1)) + (when (cpad-hold? 0 down) + (+! (-> r2-offset y) 1)) + (when (cpad-hold? 0 left) + (+! (-> r2-offset x) -1)) + (when (cpad-hold? 0 right) + (+! (-> r2-offset x) 1))) + (when (or (cpad-hold? 0 r3) (cpad-hold? 0 start)) ;use an or here since start/r3 share coords + (when (cpad-hold? 0 up) + (+! (-> r3-offset y) -1)) + (when (cpad-hold? 0 down) + (+! (-> r3-offset y) 1)) + (when (cpad-hold? 0 left) + (+! (-> r3-offset x) -1)) + (when (cpad-hold? 0 right) + (+! (-> r3-offset x) 1))) + (when (cpad-hold? 0 l1) + (when (cpad-hold? 0 up) + (+! (-> l1-offset y) -1)) + (when (cpad-hold? 0 down) + (+! (-> l1-offset y) 1)) + (when (cpad-hold? 0 left) + (+! (-> l1-offset x) -1)) + (when (cpad-hold? 0 right) + (+! (-> l1-offset x) 1))) + (when (cpad-hold? 0 l2) + (when (cpad-hold? 0 up) + (+! (-> l2-offset y) -1)) + (when (cpad-hold? 0 down) + (+! (-> l2-offset y) 1)) + (when (cpad-hold? 0 left) + (+! (-> l2-offset x) -1)) + (when (cpad-hold? 0 right) + (+! (-> l2-offset x) 1))) + (when (or (cpad-hold? 0 l3) (cpad-hold? 0 select)) ;use an or here since select/l3 share coords + (when (cpad-hold? 0 up) + (+! (-> l3-offset y) -1)) + (when (cpad-hold? 0 down) + (+! (-> l3-offset y) 1)) + (when (cpad-hold? 0 left) + (+! (-> l3-offset x) -1)) + (when (cpad-hold? 0 right) + (+! (-> l3-offset x) 1)))) + ;moves joysticks + (when (= button-edit-mode 2) + ;stick1 with dpad + (when (cpad-hold? 0 up) + (+! (-> stick-origin y) -1)) + (when (cpad-hold? 0 down) + (+! (-> stick-origin y) 1)) + (when (cpad-hold? 0 left) + (+! (-> stick-origin x) -1)) + (when (cpad-hold? 0 right) + (+! (-> stick-origin x) 1)) + (when (cpad-pressed? 0 l3) + (not! show-stick1?)) + ;stick2 with face buttons + (when (cpad-hold? 0 triangle) + (+! (-> stick2-origin y) -1)) + (when (cpad-hold? 0 x) + (+! (-> stick2-origin y) 1)) + (when (cpad-hold? 0 square) + (+! (-> stick2-origin x) -1)) + (when (cpad-hold? 0 circle) + (+! (-> stick2-origin x) 1)) + (when (cpad-pressed? 0 r3) + (not! show-stick2?))) + ;moves dpad + (when (= button-edit-mode 3) + ;dpad-origin with dpad + (when (cpad-hold? 0 up) + (+! (-> dpad-origin y) -1)) + (when (cpad-hold? 0 down) + (+! (-> dpad-origin y) 1)) + (when (cpad-hold? 0 left) + (+! (-> dpad-origin x) -1)) + (when (cpad-hold? 0 right) + (+! (-> dpad-origin x) 1)))) ; ; @@ -324,53 +433,48 @@ Down lets you edit buttons, left lets you edit the sticks, right for dpad, up to (defun input-display-on () (when (not (process-by-name 'button-proc *active-pool*)) ;process-spawn-function, spawns a process that runs the function you give it - (process-spawn-function process :name 'button-proc + (process-spawn-function process + :name 'button-proc ;This lambda is our function (lambda :behavior process () ;Code before the loop runs once on process spawn ; ;Loop runs once per frame while process is active (loop - ;function that checks input to turn on editing (edit-mode-controls) - ;Start a bucket thing block so we can use draw functions (with-dma-buffer-add-bucket ((testbuf (-> (current-frame) global-buf)) (bucket-id debug-no-zbuf)) ;Edit mode string draws (when (and (cpad-hold? 0 l2) (cpad-hold? 0 l3)) - (draw-string-xy-scaled "L2+L3+Dpad to start editing input display" testbuf 5 170 (the font-color 12) (font-flags shadow kerning) 0.7) ) + (draw-string-xy-scaled "L2+L3+Dpad to start editing input display" + testbuf + 5 + 170 + (the font-color 12) + (font-flags shadow kerning) + 0.7)) (when (!= button-edit-mode 0) - (draw-string-xy-scaled (string-format "~s" (-> button-edit-strings button-edit-mode)) testbuf 5 177 (the font-color 12) (font-flags shadow kerning) 0.7) ) - + (draw-string-xy-scaled (string-format "~s" (-> button-edit-strings button-edit-mode)) + testbuf + 5 + 177 + (the font-color 12) + (font-flags shadow kerning) + 0.7)) ;Other draw stuff (draw-face-buttons testbuf) - (draw-other-buttons testbuf) - (draw-dpad testbuf) - (draw-stick testbuf) - - (draw-stick2 testbuf) - ) - + (draw-stick2 testbuf)) ;Processes should suspend themselves, the loop will resume next frame - (suspend) - ) - ) - ) - ) - + (suspend))))) ;Lisp returns the last form as the function return - (none) - ) - + (none)) (defun input-display-off () "Kill the button process" (when (process-by-name 'button-proc *active-pool*) - (kill-by-name 'button-proc *active-pool*) - ) - (none) - ) \ No newline at end of file + (kill-by-name 'button-proc *active-pool*)) + (none)) diff --git a/goal_src/jak1/engine/mods/mod-common-functions.gc b/goal_src/jak1/engine/mods/mod-common-functions.gc index 38b170da4d..fb250f9667 100644 --- a/goal_src/jak1/engine/mods/mod-common-functions.gc +++ b/goal_src/jak1/engine/mods/mod-common-functions.gc @@ -9,11 +9,11 @@ ;; What is this file for. ;;;;;;;;;;;;;;;;;;;;;;;;;; -#| This file is a place where you can define custom functions and GOAL code +#| + This file is a place where you can define custom functions and GOAL code to call inside of mod-custom-code.gc for example I have defined a function that increases the powercell count by one when it is called - |# - +|# ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Useful GOAL modding documentation @@ -29,15 +29,12 @@ Gives a random FLOAT or INT between the provided ranges when called if the result of rand-vu-int-range is 1, then DANCE! if it is not 1, then Don't dance (if (= (rand-vu-int-range 0 10) 1) (DANCE!) (Don't dance)) - - |# ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Define Custom Variables to use in mods ;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Define Custom Functions to call in mods ;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -46,19 +43,16 @@ if the result of rand-vu-int-range is 1, then DANCE! if it is not 1, then Don't ;; Macros can be used more-or-less just like functions (defmacro current-cell-count () - `(-> *game-info* fuel) - ) + `(-> *game-info* fuel)) (defmacro set-current-cell-count (count) - `(set! (-> *game-info* fuel) ,count) - ) + `(set! (-> *game-info* fuel) ,count)) (defun increase-power-cell-by-one () (set-current-cell-count (+ (current-cell-count) 1)) ;; with the two macros defined above, this is equivalent to ;; (set! (-> *game-info* fuel) (+ (-> *game-info* fuel) 1)) - (none) - ) + (none)) ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Define Approved Custom Functions/Macros to call in all mods @@ -67,405 +61,323 @@ if the result of rand-vu-int-range is 1, then DANCE! if it is not 1, then Don't ;; These are included with the mod base and you are welcome to use them in your mods! (defmacro current-checkpoint-name () - `(-> *game-info* current-continue name) - ) + `(-> *game-info* current-continue name)) (defun set-current-checkpoint-by-name ((name string)) - (set-continue! *game-info* name) - ) + (set-continue! *game-info* name)) (defmacro current-level-name () - `(-> (level-get-target-inside *level*) name) - ) + `(-> (level-get-target-inside *level*) name)) (defmacro current-orb-count () - `(-> *game-info* money) - ) + `(-> *game-info* money)) (defmacro current-cutscene () - `(-> *art-control* active-stream) - ) + `(-> *art-control* active-stream)) (defmacro set-cpad-pressed! (pad-idx &rest buttons) - `(logior! (cpad-pressed ,pad-idx) (pad-buttons ,@buttons)) - ) + `(logior! (cpad-pressed ,pad-idx) (pad-buttons ,@buttons))) (defmacro set-cpad-hold! (pad-idx &rest buttons) - `(logior! (cpad-hold ,pad-idx) (pad-buttons ,@buttons)) - ) + `(logior! (cpad-hold ,pad-idx) (pad-buttons ,@buttons))) ;;This function moves an actor to the given coordinates ;;example: (move-actor "farmer-3" 3.0 74.0 -120.0) (defun move-actor ((actor-name string) (x float) (y float) (z float)) (when (entity-by-name actor-name) (let* ((entity-actor (entity-by-name actor-name)) - (actor (-> entity-actor extra process)) - ) + (actor (-> entity-actor extra process))) (when actor (case (-> actor type) ((fuel-cell) - (set-vector! (-> entity-actor trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> entity-actor extra trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the process-drawable actor) root trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the fuel-cell actor) base) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the fuel-cell actor) root trans) (meters x) (meters y) (meters z) 1.0) - (when (name= (-> (the fuel-cell actor) state name) 'wait) - ;; only move collision when idle (messes up glowing in cutscene) - (set! (-> (the fuel-cell actor) root root-prim world-sphere x) (meters x)) - (set! (-> (the fuel-cell actor) root root-prim world-sphere y) (meters y)) - (set! (-> (the fuel-cell actor) root root-prim world-sphere z) (meters z)) - ) - ) + (set-vector! (-> entity-actor trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> entity-actor extra trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the process-drawable actor) root trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the fuel-cell actor) base) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the fuel-cell actor) root trans) (meters x) (meters y) (meters z) 1.0) + (when (name= (-> (the fuel-cell actor) state name) 'wait) + ;; only move collision when idle (messes up glowing in cutscene) + (set! (-> (the fuel-cell actor) root root-prim world-sphere x) (meters x)) + (set! (-> (the fuel-cell actor) root root-prim world-sphere y) (meters y)) + (set! (-> (the fuel-cell actor) root root-prim world-sphere z) (meters z)))) ((orb-cache-top) - ;; don't move while its activated (let it go up/down) - (when (not (name= (-> (the orb-cache-top actor) state name) 'orb-cache-top-activate)) - (set-vector! (-> entity-actor trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> entity-actor extra trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the process-drawable actor) root trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the orb-cache-top actor) basetrans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the orb-cache-top actor) root trans) (meters x) (meters y) (meters z) 1.0) - (set! (-> (the orb-cache-top actor) root root-prim world-sphere x) (meters x)) - (set! (-> (the orb-cache-top actor) root root-prim world-sphere y) (meters y)) - (set! (-> (the orb-cache-top actor) root root-prim world-sphere z) (meters z)) - (set-vector! (-> (the orb-cache-top actor) draw origin) (meters x) (meters y) (meters z) 1.0) - (let ((radius (-> (the process-drawable actor) draw radius)) - (bounds (res-lump-data entity-actor 'visvol (inline-array vector))) - ) - (set-vector! (-> bounds 0) (- (meters x) radius) (meters y) (- (meters z) radius) 1.0) - (set-vector! (-> bounds 1) (+ (meters x) radius) (meters y) (+ (meters z) radius) 1.0) - ) - ) - ) + ;; don't move while its activated (let it go up/down) + (when (not (name= (-> (the orb-cache-top actor) state name) 'orb-cache-top-activate)) + (set-vector! (-> entity-actor trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> entity-actor extra trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the process-drawable actor) root trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the orb-cache-top actor) basetrans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the orb-cache-top actor) root trans) (meters x) (meters y) (meters z) 1.0) + (set! (-> (the orb-cache-top actor) root root-prim world-sphere x) (meters x)) + (set! (-> (the orb-cache-top actor) root root-prim world-sphere y) (meters y)) + (set! (-> (the orb-cache-top actor) root root-prim world-sphere z) (meters z)) + (set-vector! (-> (the orb-cache-top actor) draw origin) (meters x) (meters y) (meters z) 1.0) + (let ((radius (-> (the process-drawable actor) draw radius)) + (bounds (res-lump-data entity-actor 'visvol (inline-array vector)))) + (set-vector! (-> bounds 0) (- (meters x) radius) (meters y) (- (meters z) radius) 1.0) + (set-vector! (-> bounds 1) (+ (meters x) radius) (meters y) (+ (meters z) radius) 1.0)))) ((money) - ;; don't move orbs if being blue-eco-sucked - (when (not (logtest? (-> (the money actor) flags) (collectable-flags suck))) - (set-vector! (-> entity-actor trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> entity-actor extra trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the process-drawable actor) root trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the money actor) base) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the money actor) root trans) (meters x) (meters y) (meters z) 1.0) - (set! (-> (the money actor) root root-prim world-sphere x) (meters x)) - (set! (-> (the money actor) root root-prim world-sphere y) (meters y)) - (set! (-> (the money actor) root root-prim world-sphere z) (meters z)) - ) - ) + ;; don't move orbs if being blue-eco-sucked + (when (not (logtest? (-> (the money actor) flags) (collectable-flags suck))) + (set-vector! (-> entity-actor trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> entity-actor extra trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the process-drawable actor) root trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the money actor) base) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the money actor) root trans) (meters x) (meters y) (meters z) 1.0) + (set! (-> (the money actor) root root-prim world-sphere x) (meters x)) + (set! (-> (the money actor) root root-prim world-sphere y) (meters y)) + (set! (-> (the money actor) root root-prim world-sphere z) (meters z)))) ((crate crate-buzzer) - ;; only move crates if they're not jumping - (when (= (-> (the crate actor) smush amp) 0.0) - (set-vector! (-> entity-actor trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> entity-actor extra trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the process-drawable actor) root trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the crate actor) base) (meters x) (meters y) (meters z) 1.0) - ;; (set-vector! (-> (the crate actor) root trans) (meters x) (meters y) (meters z) 1.0) - ;; (set! (-> (the crate actor) root root-prim world-sphere x) (meters x)) - ;; (set! (-> (the crate actor) root root-prim world-sphere y) (meters y)) - ;; (set! (-> (the crate actor) root root-prim world-sphere z) (meters z)) - ) - ) + ;; only move crates if they're not jumping + (when (= (-> (the crate actor) smush amp) 0.0) + (set-vector! (-> entity-actor trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> entity-actor extra trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the process-drawable actor) root trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the crate actor) base) (meters x) (meters y) (meters z) 1.0) + ;; (set-vector! (-> (the crate actor) root trans) (meters x) (meters y) (meters z) 1.0) + ;; (set! (-> (the crate actor) root root-prim world-sphere x) (meters x)) + ;; (set! (-> (the crate actor) root root-prim world-sphere y) (meters y)) + ;; (set! (-> (the crate actor) root root-prim world-sphere z) (meters z)) + )) ((darkvine) - (set-vector! (-> entity-actor trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> entity-actor extra trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the process-drawable actor) root trans) (meters x) (meters y) (meters z) 1.0) - ) + (set-vector! (-> entity-actor trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> entity-actor extra trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the process-drawable actor) root trans) (meters x) (meters y) (meters z) 1.0)) (else - (format 0 "unexpected actor type ~S ~S ~S~%" actor-name (-> entity-actor type) (-> actor type)) - (set-vector! (-> entity-actor trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> entity-actor extra trans) (meters x) (meters y) (meters z) 1.0) - (set-vector! (-> (the process-drawable actor) root trans) (meters x) (meters y) (meters z) 1.0) - ) - ) - ) - ) - ) - (none) - ) + (format 0 "unexpected actor type ~S ~S ~S~%" actor-name (-> entity-actor type) (-> actor type)) + (set-vector! (-> entity-actor trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> entity-actor extra trans) (meters x) (meters y) (meters z) 1.0) + (set-vector! (-> (the process-drawable actor) root trans) (meters x) (meters y) (meters z) 1.0)))))) + (none)) (defun process-by-aid ((arg0 uint)) "Get the process for the entity with the given aid. If there is no entity or process, #f." - (let ((v1-0 (entity-by-aid arg0))) - (if v1-0 - (-> v1-0 extra process) - ) - ) -) + (let ((v1-0 (entity-by-aid arg0))) (if v1-0 (-> v1-0 extra process)))) (defun spawn-actor-by-name ((name string)) ;; Takes in the string of name of a actor, and spawns a new process based on the entity. - (let* ((entity-actor (the entity-actor (entity-by-name name))) - (type (-> entity-actor etype)) - (e-info (entity-info-lookup type)) - ) - (when (entity-by-name name) - (init-entity - (get-process *default-dead-pool* type (if e-info (-> e-info heap-size) #x4000)) - entity-actor) - (sound-play "buzzer-pickup") - ) - (if (not (entity-by-name name)) - (sound-play "oof") - ) - ) - (none) -) + (let* ((entity-actor (the entity-actor (entity-by-name name))) + (type (-> entity-actor etype)) + (e-info (entity-info-lookup type))) + (when (entity-by-name name) + (init-entity (get-process *default-dead-pool* type (if e-info (-> e-info heap-size) #x4000)) entity-actor) + (sound-play "buzzer-pickup")) + (if (not (entity-by-name name)) (sound-play "oof"))) + (none)) ;;Draws a debug sphere on the actor, takes in a string actor name and a radius for the sphere in meters -(defun draw-debug-sphere-on-actor ((actorName string)(radius float)) +(defun draw-debug-sphere-on-actor ((actorName string) (radius float)) (when *debug-segment* (when (process-by-ename actorName) - (add-debug-sphere #t (bucket-id debug) (-> (the-as process-drawable (process-by-ename actorName)) root trans) (meters radius) (static-rgba 0 #xff 0 #x40)) - ) - ) - (none) -) - + (add-debug-sphere #t + (bucket-id debug) + (-> (the-as process-drawable (process-by-ename actorName)) root trans) + (meters radius) + (static-rgba 0 #xff 0 #x40)))) + (none)) ;;This function moves a given actor to jaks current position, then prints a (move-actors) call in gk.exe (defun move-to-jak ((arg0 string)) -(format #t "move-actor code: (move-actor ~a ~m ~m ~m)~%" arg0(-> (target-pos 0) x) (-> (target-pos 0) y) (-> (target-pos 0) z)) + (format #t + "move-actor code: (move-actor ~a ~m ~m ~m)~%" + arg0 + (-> (target-pos 0) x) + (-> (target-pos 0) y) + (-> (target-pos 0) z)) (when (process-by-ename arg0) - (set-vector! (-> (-> (the process-drawable (process-by-ename arg0))root)trans) (-> (target-pos 0) x) (-> (target-pos 0) y) (-> (target-pos 0) z) 1.0) + (set-vector! (-> (-> (the process-drawable (process-by-ename arg0)) root) trans) + (-> (target-pos 0) x) + (-> (target-pos 0) y) + (-> (target-pos 0) z) + 1.0) (if (type-type? (-> (process-by-ename arg0) type) crate) - (begin - (set! (-> (the crate (process-by-ename arg0)) base y) (-> (target-pos 0) y)) - ) - (none) - ) - - (if (type-type? (-> (process-by-ename arg0) type) money) - (begin - (set! (-> (the money (process-by-ename arg0)) base y) (-> (target-pos 0) y)) - ) - (none) - ) - - (if (type-type? (-> (process-by-ename arg0) type) fuel-cell) - (begin - (set! (-> (the fuel-cell (process-by-ename arg0)) base y) (-> (target-pos 0) y)) - ) - (none) - ) - ) -) + (begin + (set! (-> (the crate (process-by-ename arg0)) base y) (-> (target-pos 0) y))) + (none)) + (if (type-type? (-> (process-by-ename arg0) type) money) + (begin + (set! (-> (the money (process-by-ename arg0)) base y) (-> (target-pos 0) y))) + (none)) + (if (type-type? (-> (process-by-ename arg0) type) fuel-cell) + (begin + (set! (-> (the fuel-cell (process-by-ename arg0)) base y) (-> (target-pos 0) y))) + (none)))) ;; quick macro for setting vector xyz in meters, leaving w alone (defmacro set-vector-meters! (dst x y z) - `(set-vector! ,dst (meters ,x) (meters ,y) (meters ,z) (-> ,dst w)) - ) + `(set-vector! ,dst (meters ,x) (meters ,y) (meters ,z) (-> ,dst w))) ;; quick macro for constructing static vector with w=1 (defmacro static-vector-meters (x y z) - `(new 'static 'vector :x (meters ,x) :y (meters ,y) :z (meters ,z) :w 1.0) - ) + `(new 'static 'vector :x (meters ,x) :y (meters ,y) :z (meters ,z) :w 1.0)) ;; prints vector xyz in meters (defmacro print-vector-meters (vec &key (dst #t)) - `(format ,dst "~m ~m ~m~%" (-> ,vec x) (-> ,vec y) (-> ,vec z)) - ) + `(format ,dst "~m ~m ~m~%" (-> ,vec x) (-> ,vec y) (-> ,vec z))) ;; takes a path-control and xyz values to offsets every node in the path by (defmacro shift-path! (path x y z) `(let ((voff (static-vector-meters ,x ,y ,z))) (dotimes (idx (-> ,path num-cverts)) - (vector+! (-> ,path cverts idx) (-> ,path cverts idx) voff) - ) - ) - ) + (vector+! (-> ,path cverts idx) (-> ,path cverts idx) voff)))) ;; prints all the nodes in a path in meters (defmacro path-print-meters (path) `(dotimes (idx (-> ,path num-cverts)) - (print-vector-meters (-> ,path cverts idx)) - ) - ) + (print-vector-meters (-> ,path cverts idx)))) ;; prints the position (root trans) of a process-drawable (defmacro pd-pos-m (procname) `(let* ((obj (the process-drawable (process-by-ename ,procname))) - (vec (-> obj root trans))) + (vec (-> obj root trans))) (format 0 "~m ~m ~m~%" (-> vec x) (-> vec y) (-> vec z)) - (none) - ) - ) + (none))) ;;This function moves an actor based on jaks position + an offset (defun move-to-behind-jak ((arg0 string) (arg1 meters) (arg2 meters)) - (when (process-by-ename arg0) - (set-vector! (-> (-> (the process-drawable (process-by-ename arg0))root)trans) (-(-> (target-pos 0) x) (meters arg1)) (+ (-> (target-pos 0) y) (meters arg2)) (-(-> (target-pos 0) z)(meters arg1)) 1.0) + (when (process-by-ename arg0) + (set-vector! (-> (-> (the process-drawable (process-by-ename arg0)) root) trans) + (- (-> (target-pos 0) x) (meters arg1)) + (+ (-> (target-pos 0) y) (meters arg2)) + (- (-> (target-pos 0) z) (meters arg1)) + 1.0) (if (type-type? (-> (process-by-ename arg0) type) money) - (begin - (set! (-> (the money (process-by-ename arg0)) base y) (-> (target-pos 0) y) ) - ) - (none) - ) + (begin + (set! (-> (the money (process-by-ename arg0)) base y) (-> (target-pos 0) y))) + (none)) (if (type-type? (-> (process-by-ename arg0) type) fuel-cell) - (begin - (set! (-> (the fuel-cell (process-by-ename arg0)) base y) (-> (target-pos 0) y) ) - ) - (none) - ) - ) -) + (begin + (set! (-> (the fuel-cell (process-by-ename arg0)) base y) (-> (target-pos 0) y))) + (none)))) ;;This turns on play hints (defun turnonplayhints () -(set! (-> *setting-control* default play-hints) #t) -) + (set! (-> *setting-control* default play-hints) #t)) ;;This turns off playhints -(defun turnoffplayhints() -(set! (-> *setting-control* default play-hints) #f) -) +(defun turnoffplayhints () + (set! (-> *setting-control* default play-hints) #f)) ;;This turns on collision render when called -(defun turnonCollisionmode() +(defun turnonCollisionmode () (set! *collision-renderer* #t) - (logclear! *vu1-enable-user-menu* (vu1-renderer-mask tfrag trans-tfrag tie tie-near)) -) + (logclear! *vu1-enable-user-menu* (vu1-renderer-mask tfrag trans-tfrag tie tie-near))) ;;This turns off collision render when called -(defun turnoffCollisionmode() +(defun turnoffCollisionmode () (set! *collision-renderer* #f) - (logior! *vu1-enable-user-menu* (vu1-renderer-mask tfrag trans-tfrag tie tie-near)) -) + (logior! *vu1-enable-user-menu* (vu1-renderer-mask tfrag trans-tfrag tie tie-near))) ;;This makes it thunder in the current level -(defun thunderTime() - (set! (-> (level-get-target-inside *level*) mood-func)update-mood-village2) - (set! (-> (level-get-target-inside *level*) mood) *village2-mood*) -) +(defun thunderTime () + (set! (-> (level-get-target-inside *level*) mood-func) update-mood-village2) + (set! (-> (level-get-target-inside *level*) mood) *village2-mood*)) ;;This makes the current level dark when called -(defun DarkesetGlitchTime() - (set! (-> (level-get-target-inside *level*) mood-func)update-mood-finalboss ) - (set! (-> (level-get-target-inside *level*) mood) *finalboss-mood*) -) +(defun DarkesetGlitchTime () + (set! (-> (level-get-target-inside *level*) mood-func) update-mood-finalboss) + (set! (-> (level-get-target-inside *level*) mood) *finalboss-mood*)) ;;This needs fixed -(defun rainyTime() - (set! (-> (level-get-target-inside *level*) mood-func)update-mood-swamp) - (set! (-> (level-get-target-inside *level*) mood) *swamp-mood*) -) +(defun rainyTime () + (set! (-> (level-get-target-inside *level*) mood-func) update-mood-swamp) + (set! (-> (level-get-target-inside *level*) mood) *swamp-mood*)) ;;This needs fixed -(defun snowingTime() - (set! (-> (level-get-target-inside *level*) mood-func)update-mood-snow) - (set! (-> (level-get-target-inside *level*) mood) *snow-mood*) -) +(defun snowingTime () + (set! (-> (level-get-target-inside *level*) mood-func) update-mood-snow) + (set! (-> (level-get-target-inside *level*) mood) *snow-mood*)) ;;This makes the current levels weather the same as village1 -(defun defaultWeatherTime() - (set! (-> (level-get-target-inside *level*) mood-func)update-mood-village1) - (set! (-> (level-get-target-inside *level*) mood) *village1-mood*) -) +(defun defaultWeatherTime () + (set! (-> (level-get-target-inside *level*) mood-func) update-mood-village1) + (set! (-> (level-get-target-inside *level*) mood) *village1-mood*)) ;;This moves jak to a provided coordinate example call ;;(tp-jak 0.0 12.0 32.32) -(defun tp-jak ((arg0 float)(arg1 float)(arg2 float)) +(defun tp-jak ((arg0 float) (arg1 float) (arg2 float)) (set! (-> (target-pos 0) x) (meters arg0)) (set! (-> (target-pos 0) y) (meters arg1)) - (set! (-> (target-pos 0) z) (meters arg2)) -) + (set! (-> (target-pos 0) z) (meters arg2))) ;;This returns true or false depending on if jak is within a provided distance from an actor (defun close? ((actor-ename string) (dist float)) - (and - (process-by-ename actor-ename) - (<= - (vector-vector-distance - (target-pos 0) - (-> (the process-drawable (process-by-ename actor-ename)) root trans) - ) - dist - ) - ) - ) - + (and (process-by-ename actor-ename) + (<= (vector-vector-distance (target-pos 0) (-> (the process-drawable (process-by-ename actor-ename)) root trans)) dist))) ;; This returns true or false if jak is within a bubble defined by coordinates and width (defun in-bubble? ((x float) (y float) (z float) (w float)) - (<= - (vector-vector-distance - (target-pos 0) - (set-vector! (new-stack-vector0) x y z 1.0) - ) - (/ w 2.0) - ) - ) + (<= (vector-vector-distance (target-pos 0) (set-vector! (new-stack-vector0) x y z 1.0)) (/ w 2.0))) (defun music-manager () (stop-main-music) - (case (-> (level-get-target-inside *level*) name) - (('test-zone) - ;; (if (> (knuth-rand-int-range 0 15) (+ 8 5)) - ;; (play-main-music "SND/music-test-zone.mp3" (the int (-> *setting-control* default music-volume))) - ;; (play-main-music "SND/music-test-zone-track2.mp3" (the int (-> *setting-control* default music-volume)))) - ) - ;;Add more cases here for each level - (else - (play-main-music "" (the int (-> *setting-control* default music-volume))) - ;;(stop-main-music) This function is broken but playing a invalid sound does the same thing - ) - ) -(none) -) + (case (-> (level-get-target-inside *level*) name) + (('test-zone) + ;; (if (> (knuth-rand-int-range 0 15) (+ 8 5)) + ;; (play-main-music "SND/music-test-zone.mp3" (the int (-> *setting-control* default music-volume))) + ;; (play-main-music "SND/music-test-zone-track2.mp3" (the int (-> *setting-control* default music-volume)))) + ) + ;;Add more cases here for each level + (else + (play-main-music "" (the int (-> *setting-control* default music-volume))) + ;;(stop-main-music) This function is broken but playing a invalid sound does the same thing + )) + (none)) (defbehavior music-manager-proc process () (music-manager) - (none) -) + (none)) (define *pc-temp-vector* (new 'static 'vector :x 1.0 :y 1.0 :z 1.0)) + (defun get-joint-pos-by-name ((actor process-drawable) (name string)) (when actor - (dotimes (i (-> actor node-list length)) - (when (string= (-> actor node-list data i joint name) name) - (return (the-as vector (vector<-cspace! *pc-temp-vector* (-> actor node-list data i)))) - (the-as vector (new-stack-vector0))) - ) - (the-as vector (new-stack-vector0)) -)) + (dotimes (i (-> actor node-list length)) + (when (string= (-> actor node-list data i joint name) name) + (return (the-as vector (vector<-cspace! *pc-temp-vector* (-> actor node-list data i)))) + (the-as vector (new-stack-vector0)))) + (the-as vector (new-stack-vector0)))) (defun print-joint-names ((actor process-drawable)) (format #t (string-format "Actor: ~S has these ~D Joints:~%" (-> actor name) (-> actor node-list length))) (dotimes (i (-> actor node-list length)) - (format #t (string-format "~D. ~S~%" i (-> actor node-list data i joint name)))) - (none) -) + (format #t (string-format "~D. ~S~%" i (-> actor node-list data i joint name)))) + (none)) + ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Jak Color functions ;;;;;;;;;;;;;;;;;;;;;;;;;; (defun draw-xyz ((jak target) (x float) (y float) (z float)) (set! (-> jak draw color-mult x) x) (set! (-> jak draw color-mult y) y) - (set! (-> jak draw color-mult z) z) -) + (set! (-> jak draw color-mult z) z)) + (defun draw-normal ((jak target)) - (draw-xyz jak 1.0 1.0 1.0) -) + (draw-xyz jak 1.0 1.0 1.0)) + (defun draw-white ((jak target)) - (draw-xyz jak 10.0 10.0 10.0) -) + (draw-xyz jak 10.0 10.0 10.0)) + (defun draw-black ((jak target)) - (draw-xyz jak 0.0 0.0 0.0) -) + (draw-xyz jak 0.0 0.0 0.0)) + (defun draw-red ((jak target)) - (draw-xyz jak 3.0 0.0 0.0) -) + (draw-xyz jak 3.0 0.0 0.0)) + (defun draw-green ((jak target)) - (draw-xyz jak 0.0 3.0 0.0) -) + (draw-xyz jak 0.0 3.0 0.0)) + (defun draw-blue ((jak target)) - (draw-xyz jak 0.0 0.0 3.0) -) + (draw-xyz jak 0.0 0.0 3.0)) + (defun draw-yellow ((jak target)) - (draw-xyz jak 3.0 3.0 0.0) -) + (draw-xyz jak 3.0 3.0 0.0)) + (defun draw-pink ((jak target)) - (draw-xyz jak 3.0 0.0 3.0) -) + (draw-xyz jak 3.0 0.0 3.0)) + (defun draw-light-blue ((jak target)) - (draw-xyz jak 0.0 3.0 3.0) -) + (draw-xyz jak 0.0 3.0 3.0)) ;; Helper functions for spawning orbs (used by orb placer in debug mode) @@ -475,21 +387,12 @@ if the result of rand-vu-int-range is 1, then DANCE! if it is not 1, then Don't (set! (-> fax pickup-amount) amount) (set! (-> fax pickup-spawn-amount) amount) (set! (-> fax fade-time) (the-as time-frame 0)) - (let ((proc (the money (ppointer->process (birth-pickup-at-point vec (pickup-type money) amount #t *active-pool* fax))))) (when bob? - (set! (-> proc bob-amount) 1024.0) - ) + (set! (-> proc bob-amount) 1024.0)) (format 0 "spawned ~A~%" proc) ;; return handle to the orb - (process->handle proc) - ) - ) - ) + (process->handle proc)))) (defun spawn-money-meters ((x float) (y float) (z float) (amount float) (bob? symbol)) - (let ((vec (new 'stack-no-clear 'vector))) - (set-vector-meters! vec x y z) - (spawn-money vec amount bob?) - ) - ) \ No newline at end of file + (let ((vec (new 'stack-no-clear 'vector))) (set-vector-meters! vec x y z) (spawn-money vec amount bob?))) diff --git a/goal_src/jak1/engine/mods/mod-custom-code.gc b/goal_src/jak1/engine/mods/mod-custom-code.gc index a9faf972b7..71d631c764 100644 --- a/goal_src/jak1/engine/mods/mod-custom-code.gc +++ b/goal_src/jak1/engine/mods/mod-custom-code.gc @@ -1,144 +1,101 @@ - ;;-*-Lisp-*- - (in-package goal) +;;-*-Lisp-*- +(in-package goal) - ;; name: mod-custom-code.gc - ;; name in dgo: mod-custom-code - ;; dgos: TODO +;; name: mod-custom-code.gc +;; name in dgo: mod-custom-code +;; dgos: TODO +;;;;;;;;;;;;;;;;;;;;;;;;;; +;; What is this file for. +;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; What is this file for. - ;;;;;;;;;;;;;;;;;;;;;;;;;; - - #| This file contains function defenitions that are pre placed in the mod base, +#| + This file contains function defenitions that are pre placed in the mod base, so if you place custom code inside of these functions, it will exectue based on the name of the function, for example, if you place (set! (-> *game-info* fuel) (+ (-> *game-info* fuel) 1)) to the function named runs-on-orb-pickup, then jaks powercell count will increase each time you collect - an orb |# - - - ;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Begin function defintions. - ;;;;;;;;;;;;;;;;;;;;;;;;;; - - (defun runs-every-frame () - ;;(increase-power-cell-by-one) This is a call to increase-power-cell-by-one defined in mod-common-functions.gc - - (if *show-input-display* - (input-display-on) - (input-display-off) - ) - - ;; ensure orb-placer is spawned/killed as requested, debug menu is updated - (when *debug-segment* - (orb-placer-maintenance) - ) - - (none) - ) - - (defun runs-on-orb-pickup ((parent process-tree)) - (let* ((from-cache? (and parent (type-type? (-> parent type) orb-cache-top)))) - ;; Code here runs on ANY orb pickup - - - (when from-cache? - ;; Code here runs only if the orb was from an orb cache - - ) - - (when (not from-cache?) - ;; Code here runs only if the orb was NOT from an orb cache - - ) - ) - (none) - ) - - (defun runs-on-fly-pickup () - ;; Code here runs on any scout fly pickup - - (none) + an orb +|# + +;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Begin function defintions. +;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun runs-every-frame () + ;;(increase-power-cell-by-one) This is a call to increase-power-cell-by-one defined in mod-common-functions.gc + (if *show-input-display* (input-display-on) (input-display-off)) + ;; ensure orb-placer is spawned/killed as requested, debug menu is updated + (when *debug-segment* + (orb-placer-maintenance)) + (none)) + +(defun runs-on-orb-pickup ((parent process-tree)) + (let* ((from-cache? (and parent (type-type? (-> parent type) orb-cache-top)))) + ;; Code here runs on ANY orb pickup + (when from-cache? + ;; Code here runs only if the orb was from an orb cache ) - - (defun runs-on-cell-pickup ((cell-event symbol)) - (case cell-event - (('pickup) - ;; Code here runs as soon as you pickup a powercell - - ) - (('cutscene-end) - ;; Code here runs at the end of any powercell cutscene - - ) - ) - - (none) - ) - - (defun runs-on-eco-pickup ((eco-type pickup-type) (parent process-tree)) - (let* ((from-vent? (and parent (type-type? (-> parent type) vent)))) - ;; Code here runs as soon as you pickup ANY eco - - (case eco-type - (((pickup-type eco-yellow)) - ;; Code here runs as soon as you pickup yellow eco - - ) - (((pickup-type eco-red)) - ;; Code here runs as soon as you pickup red eco - - ) - (((pickup-type eco-blue)) - ;; Code here runs as soon as you pickup blue eco - - ) - (((pickup-type eco-pill)) - ;; Code here runs as soon as you pickup small green eco - - ) - (((pickup-type eco-green)) - ;; Code here runs as soon as you pickup big green eco - - ) - ) - - (when from-vent? - ;; Code here runs only if the eco was picked up from a vent - - ) - ) - - (none) - ) - - (defun runs-on-jak-spawn () - ;; Code here runs every time jak spawns (loading a file new game or death) - - ;;uncomment this to use custom music for custom levels - the function is in mod-common-functions.gc - ;;(process-spawn-function process music-manager-proc) - (none) - ) - - (defun runs-on-jak-death ((death-event symbol)) - (case death-event - (('dying) - ;; Code here runs immediately every time jak dies, before any death animation or death cutscene - - ) - (('blackout) - ;; Code here runs after jak dies (and any death cutscene finishes), during the blackout before he spawns - - ) - ) - - (none) - ) - - - ;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; deprecated function defintions. - ;;;;;;;;;;;;;;;;;;;;;;;;;; - - #| these are no longer recommended/supported however we include them anyways to not break anyones mods. - |# \ No newline at end of file + (when (not from-cache?) + ;; Code here runs only if the orb was NOT from an orb cache + )) + (none)) + +(defun runs-on-fly-pickup () + ;; Code here runs on any scout fly pickup + (none)) + +(defun runs-on-cell-pickup ((cell-event symbol)) + (case cell-event + (('pickup) + ;; Code here runs as soon as you pickup a powercell + ) + (('cutscene-end) + ;; Code here runs at the end of any powercell cutscene + )) + (none)) + +(defun runs-on-eco-pickup ((eco-type pickup-type) (parent process-tree)) + (let* ((from-vent? (and parent (type-type? (-> parent type) vent)))) + ;; Code here runs as soon as you pickup ANY eco + (case eco-type + (((pickup-type eco-yellow)) + ;; Code here runs as soon as you pickup yellow eco + ) + (((pickup-type eco-red)) + ;; Code here runs as soon as you pickup red eco + ) + (((pickup-type eco-blue)) + ;; Code here runs as soon as you pickup blue eco + ) + (((pickup-type eco-pill)) + ;; Code here runs as soon as you pickup small green eco + ) + (((pickup-type eco-green)) + ;; Code here runs as soon as you pickup big green eco + )) + (when from-vent? + ;; Code here runs only if the eco was picked up from a vent + )) + (none)) + +(defun runs-on-jak-spawn () + ;; Code here runs every time jak spawns (loading a file new game or death) + ;;uncomment this to use custom music for custom levels - the function is in mod-common-functions.gc + ;;(process-spawn-function process music-manager-proc) + (none)) + +(defun runs-on-jak-death ((death-event symbol)) + (case death-event + (('dying) + ;; Code here runs immediately every time jak dies, before any death animation or death cutscene + ) + (('blackout) + ;; Code here runs after jak dies (and any death cutscene finishes), during the blackout before he spawns + )) + (none)) + +;;;;;;;;;;;;;;;;;;;;;;;;;; +;; deprecated function defintions. +;;;;;;;;;;;;;;;;;;;;;;;;;; + +#| these are no longer recommended/supported however we include them anyways to not break anyones mods. |# diff --git a/goal_src/jak1/engine/mods/mod-debug.gc b/goal_src/jak1/engine/mods/mod-debug.gc index feec7bb609..4c62a74b47 100644 --- a/goal_src/jak1/engine/mods/mod-debug.gc +++ b/goal_src/jak1/engine/mods/mod-debug.gc @@ -10,7 +10,6 @@ (defun-debug debug-menu-make-modding-tools-menu ((ctx debug-menu-context)) (let ((modding-tools-menu (new 'debug 'debug-menu ctx "Modding Tools"))) - ;; orb-placer menu (let ((orb-placer-menu (new 'debug 'debug-menu ctx "Orb Placer"))) (debug-menu-append-item orb-placer-menu (new-dm-bool "Edit Mode?" *orb-placer-enabled?* dm-boolean-toggle-pick-func)) @@ -18,17 +17,11 @@ (let ((select-orb-menu (new 'debug 'debug-menu ctx "Select Orb"))) (set! *orb-placer-select-menu* select-orb-menu) ;; populated on orb add - (debug-menu-append-item orb-placer-menu (new-dm-submenu "Select Orb" select-orb-menu)) - ) + (debug-menu-append-item orb-placer-menu (new-dm-submenu "Select Orb" select-orb-menu))) (debug-menu-append-item orb-placer-menu (new-dm-func "Print Selected Orb Position" #f orb-placer-print-selected)) (debug-menu-append-item orb-placer-menu (new-dm-func "Print All Orb Positions" #f orb-placer-print-all)) - - (debug-menu-append-item modding-tools-menu (new-dm-submenu "Orb Placer" orb-placer-menu)) - ) - (new-dm-submenu "Modding Tools" modding-tools-menu) - ) - ) + (debug-menu-append-item modding-tools-menu (new-dm-submenu "Orb Placer" orb-placer-menu))) + (new-dm-submenu "Modding Tools" modding-tools-menu))) (when (-> *debug-menu-context* root-menu) - (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-modding-tools-menu *debug-menu-context*)) - ) \ No newline at end of file + (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-modding-tools-menu *debug-menu-context*))) diff --git a/goal_src/jak1/engine/mods/mod-settings.gc b/goal_src/jak1/engine/mods/mod-settings.gc index 568212e05c..dc9049ab17 100644 --- a/goal_src/jak1/engine/mods/mod-settings.gc +++ b/goal_src/jak1/engine/mods/mod-settings.gc @@ -9,17 +9,17 @@ ;; What is this file for. ;;;;;;;;;;;;;;;;;;;;;;;;;; -#| This file is a place where you can define custom functions and GOAL code +#| + This file is a place where you can define custom functions and GOAL code to call inside of mod-custom-code.gc for example I have defined a function that increases the powercell count by one when it is called - |# - +|# ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Useful GOAL modding documentation ;;;;;;;;;;;;;;;;;;;;;;;;;; -#| +#| Checks the condition and if it is true it does first argument if false it does optional second argument (if (condition) (do if true) (do if false)) @@ -29,15 +29,13 @@ Gives a random FLOAT or INT between the provided ranges when called if the result of rand-vu-int-range is 1, then DANCE! if it is not 1, then Don't dance (if (= (rand-vu-int-range 0 10) 1) (DANCE!) (Don't dance)) - - |# ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Define Settings to use in mods ;;;;;;;;;;;;;;;;;;;;;;;;;; -(define startingDebugContinuePoint "village1-hut") +(define *debug-continue-point* "village1-hut") ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Define Custom Settings Variables to use in mods @@ -54,4 +52,4 @@ if the result of rand-vu-int-range is 1, then DANCE! if it is not 1, then Don't ;; do NOT change %MODVERSIONPLACEHOLDER% below, otherwise the mod-bundling-tools ;; will be unable to automatically add version info to the speedrun display -(define *mod-version-text* "%MODVERSIONPLACEHOLDER%") \ No newline at end of file +(define *mod-version-text* "%MODVERSIONPLACEHOLDER%") diff --git a/goal_src/jak1/engine/mods/orb-placer.gc b/goal_src/jak1/engine/mods/orb-placer.gc index 430f6463b5..32649efbb3 100644 --- a/goal_src/jak1/engine/mods/orb-placer.gc +++ b/goal_src/jak1/engine/mods/orb-placer.gc @@ -1,5 +1,4 @@ (in-package goal) - (declare-file (debug)) ;; controls whether the orb-placer process will run @@ -17,108 +16,113 @@ ;; array of handles to orbs that have been spawned by orb-placer (define *orb-placer-orbs* (new 'global 'boxed-array handle ORB_PLACER_MAX)) -(define *orb-placer-temp-strs* (new 'static 'boxed-array :type string :length ORB_PLACER_MAX - "orba-00" - "orba-01" - "orba-02" - "orba-03" - "orba-04" - "orba-05" - "orba-06" - "orba-07" - "orba-08" - "orba-09" - "orba-10" - "orba-11" - "orba-12" - "orba-13" - "orba-14" - "orba-15" - "orba-16" - "orba-17" - "orba-18" - "orba-19" - "orba-20" - "orba-21" - "orba-22" - "orba-23" - "orba-24" - "orba-25" - "orba-26" - "orba-27" - "orba-28" - "orba-29" - "orba-30" - "orba-31" - "orba-32" - "orba-33" - "orba-34" - "orba-35" - "orba-36" - "orba-37" - "orba-38" - "orba-39" - "orba-40" - "orba-41" - "orba-42" - "orba-43" - "orba-44" - "orba-45" - "orba-46" - "orba-47" - "orba-48" - "orba-49" - "orba-50" - "orba-51" - "orba-52" - "orba-53" - "orba-54" - "orba-55" - "orba-56" - "orba-57" - "orba-58" - "orba-59" - "orba-60" - "orba-61" - "orba-62" - "orba-63" - "orba-64" - "orba-65" - "orba-66" - "orba-67" - "orba-68" - "orba-69" - "orba-70" - "orba-71" - "orba-72" - "orba-73" - "orba-74" - "orba-75" - "orba-76" - "orba-77" - "orba-78" - "orba-79" - "orba-80" - "orba-81" - "orba-82" - "orba-83" - "orba-84" - "orba-85" - "orba-86" - "orba-87" - "orba-88" - "orba-89" - "orba-90" - "orba-91" - "orba-92" - "orba-93" - "orba-94" - "orba-95" - "orba-96" - "orba-97" - "orba-98" - "orba-99" - )) +(define *orb-placer-temp-strs* + (new 'static + 'boxed-array + :type + string + :length + ORB_PLACER_MAX + "orba-00" + "orba-01" + "orba-02" + "orba-03" + "orba-04" + "orba-05" + "orba-06" + "orba-07" + "orba-08" + "orba-09" + "orba-10" + "orba-11" + "orba-12" + "orba-13" + "orba-14" + "orba-15" + "orba-16" + "orba-17" + "orba-18" + "orba-19" + "orba-20" + "orba-21" + "orba-22" + "orba-23" + "orba-24" + "orba-25" + "orba-26" + "orba-27" + "orba-28" + "orba-29" + "orba-30" + "orba-31" + "orba-32" + "orba-33" + "orba-34" + "orba-35" + "orba-36" + "orba-37" + "orba-38" + "orba-39" + "orba-40" + "orba-41" + "orba-42" + "orba-43" + "orba-44" + "orba-45" + "orba-46" + "orba-47" + "orba-48" + "orba-49" + "orba-50" + "orba-51" + "orba-52" + "orba-53" + "orba-54" + "orba-55" + "orba-56" + "orba-57" + "orba-58" + "orba-59" + "orba-60" + "orba-61" + "orba-62" + "orba-63" + "orba-64" + "orba-65" + "orba-66" + "orba-67" + "orba-68" + "orba-69" + "orba-70" + "orba-71" + "orba-72" + "orba-73" + "orba-74" + "orba-75" + "orba-76" + "orba-77" + "orba-78" + "orba-79" + "orba-80" + "orba-81" + "orba-82" + "orba-83" + "orba-84" + "orba-85" + "orba-86" + "orba-87" + "orba-88" + "orba-89" + "orba-90" + "orba-91" + "orba-92" + "orba-93" + "orba-94" + "orba-95" + "orba-96" + "orba-97" + "orba-98" + "orba-99")) ;; global for this so we can repopulate it as needed (define *orb-placer-select-menu* (the-as debug-menu #f)) @@ -127,37 +131,26 @@ (when (= msg (debug-menu-msg press)) (cond ((= *orb-placer-selected-idx* idx) - ;; deselect - (set! *orb-placer-selected-idx* -1) - (set! *orb-placer-enabled?* #f) - ) + ;; deselect + (set! *orb-placer-selected-idx* -1) + (set! *orb-placer-enabled?* #f)) (else - ;; select - (set! *orb-placer-selected-idx* idx) - (set! *orb-placer-enabled?* #t) - ) - ) - ) - (= *orb-placer-selected-idx* idx) - ) + ;; select + (set! *orb-placer-selected-idx* idx) + (set! *orb-placer-enabled?* #t)))) + (= *orb-placer-selected-idx* idx)) (defun orb-placer-highlight ((orb money) (highlight? symbol)) - (cond + (cond (highlight? - (set-vector! (-> orb draw color-mult) 0.8 0.8 0.0 1.0) - (set-vector! (-> orb draw color-emissive) 0.0 1.0 0.2 1.0) - ) - (else - (set-vector! (-> orb draw color-mult) 0.8 0.8 0.8 1.0) - (set-vector! (-> orb draw color-emissive) 0.2 0.2 0.2 1.0) - ) - ) - (none) - ) + (set-vector! (-> orb draw color-mult) 0.8 0.8 0.0 1.0) + (set-vector! (-> orb draw color-emissive) 0.0 1.0 0.2 1.0)) + (else (set-vector! (-> orb draw color-mult) 0.8 0.8 0.8 1.0) (set-vector! (-> orb draw color-emissive) 0.2 0.2 0.2 1.0))) + (none)) (defun orb-placer-list-maintenace ((update-debug-list? symbol)) - (when update-debug-list? (debug-menu-remove-all-items *orb-placer-select-menu*)) - + (when update-debug-list? + (debug-menu-remove-all-items *orb-placer-select-menu*)) (dotimes (i *orb-placer-count*) (let ((orb-handle (-> *orb-placer-orbs* i)) (is-selected? (and *orb-placer-enabled?* (= i *orb-placer-selected-idx*)))) @@ -165,41 +158,23 @@ (let ((orb-proc (the money (handle->process orb-handle)))) (when (and orb-proc (!= (-> orb-proc next-state name) 'dead-state) (!= (-> orb-proc next-state name) 'hud-collecting)) ;; ensure correct highlighting - (orb-placer-highlight - orb-proc - is-selected? - ) - + (orb-placer-highlight orb-proc is-selected?) ;; draw z-debug text - (add-debug-text-3d - #t - (bucket-id debug-no-zbuf) - (-> *orb-placer-temp-strs* i) - (-> orb-proc base) - (if is-selected? (font-color red) (font-color white)) - (new 'static 'vector2h :y 16) - ) - + (add-debug-text-3d #t + (bucket-id debug-no-zbuf) + (-> *orb-placer-temp-strs* i) + (-> orb-proc base) + (if is-selected? (font-color red) (font-color white)) + (new 'static 'vector2h :y 16)) (when update-debug-list? ;; append to debug menu list (let ((orb-menu-item (new-dm-flag (-> *orb-placer-temp-strs* i) i dm-orb-placer-select-func))) (debug-menu-append-item *orb-placer-select-menu* orb-menu-item) (when is-selected? - (set! (-> *orb-placer-select-menu* selected-item) orb-menu-item) - ) - ) - ) - ) - ) - ) - ) - ) - + (set! (-> *orb-placer-select-menu* selected-item) orb-menu-item))))))))) (when update-debug-list? - (set! (-> *orb-placer-select-menu* items) (sort (-> *orb-placer-select-menu* items) debug-menu-node *orb-placer-select-menu* items) (sort (-> *orb-placer-select-menu* items) debug-menu-node *target* root trans)) - (+! (-> vec y) (meters 2.0)) ;; dont spawn in ground - ) + ;; jak exists, use his position + (vector-copy! vec (-> *target* root trans)) + (+! (-> vec y) (meters 2.0)) ;; dont spawn in ground + ) (else - ;; use camera position - (vector-copy! vec (-> *math-camera* trans)) - ) - ) + ;; use camera position + (vector-copy! vec (-> *math-camera* trans)))) ;; convert the camera angle from a matrix to a quaternion (???) (matrix->quaternion camera-quat (-> *camera-combiner* inv-camera-rot)) ;; convert the quaternion to a vector representing rotation around z axis (isnt it the y axis in GOAL tho?) (vector-z-quaternion! camera-z-vector camera-quat) ;; shift orb's position with camera angle, by 3m (vector+! vec vec (vector-normalize! camera-z-vector (meters 3.0))) - ;; spawn and update orb-placer data (let ((orb-handle (spawn-money vec 1.0 #t))) (when (nonzero? orb-handle) @@ -232,24 +204,15 @@ (set! *orb-placer-selected-idx* *orb-placer-count*) (orb-placer-highlight (the money (handle->process orb-handle)) #t) (+! *orb-placer-count* 1) - (orb-placer-list-maintenace #t) - ) - ) - ) - ) - (none) - ) + (orb-placer-list-maintenace #t))))) + (none)) (defun orb-placer-print-selected () (when (and (>= *orb-placer-selected-idx* 0) (nonzero? (-> *orb-placer-orbs* *orb-placer-selected-idx*))) (let ((orb (the money (handle->process (-> *orb-placer-orbs* *orb-placer-selected-idx*))))) (when orb - (format 0 " ~m, ~m, ~m~%" (-> orb base x) (-> orb base y) (-> orb base z)) - ) - ) - ) - (none) - ) + (format 0 " ~m, ~m, ~m~%" (-> orb base x) (-> orb base y) (-> orb base z))))) + (none)) (defun orb-placer-print-all () (format 0 "|------------orba start------------|~%") @@ -257,144 +220,82 @@ (let ((orb-handle (-> *orb-placer-orbs* i))) (when (and (nonzero? orb-handle) (handle->process orb-handle)) (let ((orb (the money (handle->process orb-handle)))) - (format 0 " ~m, ~m, ~m~%" (-> orb base x) (-> orb base y) (-> orb base z)) - ) - ) - ) - ) + (format 0 " ~m, ~m, ~m~%" (-> orb base x) (-> orb base y) (-> orb base z)))))) (format 0 "|-------------orba end-------------|~%") - (none) - ) + (none)) ;; called from run-every-frame to ensure orb-placer is spawned/killed (define *orb-offset-tmp-vec* (new 'global 'vector)) + (defun orb-placer-maintenance () (when *debug-segment* (orb-placer-list-maintenace #f) - (when (and (not (paused?)) *orb-placer-enabled?*) - (with-dma-buffer-add-bucket ((buf (-> (current-frame) global-buf)) - (bucket-id subtitle)) - (draw-string-xy "Orb Placer Edit Mode" - buf 510 2 (font-color red) (font-flags right shadow kerning)))) - + (with-dma-buffer-add-bucket ((buf (-> (current-frame) global-buf)) (bucket-id subtitle)) + (draw-string-xy "Orb Placer Edit Mode" buf 510 2 (font-color red) (font-flags right shadow kerning)))) (cond ((process-by-name "orb-placer" *active-pool*) - ;; orb-placer exists - ;; if its not enabled, kill it - (when (not (and *debug-segment* *orb-placer-enabled?*)) - - (kill-by-name "orb-placer" *active-pool*) - - ;; make sure target is ungrabbed - (when (and *target* (= (-> *target* next-state name) 'target-grab)) - (send-event *target* 'end-mode) - ) - ;; release freecam if no target - (when (and (not *target*) (not (send-event *camera* 'query-state cam-free-floating))) - (send-event *camera* 'change-state cam-free-floating 0) - ) - ) - ) + ;; orb-placer exists + ;; if its not enabled, kill it + (when (not (and *debug-segment* *orb-placer-enabled?*)) + (kill-by-name "orb-placer" *active-pool*) + ;; make sure target is ungrabbed + (when (and *target* (= (-> *target* next-state name) 'target-grab)) + (send-event *target* 'end-mode)) + ;; release freecam if no target + (when (and (not *target*) (not (send-event *camera* 'query-state cam-free-floating))) + (send-event *camera* 'change-state cam-free-floating 0)))) (else - ;; orb-placer doesn't exist - ;; if its enabled, spawn it - (when (and *debug-segment* *orb-placer-enabled?*) - ;; process-spawn-function, spawns a process that runs the function you give it - (process-spawn-function process :name "orb-placer" - (lambda :behavior process () - (stack-size-set! (-> self top-thread) 512) - ;; Code before the loop runs once on process spawn - - (let ((pad (-> *cpad-list* cpads 0)) - (vec *orb-offset-tmp-vec*)) - (loop - ;; Loop runs once per frame while process is active - - ;; make sure target is grabbed - (when (and *target* (!= (-> *target* next-state name) 'target-grab)) - (send-event *target* 'change-mode 'grab) - ) - ;; lock freecam if no target - (when (and (not *target*) (not (send-event *camera* 'query-state cam-fixed))) - (send-event *camera* 'change-state cam-fixed 0) - ) - - ;; if we have an orb selected and the handle is nonzero... - (when (and (>= *orb-placer-selected-idx* 0) (nonzero? (-> *orb-placer-orbs* *orb-placer-selected-idx*))) - (let ((orb (the money (handle->process (-> *orb-placer-orbs* *orb-placer-selected-idx*))))) - (when orb - ;; highlight it - (orb-placer-highlight orb #t) - - ;; respond to controller input - - ;; X/Z based on camera - (when (nonzero? (-> pad stick0-speed)) - (set! (-> vec x) (sin (-> pad stick0-dir))) - (set! (-> vec y) 0.0) - (set! (-> vec z) (cos (-> pad stick0-dir))) - (set! (-> vec w) 0.0) - ;; camera magic - (vector-matrix*! vec vec (matrix-local->world #t #f)) - (vector-flatten! vec vec (-> *camera* local-down)) - (vector-float*! vec vec (* (-> pad stick0-speed) 512.0)) ;; TODO scale? - - ;; actually move orb - (vector+! (-> orb root trans) (-> orb root trans) vec) - (vector+! (-> orb base) (-> orb base) vec) - ) - - - (cond - ;; fine tune/axis-aligned X/Z - ((cpad-pressed? 0 down) - (+! (-> orb root trans z) (meters 0.03)) - (+! (-> orb base z) (meters 0.03)) - ) - ((cpad-pressed? 0 up) - (+! (-> orb root trans z) (meters -0.03)) - (+! (-> orb base z) (meters -0.03)) - ) - ((cpad-pressed? 0 right) - (+! (-> orb root trans x) (meters 0.03)) - (+! (-> orb base x) (meters 0.03)) - ) - ((cpad-pressed? 0 left) - (+! (-> orb root trans x) (meters -0.03)) - (+! (-> orb base x) (meters -0.03)) - ) - ;; Y (up/down) - ((cpad-hold? 0 r2) - (+! (-> orb root trans y) (meters 0.08)) - (+! (-> orb base y) (meters 0.08)) - ) - ((cpad-hold? 0 l2) - (+! (-> orb root trans y) (meters -0.08)) - (+! (-> orb base y) (meters -0.08)) - ) - ((cpad-pressed? 0 r1) - (+! (-> orb root trans y) (meters 0.03)) - (+! (-> orb base y) (meters 0.03)) - ) - ((cpad-pressed? 0 l1) - (+! (-> orb root trans y) (meters -0.03)) - (+! (-> orb base y) (meters -0.03)) - ) - ) - ) - ) - ) - - ;; Processes should suspend themselves, the loop will resume next frame - (suspend) - ) - ) - ) - ) - ) - ) - ) - ) - (none) - ) \ No newline at end of file + ;; orb-placer doesn't exist + ;; if its enabled, spawn it + (when (and *debug-segment* *orb-placer-enabled?*) + ;; process-spawn-function, spawns a process that runs the function you give it + (process-spawn-function process + :name "orb-placer" + (lambda :behavior process () + (stack-size-set! (-> self top-thread) 512) + ;; Code before the loop runs once on process spawn + (let ((pad (-> *cpad-list* cpads 0)) + (vec *orb-offset-tmp-vec*)) + (loop + ;; Loop runs once per frame while process is active + ;; make sure target is grabbed + (when (and *target* (!= (-> *target* next-state name) 'target-grab)) + (send-event *target* 'change-mode 'grab)) + ;; lock freecam if no target + (when (and (not *target*) (not (send-event *camera* 'query-state cam-fixed))) + (send-event *camera* 'change-state cam-fixed 0)) + ;; if we have an orb selected and the handle is nonzero... + (when (and (>= *orb-placer-selected-idx* 0) (nonzero? (-> *orb-placer-orbs* *orb-placer-selected-idx*))) + (let ((orb (the money (handle->process (-> *orb-placer-orbs* *orb-placer-selected-idx*))))) + (when orb + ;; highlight it + (orb-placer-highlight orb #t) + ;; respond to controller input + ;; X/Z based on camera + (when (nonzero? (-> pad stick0-speed)) + (set! (-> vec x) (sin (-> pad stick0-dir))) + (set! (-> vec y) 0.0) + (set! (-> vec z) (cos (-> pad stick0-dir))) + (set! (-> vec w) 0.0) + ;; camera magic + (vector-matrix*! vec vec (matrix-local->world #t #f)) + (vector-flatten! vec vec (-> *camera* local-down)) + (vector-float*! vec vec (* (-> pad stick0-speed) 512.0)) ;; TODO scale? + ;; actually move orb + (vector+! (-> orb root trans) (-> orb root trans) vec) + (vector+! (-> orb base) (-> orb base) vec)) + (cond + ;; fine tune/axis-aligned X/Z + ((cpad-pressed? 0 down) (+! (-> orb root trans z) (meters 0.03)) (+! (-> orb base z) (meters 0.03))) + ((cpad-pressed? 0 up) (+! (-> orb root trans z) (meters -0.03)) (+! (-> orb base z) (meters -0.03))) + ((cpad-pressed? 0 right) (+! (-> orb root trans x) (meters 0.03)) (+! (-> orb base x) (meters 0.03))) + ((cpad-pressed? 0 left) (+! (-> orb root trans x) (meters -0.03)) (+! (-> orb base x) (meters -0.03))) + ;; Y (up/down) + ((cpad-hold? 0 r2) (+! (-> orb root trans y) (meters 0.08)) (+! (-> orb base y) (meters 0.08))) + ((cpad-hold? 0 l2) (+! (-> orb root trans y) (meters -0.08)) (+! (-> orb base y) (meters -0.08))) + ((cpad-pressed? 0 r1) (+! (-> orb root trans y) (meters 0.03)) (+! (-> orb base y) (meters 0.03))) + ((cpad-pressed? 0 l1) (+! (-> orb root trans y) (meters -0.03)) (+! (-> orb base y) (meters -0.03))))))) + ;; Processes should suspend themselves, the loop will resume next frame + (suspend))))))))) + (none)) diff --git a/goal_src/jak1/engine/nav/navigate-h.gc b/goal_src/jak1/engine/nav/navigate-h.gc index 5fd5659683..29d3b4871f 100644 --- a/goal_src/jak1/engine/nav/navigate-h.gc +++ b/goal_src/jak1/engine/nav/navigate-h.gc @@ -127,8 +127,7 @@ (poly-count int32) (poly (inline-array nav-poly)) (route (inline-array vector4ub)) - (custom-hacky? symbol) - ) + (custom-hacky? symbol)) (:methods (tri-centroid-world (_type_ nav-poly vector) vector) ;; finds the centroid of the given triangle, in the "world" coordinate system. (tri-centroid-local (_type_ nav-poly vector) vector) ;; finds the centroid of the given triangle, in the local nav-mesh coordinate system. @@ -166,11 +165,23 @@ ;; not sure why it's separate from 27 (and such a different implementation). there might be some details I'm missing here. (is-in-mesh? (_type_ vector float meters) symbol))) -(defmethod inspect nav-mesh ((obj nav-mesh)) +(defmethod inspect nav-mesh + ((obj nav-mesh)) (format #t "(new 'static 'nav-mesh~%" obj (-> obj type)) - (format #t "~T:bounds (new 'static 'sphere :x (meters ~f) :y (meters ~f) :z (meters ~f) :w (meters ~f))~%" (/ (-> obj bounds x) 4096) (/ (-> obj bounds y) 4096) (/ (-> obj bounds z) 4096) (/ (-> obj bounds w) 4096)) - (format #t "~T:origin (new 'static 'vector :x (meters ~f) :y (meters ~f) :z (meters ~f) :w ~f)~%" (/ (-> obj origin x) 4096) (/ (-> obj origin y) 4096) (/ (-> obj origin z) 4096) (-> obj origin w)) - #|(format #t "~Tnode-count: ~D~%" (-> obj node-count)) + (format #t + "~T:bounds (new 'static 'sphere :x (meters ~f) :y (meters ~f) :z (meters ~f) :w (meters ~f))~%" + (/ (-> obj bounds x) 4096) + (/ (-> obj bounds y) 4096) + (/ (-> obj bounds z) 4096) + (/ (-> obj bounds w) 4096)) + (format #t + "~T:origin (new 'static 'vector :x (meters ~f) :y (meters ~f) :z (meters ~f) :w ~f)~%" + (/ (-> obj origin x) 4096) + (/ (-> obj origin y) 4096) + (/ (-> obj origin z) 4096) + (-> obj origin w)) + #| +(format #t "~Tnode-count: ~D~%" (-> obj node-count)) (let ((i 0)) (while (< i (-> obj node-count)) (format #t "~T--NODE ~d:~%" i) @@ -195,15 +206,19 @@ (format #t "~T----------~%" (&-> obj nodes i scale-x)) (+! i 1) ) - )|# + ) + |# (format #t "~T:vertex-count ~D~%" (-> obj vertex-count)) (format #t "~T:vertex (new 'static 'inline-array nav-vertex ~D~%" (-> obj vertex-count)) (let ((i 0)) (while (< i (-> obj vertex-count)) - (format #t "~T~T(new 'static 'nav-vertex :x (meters ~f) :y (meters ~f) :z (meters ~f) :w ~f)~%" (/ (-> obj vertex i x) 4096) (/ (-> obj vertex i y) 4096) (/ (-> obj vertex i z) 4096) (-> obj vertex i w)) - (+! i 1) - ) - ) + (format #t + "~T~T(new 'static 'nav-vertex :x (meters ~f) :y (meters ~f) :z (meters ~f) :w ~f)~%" + (/ (-> obj vertex i x) 4096) + (/ (-> obj vertex i y) 4096) + (/ (-> obj vertex i z) 4096) + (-> obj vertex i w)) + (+! i 1))) (format #t "~T)~%") (format #t "~T:poly-count ~D~%" (-> obj poly-count)) (format #t "~T:poly (new 'static 'inline-array nav-poly ~D~%" (-> obj poly-count)) @@ -211,37 +226,74 @@ (while (< i (-> obj poly-count)) (format #t "~T~T(new 'static 'nav-poly~%") (format #t "~T~T:id #x~X~%" (-> obj poly i id)) - (format #t "~T~T:vertex (new 'static 'array uint8 3 #x~X #x~X #x~X)~%" (-> obj poly i vertex 0) (-> obj poly i vertex 1) (-> obj poly i vertex 2)) - (format #t "~T~T:adj-poly (new 'static 'array uint8 3 #x~X #x~X #x~X)~%" (-> obj poly i adj-poly 0) (-> obj poly i adj-poly 1) (-> obj poly i adj-poly 2)) + (format #t + "~T~T:vertex (new 'static 'array uint8 3 #x~X #x~X #x~X)~%" + (-> obj poly i vertex 0) + (-> obj poly i vertex 1) + (-> obj poly i vertex 2)) + (format #t + "~T~T:adj-poly (new 'static 'array uint8 3 #x~X #x~X #x~X)~%" + (-> obj poly i adj-poly 0) + (-> obj poly i adj-poly 1) + (-> obj poly i adj-poly 2)) (format #t "~T~T:pat ~D~%" (-> obj poly i pat)) (format #t "~T~T)~%") - (+! i 1) - ) - ) + (+! i 1))) (format #t "~T)~%") (format #t "~T:node-count ~D~%" (-> obj node-count)) (format #t "~T:nodes (new 'static 'inline-array nav-node ~d~%" (-> obj node-count)) (let ((i 0)) - (while (< i (-> obj node-count)) - (format #t "~T~T(new 'static 'nav-node :center-x (meters ~f) :center-y (meters ~f) :center-z (meters ~f) :type ~d :parent-offset ~d~%" - (/ (-> obj nodes i center-x) 4096) (/ (-> obj nodes i center-y) 4096) (/ (-> obj nodes i center-z) 4096) (-> obj nodes i type) (-> obj nodes i parent-offset)) - (format #t "~T~T:center (new 'static 'vector :x (meters ~f) :y (meters ~f) :z (meters ~f) :w ~f)~%" - (/ (-> obj nodes i center x) 4096) (/ (-> obj nodes i center y) 4096) (/ (-> obj nodes i center z) 4096) (-> obj nodes i center w)) - (format #t "~T~T:radius-x (meters ~f) :radius-y (meters ~f) :radius-z (meters ~f)~%" - (/ (-> obj nodes i radius-x) 4096) (/ (-> obj nodes i radius-y) 4096) (/ (-> obj nodes i radius-z) 4096)) - (format #t "~T~T:left-offset ~d :right-offset ~d :num-tris ~d~%" - (-> obj nodes i left-offset) (-> obj nodes i right-offset) (-> obj nodes i num-tris)) - (format #t "~T~T:radius (new 'static 'vector :x (meters ~f) :y (meters ~f) :z (meters ~f) :w ~f) :scale-x (meters ~f)~%" - (/ (-> obj nodes i radius x) 4096) (/ (-> obj nodes i radius y) 4096) (/ (-> obj nodes i radius z) 4096) (-> obj nodes i radius w) (/ (-> obj nodes i scale-x) 4096)) - (format #t "~T~T:first-tris (new 'static 'array uint8 4 #x~X #x~X #x~X #x~X) :scale-z (meters ~f)~%" - (-> obj nodes i first-tris 0) (-> obj nodes i first-tris 1) (-> obj nodes i first-tris 2) (-> obj nodes i first-tris 3) (/ (-> obj nodes i scale-z) 4096)) - (format #t "~T~T:last-tris (new 'static 'array uint8 4 #x~X #x~X #x~X #x~X)~%" - (-> obj nodes i last-tris 0) (-> obj nodes i last-tris 1) (-> obj nodes i last-tris 2) (-> obj nodes i last-tris 3)) - (format #t "~T~T:scale (new 'static 'vector :x (meters ~f) :y ~f :z (meters ~f) :w ~f))~%" - (/ (-> obj nodes i scale x) 4096) (-> obj nodes i scale y) (/ (-> obj nodes i scale z) 4096) (-> obj nodes i scale w)) - (+! i 1) - ) - ) + (while (< i (-> obj node-count)) + (format #t + "~T~T(new 'static 'nav-node :center-x (meters ~f) :center-y (meters ~f) :center-z (meters ~f) :type ~d :parent-offset ~d~%" + (/ (-> obj nodes i center-x) 4096) + (/ (-> obj nodes i center-y) 4096) + (/ (-> obj nodes i center-z) 4096) + (-> obj nodes i type) + (-> obj nodes i parent-offset)) + (format #t + "~T~T:center (new 'static 'vector :x (meters ~f) :y (meters ~f) :z (meters ~f) :w ~f)~%" + (/ (-> obj nodes i center x) 4096) + (/ (-> obj nodes i center y) 4096) + (/ (-> obj nodes i center z) 4096) + (-> obj nodes i center w)) + (format #t + "~T~T:radius-x (meters ~f) :radius-y (meters ~f) :radius-z (meters ~f)~%" + (/ (-> obj nodes i radius-x) 4096) + (/ (-> obj nodes i radius-y) 4096) + (/ (-> obj nodes i radius-z) 4096)) + (format #t + "~T~T:left-offset ~d :right-offset ~d :num-tris ~d~%" + (-> obj nodes i left-offset) + (-> obj nodes i right-offset) + (-> obj nodes i num-tris)) + (format #t + "~T~T:radius (new 'static 'vector :x (meters ~f) :y (meters ~f) :z (meters ~f) :w ~f) :scale-x (meters ~f)~%" + (/ (-> obj nodes i radius x) 4096) + (/ (-> obj nodes i radius y) 4096) + (/ (-> obj nodes i radius z) 4096) + (-> obj nodes i radius w) + (/ (-> obj nodes i scale-x) 4096)) + (format #t + "~T~T:first-tris (new 'static 'array uint8 4 #x~X #x~X #x~X #x~X) :scale-z (meters ~f)~%" + (-> obj nodes i first-tris 0) + (-> obj nodes i first-tris 1) + (-> obj nodes i first-tris 2) + (-> obj nodes i first-tris 3) + (/ (-> obj nodes i scale-z) 4096)) + (format #t + "~T~T:last-tris (new 'static 'array uint8 4 #x~X #x~X #x~X #x~X)~%" + (-> obj nodes i last-tris 0) + (-> obj nodes i last-tris 1) + (-> obj nodes i last-tris 2) + (-> obj nodes i last-tris 3)) + (format #t + "~T~T:scale (new 'static 'vector :x (meters ~f) :y ~f :z (meters ~f) :w ~f))~%" + (/ (-> obj nodes i scale x) 4096) + (-> obj nodes i scale y) + (/ (-> obj nodes i scale z) 4096) + (-> obj nodes i scale w)) + (+! i 1))) #| (deftype nav-node (structure) ((center-x float :offset-assert 0) @@ -264,19 +316,20 @@ (scale vector :inline :offset 32) ) |# - (format #t "~T)~%") (format #t "~T:route (new 'static 'inline-array vector4ub ~d~%" (* (-> obj poly-count) 2)) (let ((i 0)) (while (< i (* (-> obj poly-count) 2)) - (format #t "~T~T(new 'static 'vector4ub :data (new 'static 'array uint8 4 #x~X #x~X #x~X #x~X))~%" (-> obj route i data 0) (-> obj route i data 1) (-> obj route i data 2) (-> obj route i data 3)) - (+! i 1) - ) - ) + (format #t + "~T~T(new 'static 'vector4ub :data (new 'static 'array uint8 4 #x~X #x~X #x~X #x~X))~%" + (-> obj route i data 0) + (-> obj route i data 1) + (-> obj route i data 2) + (-> obj route i data 3)) + (+! i 1))) (format #t "~T)~%") (format #t ")~%") - obj - ) + obj) (define-extern *default-nav-mesh* nav-mesh) diff --git a/goal_src/jak1/engine/nav/navigate.gc b/goal_src/jak1/engine/nav/navigate.gc index b7dc153b88..ed87c8297d 100644 --- a/goal_src/jak1/engine/nav/navigate.gc +++ b/goal_src/jak1/engine/nav/navigate.gc @@ -372,27 +372,26 @@ (when (point-inside-rect? arg1 arg2 arg3) (cond ((zero? (-> arg1 type)) - (let ((v1-2 (-> arg1 left-offset)) - (s3-0 (-> arg1 right-offset))) - (when (>= v1-2 0) - (let* ((a1-2 (the-as nav-node (&+ (the-as (pointer nav-node) (-> arg0 nodes)) v1-2))) + (let ((v1-2 (-> arg1 left-offset)) + (s3-0 (-> arg1 right-offset))) + (when (>= v1-2 0) + (let* ((a1-2 (the-as nav-node (&+ (the-as (pointer nav-node) (-> arg0 nodes)) v1-2))) (v1-3 (recursive-inside-poly arg0 a1-2 arg2 arg3))) - (if (>= v1-3 0) (return v1-3)))) - (when (>= s3-0 0) - (let* ((a1-3 (&+ (the-as (pointer nav-node) (-> arg0 nodes)) s3-0)) + (if (>= v1-3 0) (return v1-3)))) + (when (>= s3-0 0) + (let* ((a1-3 (&+ (the-as (pointer nav-node) (-> arg0 nodes)) s3-0)) (v1-7 (recursive-inside-poly arg0 (the-as nav-node a1-3) arg2 arg3))) - (if (>= v1-7 0) (return v1-7))))) - (return -1)) + (if (>= v1-7 0) (return v1-7))))) + (return -1)) (else - (let ((s3-1 (-> arg1 num-tris)) - (s2-1 (-> arg1 first-tris))) - (dotimes (s1-0 (the-as int s3-1)) - (let ((s0-0 (-> s2-1 0))) (if (point-inside-poly? arg0 s0-0 arg2 arg3) (return (the-as int s0-0)))) - (set! s2-1 (&-> s2-1 1)) - (if (= s1-0 3) (set! s2-1 (&-> s2-1 4))))) - (return -1))) - (the-as none 0)) - ) + (let ((s3-1 (-> arg1 num-tris)) + (s2-1 (-> arg1 first-tris))) + (dotimes (s1-0 (the-as int s3-1)) + (let ((s0-0 (-> s2-1 0))) (if (point-inside-poly? arg0 s0-0 arg2 arg3) (return (the-as int s0-0)))) + (set! s2-1 (&-> s2-1 1)) + (if (= s1-0 3) (set! s2-1 (&-> s2-1 4))))) + (return -1))) + (the-as none 0))) -1) (defmethod find-poly-fast ((this nav-mesh) (arg0 vector) (arg1 meters)) @@ -1095,13 +1094,14 @@ (dotimes (s3-0 (-> s5-0 vertex-count)) (let ((s3-1 add-debug-text-3d) (s2-1 #t) - (s1-0 68) - ) + (s1-0 68)) (format (clear *temp-string*) "~D" s3-0) - (s3-1 s2-1 (bucket-id debug-no-zbuf) *temp-string* (vector+! s4-0 (the-as vector (-> s5-0 vertex s3-0)) (-> s5-0 origin)) (font-color pink) (the-as vector2h #f)) - ) - ) - ) + (s3-1 s2-1 + (bucket-id debug-no-zbuf) + *temp-string* + (vector+! s4-0 (the-as vector (-> s5-0 vertex s3-0)) (-> s5-0 origin)) + (font-color pink) + (the-as vector2h #f))))) (when #f (dotimes (s3-1 (-> s5-0 node-count)) (let ((a1-4 (-> s5-0 nodes s3-1)) diff --git a/goal_src/jak1/engine/ps2/pad.gc b/goal_src/jak1/engine/ps2/pad.gc index e9a1e01906..37dd0aa947 100644 --- a/goal_src/jak1/engine/ps2/pad.gc +++ b/goal_src/jak1/engine/ps2/pad.gc @@ -45,6 +45,21 @@ (x 14) (square 15)) +(defenum abutton-idx + :type uint8 + (right 0) + (left 1) + (up 2) + (down 3) + (triangle 4) + (circle 5) + (x 6) + (square 7) + (l1 8) + (r1 9) + (l2 10) + (r2 11)) + (defenum pad-type (normal 4) (analog 5) @@ -156,22 +171,19 @@ (set! (-> gp-0 cpads 3) (new 'global 'cpad-info 3)) gp-0)) - ;; Allocates enough input frames to support counting 50ms of time at 300fps. +;; Allocates enough input frames to support counting 50ms of time at 300fps. (deftype cpad-history (basic) ((button0-abs pad-buttons 15) ;; bitmask of buttons, pressed or not, with history (button0-rel pad-buttons 15) ;; bitmask of if button going down. - ) -) + )) ;; List of extended history for controllers at high fps. It always has 4 controllers. (deftype cpad-history-list (basic) - ((num-cpads int32) - (cpads cpad-history 4) ;; modified from 2->4 for PC 4-pad support + ((num-cpads int32) + (cpads cpad-history 4) ;; modified from 2->4 for PC 4-pad support ) (:methods - (new (symbol type) _type_) - ) - ) + (new (symbol type) _type_))) (defmethod new cpad-history-list ((allocation symbol) (type-to-make type)) "Create a cpad-history-list for 4 controllers. It's fine to do this even if controllers @@ -182,9 +194,7 @@ (set! (-> this cpads 1) (new 'global 'cpad-history)) (set! (-> this cpads 2) (new 'global 'cpad-history)) (set! (-> this cpads 3) (new 'global 'cpad-history)) - this - ) - ) + this)) (defun analog-input ((in int) (offset float) (center-val float) (max-val float) (out-range float)) "Convert integer input from pad into a float between -out-range and +out-range. @@ -245,17 +255,14 @@ ;; the four controllers (define *cpad-list* (new 'global 'cpad-list)) + ;; the cpad-history for each controller (define *cpad-history-list* (new 'global 'cpad-history-list)) (desfun generate-frame-checks (pad-idx frames) (if (= frames 0) - 0 - `(logior (-> *cpad-history-list* cpads ,pad-idx button0-rel ,(- frames 1)) - ,(generate-frame-checks pad-idx (- frames 1)) - ) - ) -) + 0 + `(logior (-> *cpad-history-list* cpads ,pad-idx button0-rel ,(- frames 1)) ,(generate-frame-checks pad-idx (- frames 1))))) ;; weird leftover debug thing, enabling overrides the x position of both sticks on all controllers. (define *cpad-debug* #f) @@ -268,7 +275,7 @@ (let ((pad-list *cpad-list*)) (dotimes (pad-idx (-> pad-list num-cpads)) (let ((pad (-> *cpad-list* cpads pad-idx)) - (history (-> *cpad-history-list* cpads pad-idx))) + (history (-> *cpad-history-list* cpads pad-idx))) ;; read from hardware. (cpad-get-data pad) (cond @@ -295,61 +302,49 @@ (set! (-> pad button0-abs 1) (-> pad button0-shadow-abs 0)) (set! (-> pad button0-rel 2) (-> pad button0-rel 1)) (set! (-> pad button0-rel 1) (-> pad button0-rel 0)) - - ;; og:preserve-this high fps fix + ;; og:preserve-this high fps fix (when (>= (-> *pc-settings* target-fps) 300) - (set! (-> history button0-abs 14) (-> history button0-abs 13)) - (set! (-> history button0-abs 13) (-> history button0-abs 12)) - (set! (-> history button0-abs 12) (-> history button0-abs 11)) - - (set! (-> history button0-rel 14) (-> history button0-rel 13)) - (set! (-> history button0-rel 13) (-> history button0-rel 12)) - (set! (-> history button0-rel 12) (-> history button0-rel 11)) - ) + (set! (-> history button0-abs 14) (-> history button0-abs 13)) + (set! (-> history button0-abs 13) (-> history button0-abs 12)) + (set! (-> history button0-abs 12) (-> history button0-abs 11)) + (set! (-> history button0-rel 14) (-> history button0-rel 13)) + (set! (-> history button0-rel 13) (-> history button0-rel 12)) + (set! (-> history button0-rel 12) (-> history button0-rel 11))) (when (>= (-> *pc-settings* target-fps) 240) - (set! (-> history button0-abs 11) (-> history button0-abs 10)) - (set! (-> history button0-abs 10) (-> history button0-abs 9)) - (set! (-> history button0-abs 9) (-> history button0-abs 8)) - (set! (-> history button0-rel 11) (-> history button0-rel 10)) - (set! (-> history button0-rel 10) (-> history button0-rel 9)) - (set! (-> history button0-rel 9) (-> history button0-rel 8)) - ) + (set! (-> history button0-abs 11) (-> history button0-abs 10)) + (set! (-> history button0-abs 10) (-> history button0-abs 9)) + (set! (-> history button0-abs 9) (-> history button0-abs 8)) + (set! (-> history button0-rel 11) (-> history button0-rel 10)) + (set! (-> history button0-rel 10) (-> history button0-rel 9)) + (set! (-> history button0-rel 9) (-> history button0-rel 8))) (when (>= (-> *pc-settings* target-fps) 165) - (set! (-> history button0-abs 8) (-> history button0-abs 7)) - (set! (-> history button0-rel 8) (-> history button0-rel 7)) - ) - (when (>= (-> *pc-settings* target-fps) 150) - (set! (-> history button0-abs 7) (-> history button0-abs 6)) - (set! (-> history button0-abs 6) (-> history button0-abs 5)) - - (set! (-> history button0-rel 7) (-> history button0-rel 6)) - (set! (-> history button0-rel 6) (-> history button0-rel 5)) - ) + (set! (-> history button0-abs 8) (-> history button0-abs 7)) + (set! (-> history button0-rel 8) (-> history button0-rel 7))) + (when (>= (-> *pc-settings* target-fps) 150) + (set! (-> history button0-abs 7) (-> history button0-abs 6)) + (set! (-> history button0-abs 6) (-> history button0-abs 5)) + (set! (-> history button0-rel 7) (-> history button0-rel 6)) + (set! (-> history button0-rel 6) (-> history button0-rel 5))) (when (>= (-> *pc-settings* target-fps) 120) - (set! (-> history button0-abs 5) (-> history button0-abs 4)) - (set! (-> history button0-abs 4) (-> history button0-abs 3)) - (set! (-> history button0-rel 5) (-> history button0-rel 4)) - (set! (-> history button0-rel 4) (-> history button0-rel 3)) - ) + (set! (-> history button0-abs 5) (-> history button0-abs 4)) + (set! (-> history button0-abs 4) (-> history button0-abs 3)) + (set! (-> history button0-rel 5) (-> history button0-rel 4)) + (set! (-> history button0-rel 4) (-> history button0-rel 3))) (when (>= (-> *pc-settings* target-fps) 75) - (set! (-> history button0-abs 3) (-> history button0-abs 2)) - (set! (-> history button0-rel 3) (-> history button0-rel 2)) - ) + (set! (-> history button0-abs 3) (-> history button0-abs 2)) + (set! (-> history button0-rel 3) (-> history button0-rel 2))) (set! (-> history button0-abs 2) (-> history button0-abs 1)) (set! (-> history button0-abs 1) (-> pad button0-shadow-abs 0)) (set! (-> history button0-rel 2) (-> history button0-rel 1)) (set! (-> history button0-rel 1) (-> pad button0-rel 0)) - ;; we might want to clear a button after it is pressed, so we back it up in a "shadow" field (let ((current-button0 (-> pad button0))) (set! (-> pad button0-shadow-abs 0) (the-as pad-buttons current-button0)) (set! (-> pad button0-abs 0) (the-as pad-buttons current-button0)) - (set! (-> history button0-abs 0) (-> pad button0-abs 0)) - ) + (set! (-> history button0-abs 0) (-> pad button0-abs 0))) ;; buttons going down (set! (-> pad button0-rel 0) (logclear (-> pad button0-abs 0) (-> pad button0-abs 1))) - (set! (-> history button0-rel 0) (-> pad button0-rel 0)) - + (set! (-> history button0-rel 0) (-> pad button0-rel 0)) ;; some debugging thing they wrote at some point (when *cpad-debug* (set! (-> pad leftx) (the-as uint 255)) diff --git a/goal_src/jak1/engine/sound/gsound.gc b/goal_src/jak1/engine/sound/gsound.gc index caea67ed8e..a534688b74 100644 --- a/goal_src/jak1/engine/sound/gsound.gc +++ b/goal_src/jak1/engine/sound/gsound.gc @@ -270,14 +270,37 @@ (set! ,sound-trans (the vector #f))))) (sound-trans-convert (-> ,cmd parms trans) ,sound-trans))) -(defmacro sound-play (name &key (id (new-sound-id)) &key (vol 100.0) &key (pitch 0) &key (bend 0) &key (group sfx) &key (position #t)) - `(sound-play-by-name (static-sound-name ,name) - ,id - (the int (* (/ 1024.0 100.0) ,vol)) - (the int (* 1524.0 ,pitch)) - ,bend - (sound-group ,group) - ,position)) +;; og:modbase set to #t to enable sound-replacements. disabled by default to avoid extra PC function calls +;; e.g. replace "money-pickup" with custom_assets/jak1/audio/sound_replacements/money-pickup.mp3 +(define *enable-sound-replacements?* #f) +;; og:modbase temp-string to be used by sound-play replacements only +(define *sound-play-temp-string* (new 'global 'string 2048 (the string #f))) +;; same as string-format but will only use the specified temp-string provided when called +(defmacro temp-string-format (temp-str &rest args) + `(begin + (format (clear ,temp-str) ,@args) + ,temp-str)) + +;; og:modbase try to play replacement sound, nonzero results means it wasnt found, so fall back to playing original sound +;; force-vanilla? flag lets you force vanilla sound for specific caller +(defmacro sound-play (name &key (id (new-sound-id)) &key (vol 100.0) &key (pitch 0) &key (bend 0) &key (group sfx) &key (position #t) &key (force-vanilla? #f)) + `(let ((sound-played? (and *enable-sound-replacements?* (not ,force-vanilla?) + (play-sound-file (temp-string-format *sound-play-temp-string* "sound_replacements/~S.mp3" ,name) 50)))) + ;; the below line would use vanilla volume instead, if you're sure your custom sounds won't be too loud + ;; (the-as sound-id (play-sound-file filepath (the int (* (/ 1024.0 100.0) ,vol)))) + (cond + (sound-played? + ;; Custom sound was found + (the-as sound-id sound-played?)) + (else + ;; Custom sound not found, play the original instead + (sound-play-by-name (static-sound-name ,name) + ,id + (the int (* (/ 1024.0 100.0) ,vol)) + (the int (* 1524.0 ,pitch)) + ,bend + (sound-group ,group) + ,position))))) (defun sound-play-by-name ((name sound-name) (id sound-id) (vol int) (pitch int) (bend int) (group sound-group) (trans symbol)) "Play a sound called name with the specified params" diff --git a/goal_src/jak1/engine/target/target-death.gc b/goal_src/jak1/engine/target/target-death.gc index bae0b23235..38ae2b05e3 100644 --- a/goal_src/jak1/engine/target/target-death.gc +++ b/goal_src/jak1/engine/target/target-death.gc @@ -181,7 +181,7 @@ (suspend) (suspend) (send-event (if gp-0 (-> gp-0 extra process)) 'play-anim))) - (let ((gp-1 (current-time))) (until (time-elapsed? gp-1 (seconds 2)) (suspend))) + (suspend-for (seconds 2)) (until (not v1-10) (suspend) (set! v1-10 (and *target* (logtest? (-> *target* state-flags) (state-flags grabbed))))) @@ -272,7 +272,7 @@ (s3-7 (if v1-235 (-> v1-235 extra process)) s4-13)))) (set-continue! *game-info* "lavatube-end"))) (go target-warp-in s5-6 (-> arg0 trans)))) - (else (let ((s5-7 (current-time))) (until (time-elapsed? s5-7 (seconds 0.05)) (suspend))))) + (else (suspend-for (seconds 0.05)))) (set-continue! *game-info* arg0) (when *auto-continue* (let ((s5-8 (next-level (-> arg0 level)))) @@ -715,7 +715,7 @@ (-> self attack-info attacker) (ja-channel-set! 0) (ja-post) - (let ((gp-1 (current-time))) (until (time-elapsed? gp-1 (seconds 1)) (suspend)))) + (suspend-for (seconds 1))) (('drown 'drown-death) (sound-play "death-drown") (logclear! (-> self water flags) (water-flags wt04)) @@ -775,7 +775,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((gp-9 (current-time))) (until (time-elapsed? gp-9 (seconds 2)) (suspend)))) + (suspend-for (seconds 2))) (('endlessfall) (sound-play "death-fall") (camera-change-to (the-as string cam-endlessfall) 30 #f) @@ -812,10 +812,7 @@ (target-falling-anim (seconds 0.1) (seconds 0.33)) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! eichar-launch-jump-loop-ja :num! (loop! 0.5) :frame-num 0.0) - (let ((gp-12 (current-time))) - (until (time-elapsed? gp-12 (seconds 0.8)) - (ja :group! eichar-launch-jump-loop-ja :num! (loop! 0.5)) - (suspend))) + (suspend-for (seconds 0.8) (ja :group! eichar-launch-jump-loop-ja :num! (loop! 0.5))) (camera-change-to (the-as string 'base) 0 #f)) (('target-hit-ground-hard) (set! (-> self control unknown-surface00) *neutral-mods*) diff --git a/goal_src/jak1/engine/target/target.gc b/goal_src/jak1/engine/target/target.gc index 8cf8249fac..50329802cc 100644 --- a/goal_src/jak1/engine/target/target.gc +++ b/goal_src/jak1/engine/target/target.gc @@ -245,13 +245,10 @@ (remove-exit) (go target-duck-stance)) ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + (if (and (recently-pressed? x) (can-jump? #f)) (go target-jump (-> *TARGET-bank* jump-height-min) (-> *TARGET-bank* jump-height-max) (the-as surface #f))) ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? circle) - (can-feet?)) - (go target-attack)) + (if (and (recently-pressed? circle) (can-feet?)) (go target-attack)) (if (can-hands? #t) (go target-running-attack)) (slide-down-test) (fall-test)) @@ -405,13 +402,10 @@ (remove-exit) (go target-stance)) ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + (if (and (recently-pressed? x) (can-jump? #f)) (go target-jump (-> *TARGET-bank* jump-height-min) (-> *TARGET-bank* jump-height-max) (the-as surface #f))) ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? circle) - (can-feet?)) - (go target-attack)) + (if (and (recently-pressed? circle) (can-feet?)) (go target-attack)) (if (can-hands? #t) (go target-running-attack)) (when (and (turn-around?) (time-elapsed? (-> self state-time) (seconds 0.3))) (set! (-> self control transv quad) (-> self control unknown-vector-array10 (-> self control unknown-int10) quad)) @@ -612,8 +606,7 @@ (behavior () ((-> self state-hook)) ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + (if (and (recently-pressed? x) (can-jump? #f)) (go target-jump (-> *TARGET-bank* jump-height-min) (-> *TARGET-bank* jump-height-max) (the-as surface #f))) (if (and (cpad-pressed? (-> self control unknown-cpad-info00 number) circle) (can-feet?)) (go target-attack)) (if (can-hands? #t) (go target-running-attack)) @@ -762,8 +755,7 @@ (go target-stance)) (if (move-legs?) (go target-duck-walk)) ;; og:preserve-this - High FPS Fix - (when (and (recently-pressed? x) - (can-jump? #f)) + (when (and (recently-pressed? x) (can-jump? #f)) (if (= (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) stick0-speed) 0.0) (go target-high-jump (-> *TARGET-bank* duck-jump-height-min) (-> *TARGET-bank* duck-jump-height-max) 'duck) (go target-jump (-> *TARGET-bank* jump-height-min) (-> *TARGET-bank* jump-height-max) (the-as surface #f)))) @@ -815,8 +807,7 @@ (go target-walk)) (if (not (move-legs?)) (go target-duck-stance)) ;; og:preserve-this - High FPS Fix - (when (and (recently-pressed? x) - (can-jump? #f)) + (when (and (recently-pressed? x) (can-jump? #f)) (if (= (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) stick0-speed) 0.0) (go target-high-jump (-> *TARGET-bank* duck-jump-height-min) (-> *TARGET-bank* duck-jump-height-max) 'duck) (go target-jump (-> *TARGET-bank* jump-height-min) (-> *TARGET-bank* jump-height-max) (the-as surface #f)))) @@ -874,7 +865,7 @@ (behavior () (set! (-> self control unknown-float123) (fmax (-> self control unknown-float123) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton 6))))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton (abutton-idx x)))))) ;; og:preserve-this abutton indexing (target-falling-trans #f (the-as time-frame (if (ja-group? eichar-jump-loop-ja) 15 -1))) (if (and (cpad-pressed? (-> self control unknown-cpad-info00 number) x) (< (vector-dot (-> self control dynam gravity-normal) (-> self control transv)) 12288.0) @@ -1189,10 +1180,9 @@ 600 1500)) :trans - (behavior () - ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + (behavior () + ;; og:preserve-this - High FPS Fix + (if (and (recently-pressed? x) (can-jump? #f)) (go target-jump (-> *TARGET-bank* jump-height-min) (-> *TARGET-bank* jump-height-max) (the-as surface #f))) (if (and (not (can-exit-duck?)) (can-duck?)) (go target-duck-stance)) (when (!= (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) stick0-speed) 0.0) @@ -1236,9 +1226,8 @@ (effect-control-method-10 (-> self skel effect) 'group-red-eco-spinkick (ja-frame-num 0) 74) (cpad-set-buzz! (-> *cpad-list* cpads 0) 1 153 (seconds 0.1)) (level-hint-spawn (text-id misty-eco-red-first-use) "sksp0072" (the-as entity #f) *entity-pool* (game-task none))) - ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + ;; og:preserve-this - High FPS Fix + (if (and (recently-pressed? x) (can-jump? #f)) (go target-jump (-> *TARGET-bank* jump-height-min) (-> *TARGET-bank* jump-height-max) (the-as surface #f))) (suspend) (ja :num! (seek! max (-> self control unknown-surface01 align-speed)))) @@ -1852,9 +1841,8 @@ ((time-elapsed? (-> self state-hook-time) (-> *TARGET-bank* wheel-jump-post-window)) (set! (-> self state-hook) (the-as (function none :behavior target) nothing))) (else - ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? 'target-wheel-flip)) + ;; og:preserve-this - High FPS Fix + (if (and (recently-pressed? x) (can-jump? 'target-wheel-flip)) (go target-wheel-flip (-> *TARGET-bank* wheel-flip-height) (-> *TARGET-bank* wheel-flip-dist))))) (none))) (go target-duck-stance)) @@ -1933,9 +1921,8 @@ ((time-elapsed? (-> self state-hook-time) (seconds 0.1)) (set! (-> self state-hook) (the-as (function none :behavior target) nothing))) (else - ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + ;; og:preserve-this - High FPS Fix + (if (and (recently-pressed? x) (can-jump? #f)) (go target-high-jump (-> *TARGET-bank* flip-jump-height-min) (-> *TARGET-bank* flip-jump-height-max) 'flip)))) (none))) (if (ja-group? eichar-jump-loop-ja) (go target-hit-ground #f) (go target-stance))) diff --git a/goal_src/jak1/engine/target/target2.gc b/goal_src/jak1/engine/target/target2.gc index 1f3cedc7aa..c4e0c2b42d 100644 --- a/goal_src/jak1/engine/target/target2.gc +++ b/goal_src/jak1/engine/target/target2.gc @@ -28,11 +28,7 @@ (send-event *camera* 'joystick 0.0 0.0) (suspend) (ja :num! (seek!))) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.3)) - (suspend) - (ja :num! (seek! (ja-aframe (the-as float 19.0) 0) 0.05)) - (suspend))) + (suspend-for (seconds 0.3) (suspend) (ja :num! (seek! (ja-aframe (the-as float 19.0) 0) 0.05))) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! eichar-painful-land-ja :num! (seek!) :frame-num (ja-aframe (the-as float 40.0) 0)) (until (ja-done? 0) @@ -166,11 +162,11 @@ (go hud-waiting) (none)) -(defmethod relocate ((this first-person-hud) (arg0 int)) +(defmethod relocate ((this first-person-hud) (offset int)) (dotimes (v1-0 (-> this nb-of-particles)) (when (-> this particles v1-0 part) - (if (nonzero? (-> this particles v1-0 part)) (&+! (-> this particles v1-0 part) arg0)))) - (the-as first-person-hud ((method-of-type process relocate) this arg0))) + (if (nonzero? (-> this particles v1-0 part)) (&+! (-> this particles v1-0 part) offset)))) + (the-as first-person-hud ((method-of-type process relocate) this offset))) (defmethod spawn-particles! ((this first-person-hud)) (dotimes (s5-0 (-> this nb-of-particles)) @@ -347,8 +343,8 @@ (vf4 :class vf) (vf5 :class vf) (vf6 :class vf)) - (init-vf0-vector) - ;; og:preserve-this - High FPS Fix + (init-vf0-vector) + ;; og:preserve-this - High FPS Fix (when (and (recently-pressed? r2 circle square) (and (= (-> self fact eco-type) (pickup-type eco-yellow)) (>= (-> self fact eco-level) 1.0)) (time-elapsed? (-> self control unknown-dword82) (seconds 0.5)) @@ -427,7 +423,7 @@ (vf5 :class vf) (vf6 :class vf)) (init-vf0-vector) - ;; og:preserve-this - High FPS Fix + ;; og:preserve-this - High FPS Fix (when (and (recently-pressed? r2 circle square) (time-elapsed? (-> self control unknown-dword82) (seconds 0.45)) (and (= (-> self fact eco-type) (pickup-type eco-yellow)) (>= (-> self fact eco-level) 1.0)) @@ -590,7 +586,7 @@ (logclear! (-> self control root-prim prim-core action) (collide-action swingpole-active)) (set! (-> self control unknown-handle10) (the-as handle #f))) :trans - (behavior () + (behavior () ;; og:preserve-this - High FPS Fix (when (and (recently-pressed? x) (not (logtest? (-> self state-flags) (state-flags prevent-jump))) @@ -748,7 +744,7 @@ :trans (behavior () (when (and (time-elapsed? (-> self state-time) (seconds 0.2)) - ;; og:preserve-this - High FPS Fix + ;; og:preserve-this - High FPS Fix (recently-pressed? x) (not (logtest? (-> self state-flags) (state-flags prevent-jump)))) (cond @@ -1007,7 +1003,7 @@ :to self) (set-time! (-> self control unknown-dword82)) - (let ((gp-4 (current-time))) (until (time-elapsed? gp-4 (seconds 0.1)) (suspend))) + (suspend-for (seconds 0.1)) (ja-no-eval :group! eichar-yellow-jumping-blast-ja :num! (seek!) :frame-num (ja-frame-num 0)) (until (ja-done? 0) (suspend) @@ -1036,7 +1032,7 @@ :frame-num (ja-aframe (the-as float (if (= arg1 (-> *FACT-bank* eco-full-inc)) 0.0 6.0)) 0)) (until (ja-done? 0) - ;; og:preserve-this - High FPS Fix + ;; og:preserve-this - High FPS Fix (if (and (recently-pressed? x) (not (logtest? (-> self water flags) (water-flags wt09))) (not (logtest? (-> self state-flags) (state-flags prevent-jump)))) @@ -1078,8 +1074,7 @@ (if (and (cpad-hold? (-> self control unknown-cpad-info00 number) l1 r1) (can-duck?)) (go target-duck-stance)) (if (!= (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) stick0-speed) 0.0) (go target-wade-walk)) ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + (if (and (recently-pressed? x) (can-jump? #f)) (go target-jump (-> *TARGET-bank* jump-height-min) (-> *TARGET-bank* jump-height-max) (the-as surface #f))) (when (and (cpad-pressed? (-> self control unknown-cpad-info00 number) circle) (can-feet?)) (sound-play "swim-stroke") @@ -1107,8 +1102,7 @@ (if (= (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) stick0-speed) 0.0) (go target-wade-stance)) (if (and (cpad-hold? (-> self control unknown-cpad-info00 number) l1 r1) (can-duck?)) (go target-duck-walk)) ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + (if (and (recently-pressed? x) (can-jump? #f)) (go target-jump (-> *TARGET-bank* jump-height-min) (-> *TARGET-bank* jump-height-max) (the-as surface #f))) (when (and (cpad-pressed? (-> self control unknown-cpad-info00 number) circle) (can-feet?)) (sound-play "swim-stroke") @@ -1254,14 +1248,11 @@ (set-zero! (-> self water bob))) (when (and (not (logtest? (-> self water flags) (water-flags wt11))) (time-elapsed? (-> self state-time) (seconds 0.1))) (if (logtest? (-> self water flags) (water-flags wt10)) (go target-wade-stance) (go target-stance))) - ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f) - (time-elapsed? (-> self water enter-swim-time) (seconds 0.1))) + ;; og:preserve-this - High FPS Fix + (if (and (recently-pressed? x) (can-jump? #f) (time-elapsed? (-> self water enter-swim-time) (seconds 0.1))) (go target-swim-jump (-> *TARGET-bank* swim-jump-height-min) (-> *TARGET-bank* swim-jump-height-max))) - ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? square) - (< (-> *TARGET-bank* min-dive-depth) (target-height-above-ground))) + ;; og:preserve-this - High FPS Fix + (if (and (recently-pressed? square) (< (-> *TARGET-bank* min-dive-depth) (target-height-above-ground))) (go target-swim-down)) (if (and (!= (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) stick0-speed) 0.0) (let ((gp-0 (ja-group))) @@ -1315,14 +1306,11 @@ (set-zero! (-> self water bob))) (when (and (not (logtest? (-> self water flags) (water-flags wt11))) (time-elapsed? (-> self water swim-time) (seconds 0.1))) (if (logtest? (-> self water flags) (water-flags wt10)) (go target-wade-stance) (go target-stance))) - ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f) - (time-elapsed? (-> self water enter-swim-time) (seconds 0.1))) + ;; og:preserve-this - High FPS Fix + (if (and (recently-pressed? x) (can-jump? #f) (time-elapsed? (-> self water enter-swim-time) (seconds 0.1))) (go target-swim-jump (-> *TARGET-bank* swim-jump-height-min) (-> *TARGET-bank* swim-jump-height-max))) - ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? square) - (< (-> *TARGET-bank* min-dive-depth) (target-height-above-ground))) + ;; og:preserve-this - High FPS Fix + (if (and (recently-pressed? square) (< (-> *TARGET-bank* min-dive-depth) (target-height-above-ground))) (go target-swim-down)) (cond ((= (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) stick0-speed) 0.0) @@ -1684,7 +1672,7 @@ 143360.0 :to self)) - ;; PAL patch (sound plays elsewhere) + ;; og:preserve-this PAL patch (sound plays elsewhere) ;(sound-play "launch-fire") (go target-high-jump arg0 arg0 'launch)) :post target-no-stick-post) diff --git a/goal_src/jak1/engine/ui/text-h.gc b/goal_src/jak1/engine/ui/text-h.gc index 3da28f4380..681a61d585 100644 --- a/goal_src/jak1/engine/ui/text-h.gc +++ b/goal_src/jak1/engine/ui/text-h.gc @@ -790,13 +790,12 @@ (input-opts-binds-unknown #x1615) (progress-no-other-resolution-options #x1616) (input-opts-controller-led-reflect-heat #x1617) - ;; mod text mod-base-change (pad-triangle #x2000) (pad-circle #x2001) (pad-x #x2002) (pad-square #x2003) -;; GAME-TEXT-ID ENUM ENDS + ;; GAME-TEXT-ID ENUM ENDS ) ;; DECOMP BEGINS diff --git a/goal_src/jak1/game.gp b/goal_src/jak1/game.gp index 78df45923a..3fc6b1f3db 100644 --- a/goal_src/jak1/game.gp +++ b/goal_src/jak1/game.gp @@ -2047,6 +2047,7 @@ "common-obs/plat.gc" "common-obs/plat-button.gc" "common-obs/plat-eco.gc" + "common-obs/linear-plat.gc" "common-obs/ropebridge.gc" "common-obs/ticky.gc" ) diff --git a/goal_src/jak1/kernel-defs.gc b/goal_src/jak1/kernel-defs.gc index ff29c2b0bd..502c8d0cef 100644 --- a/goal_src/jak1/kernel-defs.gc +++ b/goal_src/jak1/kernel-defs.gc @@ -500,13 +500,17 @@ (define-extern pc-get-window-scale (function (pointer float) (pointer float) none)) (define-extern pc-set-window-size! (function int int none)) + (define-extern pc-get-display-id (function int)) + (define-extern pc-set-display-id! (function int none)) + (define-extern pc-set-display-mode! (function symbol none)) -(define-extern pc-get-num-resolutions (function int)) +(define-extern pc-get-num-resolutions (function symbol int)) + +(define-extern pc-get-resolution (function int symbol (pointer int64) (pointer int64) none)) -(define-extern pc-get-resolution (function int (pointer int64) (pointer int64) none)) (define-extern pc-is-supported-resolution? (function int int symbol)) (define-extern pc-set-frame-rate (function int none)) @@ -531,17 +535,24 @@ (define-extern pc-discord-rpc-set (function int none)) - ;;main music start (define-extern play-main-music (function string int none)) + (define-extern pause-main-music (function none)) + (define-extern stop-main-music (function none)) + (define-extern resume-main-music (function none)) + (define-extern main-music-volume (function int none)) + ;;main music end -(define-extern play-sound-file (function string int none)) -(define-extern stop-sound-file (function none)) +(define-extern play-sound-file (function string int symbol)) + +(define-extern stop-sound-file (function string none)) + +(define-extern stop-all-sounds (function none)) (define-extern pc-filepath-exists? (function string symbol)) @@ -583,6 +594,8 @@ (define-extern pc-rand (function int)) +(define-extern pc-encode-utf8-string (function string string none)) + ;; Constants generated within the C++ runtime (define-extern *pc-user-dir-base-path* string) diff --git a/goal_src/jak1/kernel/gkernel.gc b/goal_src/jak1/kernel/gkernel.gc index e19f3ec745..73a056e45a 100644 --- a/goal_src/jak1/kernel/gkernel.gc +++ b/goal_src/jak1/kernel/gkernel.gc @@ -271,6 +271,11 @@ (define *pause-lock* #f) ;; set to #t when paused and doing a single frame advance with R2. +;; og:preserve-this added +(defmethod print ((this process-tree)) + (format #t "#<~A ~S @ #x~X>" (-> this type) (-> this name) this) + this) + (defmethod new process-tree ((allocation symbol) (type-to-make type) (name basic)) "Create a process-tree node" ;; allocate diff --git a/goal_src/jak1/kernel/gstate.gc b/goal_src/jak1/kernel/gstate.gc index 2152bdbe0e..1fc3e7cf53 100644 --- a/goal_src/jak1/kernel/gstate.gc +++ b/goal_src/jak1/kernel/gstate.gc @@ -209,6 +209,10 @@ It type checks the arguments for the entry function. ,*defstate-current-state-name* (find-parent-method ,*defstate-current-type* (method-id-of-type ,*defstate-current-type* ,*defstate-current-state-name*)))) +(defmacro call-parent-state-handler (handler &key (type (function none)) &rest args) + "Call the parent handler for this state." + `(let ((handler (-> (find-parent-state) ,handler))) (if handler ((the ,type handler) ,@args)))) + (defmacro behavior (bindings &rest body) "Define an anonymous behavior for a process state. This may only be used inside a defstate!" (let ((behavior-type (first *defstate-type-stack*))) @@ -428,3 +432,6 @@ It type checks the arguments for the entry function. (defmacro time-passed? (time) "has it been 'time' since set-state-time?" `(>= (time-passed) ,time)) + +(defmacro suspend-for (time &rest body) + `(let ((time (current-time))) (until (time-elapsed? time ,time) ,@body (suspend)))) diff --git a/goal_src/jak1/levels/beach/beach-obs.gc b/goal_src/jak1/levels/beach/beach-obs.gc index 52a6d7b04c..931248f431 100644 --- a/goal_src/jak1/levels/beach/beach-obs.gc +++ b/goal_src/jak1/levels/beach/beach-obs.gc @@ -21,6 +21,7 @@ (:states windmill-one-idle)) + (defskelgroup *windmill-one-sg* windmill-one windmill-one-lod0-jg @@ -167,6 +168,7 @@ grottopole-moving-down grottopole-moving-up)) + (defskelgroup *grottopole-sg* grottopole grottopole-lod0-jg @@ -319,6 +321,7 @@ (:states (ecoventrock-break symbol) ecoventrock-idle)) + (defskelgroup *ecoventrock-sg* ecoventrock ecoventrock-lod0-jg @@ -525,7 +528,7 @@ (set! sv-128 (the-as symbol #f)) (apply-all (-> self link) actor-link-subtask-complete-hook (& sv-128)) (when sv-128 - (let ((s5-2 (current-time))) (until (time-elapsed? s5-2 (seconds 0.5)) (suspend))) + (suspend-for (seconds 0.5)) (let ((gp-1 (cond (arg0 (the-as int #f)) (else @@ -570,6 +573,7 @@ flying-rock-idle flying-rock-rolling)) + (defskelgroup *kickrock-sg* kickrock kickrock-lod0-jg @@ -675,6 +679,7 @@ (:states bladeassm-idle)) + (defskelgroup *bladeassm-sg* bladeassm bladeassm-lod0-jg @@ -739,6 +744,7 @@ flutflutegg-physics flutflutegg-physics-fall)) + (defskelgroup *flutflutegg-sg* flutflutegg flutflutegg-lod0-jg @@ -753,9 +759,9 @@ ((flutflut-lod0-mg (meters 999999))) :bounds (static-spherem 0 0 0 8)) -(defmethod relocate ((this flutflutegg) (arg0 int)) - (if (nonzero? (-> this wobbler)) (&+! (-> this wobbler) arg0)) - (call-parent-method this arg0)) +(defmethod relocate ((this flutflutegg) (offset int)) + (if (nonzero? (-> this wobbler)) (&+! (-> this wobbler) offset)) + (call-parent-method this offset)) ;; WARN: Function (method 20 flutflutegg) has a return type of none, but the expression builder found a return statement. (defmethod flutflutegg-method-20 ((this flutflutegg) (arg0 float) (arg1 float) (arg2 float)) @@ -875,7 +881,7 @@ (suspend)) (camera-change-to "camera-135" 0 #f) (camera-look-at (the-as pair (ppointer->process (-> self parent))) (the-as uint 9)) - (let ((gp-0 (current-time))) (until (time-elapsed? gp-0 (seconds 4)) (suspend))) + (suspend-for (seconds 4)) (while (not (process-release? (handle->process (-> self grab-target)))) (suspend)) (camera-look-at (the-as pair *target*) (the-as uint 0)) @@ -994,6 +1000,7 @@ harvester-idle (harvester-inflate symbol))) + (defskelgroup *harvester-sg* harvester harvester-lod0-jg @@ -1094,6 +1101,7 @@ (deftype beachcam (process-hidden) ()) + (defun beachcam-spawn () (with-pp (let ((gp-0 (entity-actor-lookup (-> pp entity) 'alt-actor 0))) diff --git a/goal_src/jak1/levels/beach/lurkercrab.gc b/goal_src/jak1/levels/beach/lurkercrab.gc index 565df30fb0..1139fb8083 100644 --- a/goal_src/jak1/levels/beach/lurkercrab.gc +++ b/goal_src/jak1/levels/beach/lurkercrab.gc @@ -56,6 +56,7 @@ (:states lurkercrab-pushed)) + (defskelgroup *lurkercrab-sg* lurkercrab lurkercrab-lod0-jg @@ -146,13 +147,13 @@ nav-enemy-default-event-handler (ja-channel-push! 1 (seconds 0.075)) (loop (ja :group! lurkercrab-idle-ja :num! (identity (ja-aframe 1.0 0))) - (let ((gp-1 (current-time))) (until (time-elapsed? gp-1 (seconds 3)) (suspend))) + (suspend-for (seconds 3)) (ja-no-eval :group! lurkercrab-idle-ja :num! (seek! (ja-aframe 19.0 0)) :frame-num (ja-aframe 1.0 0)) (until (ja-done? 0) (suspend) (ja :num! (seek! (ja-aframe 19.0 0)))) (ja :num-func num-func-identity :frame-num (ja-aframe 19.0 0)) - (let ((gp-5 (current-time))) (until (time-elapsed? gp-5 (seconds 1)) (suspend))) + (suspend-for (seconds 1)) (ja-no-eval :group! lurkercrab-idle-ja :num! (seek! (ja-aframe 1.0 0)) :frame-num (ja-aframe 19.0 0)) (until (ja-done? 0) (suspend) @@ -199,7 +200,7 @@ nav-enemy-default-event-handler (nav-enemy-rnd-int-range 2 6) (until (not (nav-enemy-rnd-go-idle? 0.2)) (ja :group! lurkercrab-idle-ja :num! (identity (ja-aframe 1.0 0))) - (let ((gp-2 (current-time))) (until (time-elapsed? gp-2 (seconds 2)) (suspend)))) + (suspend-for (seconds 2))) (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (ja-no-eval :group! lurkercrab-idle-to-walk-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) @@ -326,8 +327,8 @@ nav-enemy-default-event-handler (until (ja-done? 0) (suspend) (ja :num! (seek! (ja-aframe 18.0 0) 0.75))) - (let ((gp-2 (current-time))) (until (time-elapsed? gp-2 (seconds 0.25)) (suspend))) - (let ((gp-3 (current-time))) (until (time-elapsed? gp-3 (seconds 0.1)) (suspend))) + (suspend-for (seconds 0.25)) + (suspend-for (seconds 0.1)) (go-virtual nav-enemy-chase)) :post (behavior () diff --git a/goal_src/jak1/levels/beach/lurkerpuppy.gc b/goal_src/jak1/levels/beach/lurkerpuppy.gc index 334f1e44c9..8d46e0568c 100644 --- a/goal_src/jak1/levels/beach/lurkerpuppy.gc +++ b/goal_src/jak1/levels/beach/lurkerpuppy.gc @@ -7,6 +7,7 @@ (deftype lurkerpuppy (nav-enemy) ()) + (defskelgroup *lurkerpuppy-sg* lurkerpuppy lurkerpuppy-lod0-jg @@ -77,12 +78,7 @@ nav-enemy-default-event-handler (ja-channel-push! 1 (seconds 0.1)) (ja :group! lurkerpuppy-idle-ja) (ja :num-func num-func-identity :frame-num 0.0) - (let ((gp-2 (rand-vu-int-range 750 900)) - (s5-0 (current-time))) - (until (time-elapsed? s5-0 gp-2) - (ja :num! (loop!)) - (ja-blend-eval) - (suspend))))))) + (let ((gp-2 (rand-vu-int-range 750 900))) (suspend-for gp-2 (ja :num! (loop!)) (ja-blend-eval))))))) (defstate nav-enemy-give-up (lurkerpuppy) :virtual #t diff --git a/goal_src/jak1/levels/citadel/citadel-obs.gc b/goal_src/jak1/levels/citadel/citadel-obs.gc index 5666d4f860..901527dd06 100644 --- a/goal_src/jak1/levels/citadel/citadel-obs.gc +++ b/goal_src/jak1/levels/citadel/citadel-obs.gc @@ -20,6 +20,7 @@ (setup-new-process! (_type_) none) (idle () _type_ :state))) + (defskelgroup *citb-arm-a-sg* citb-arm citb-arm-a-lod0-jg @@ -121,6 +122,7 @@ (deftype citb-arm (citb-arm-section) ((root collide-shape-moving :override))) + (defstate idle (citb-arm) :virtual #t :trans rider-trans @@ -161,6 +163,7 @@ (deftype citb-arm-shoulder (citb-arm-section) ()) + (defmethod setup-new-process! ((this citb-arm-shoulder)) (call-parent-method this) (set! (-> this draw origin-joint-index) (the-as uint 4)) @@ -171,16 +174,22 @@ (deftype citb-arm-a (citb-arm) ()) + (deftype citb-arm-b (citb-arm) ()) + (deftype citb-arm-c (citb-arm) ()) + (deftype citb-arm-d (citb-arm) ()) + (deftype citb-arm-shoulder-a (citb-arm-shoulder) ()) + (deftype citb-arm-shoulder-b (citb-arm-shoulder) ()) + (defmethod setup-new-process! ((this citb-arm-a)) (initialize-skeleton this *citb-arm-a-sg* '()) (call-parent-method this) @@ -263,6 +272,7 @@ (:states citb-disc-idle)) + (defstate citb-disc-idle (citb-disc) :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block)) @@ -323,12 +333,16 @@ (deftype citb-disc-a (citb-disc) ()) + (deftype citb-disc-b (citb-disc) ()) + (deftype citb-disc-c (citb-disc) ()) + (deftype citb-disc-d (citb-disc) ()) + (defmethod citb-disc-method-21 ((this citb-disc-a)) (initialize-skeleton this *citb-disc-a-sg* '()) 0 @@ -351,6 +365,7 @@ (deftype citb-iris-door (eco-door) ()) + (defskelgroup *citb-iris-door-sg* citb-iris-door citb-iris-door-lod0-jg @@ -393,6 +408,7 @@ (deftype citb-button (basebutton) ()) + (defmethod basebutton-method-27 ((this citb-button)) (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum hit-by-player)))) (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process)) @@ -433,6 +449,7 @@ (deftype citb-launcher (plat) ((launcher (pointer launcher)))) + (defstate plat-path-active (citb-launcher) :virtual #t :post @@ -538,6 +555,7 @@ citb-robotboss-die citb-robotboss-idle)) + (defstate citb-robotboss-idle (citb-robotboss) :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block)) @@ -650,9 +668,10 @@ citb-coil-broken citb-coil-idle)) -(defmethod relocate ((this citb-coil) (arg0 int)) - (if (nonzero? (-> this part-off)) (&+! (-> this part-off) arg0)) - (the-as citb-coil ((method-of-type process-drawable relocate) this arg0))) + +(defmethod relocate ((this citb-coil) (offset int)) + (if (nonzero? (-> this part-off)) (&+! (-> this part-off) offset)) + (the-as citb-coil ((method-of-type process-drawable relocate) this offset))) (defmethod deactivate ((this citb-coil)) (if (nonzero? (-> this part-off)) (kill-and-free-particles (-> this part-off))) @@ -724,6 +743,7 @@ citb-hose-idle citb-hose-spawn)) + (defbehavior citb-hose-event-handler citb-hose ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) (case arg2 (('spawn) (go citb-hose-spawn)) @@ -776,6 +796,7 @@ (deftype citb-chains (process-hidden) ()) + (defskelgroup *citb-generator-sg* citb-generator citb-generator-lod0-jg @@ -808,10 +829,11 @@ citb-generator-broken citb-generator-idle)) -(defmethod relocate ((this citb-generator) (arg0 int)) - (if (nonzero? (-> this part-broken)) (&+! (-> this part-broken) arg0)) - (if (nonzero? (-> this part-mushroom)) (&+! (-> this part-mushroom) arg0)) - (the-as citb-generator ((method-of-type process-drawable relocate) this arg0))) + +(defmethod relocate ((this citb-generator) (offset int)) + (if (nonzero? (-> this part-broken)) (&+! (-> this part-broken) offset)) + (if (nonzero? (-> this part-mushroom)) (&+! (-> this part-mushroom) offset)) + (the-as citb-generator ((method-of-type process-drawable relocate) this offset))) (defmethod deactivate ((this citb-generator)) (if (nonzero? (-> this part-broken)) (kill-and-free-particles (-> this part-broken))) @@ -998,6 +1020,7 @@ citadelcam-idle citadelcam-stair-plats)) + (defstate citadelcam-idle (citadelcam) :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block)) @@ -1044,6 +1067,7 @@ (deftype citb-battlecontroller (battlecontroller) ()) + (defstate battlecontroller-play-intro-camera (citb-battlecontroller) :virtual #t :code @@ -1070,7 +1094,7 @@ :code (behavior () (process-entity-status! self (entity-perm-status complete) #t) - (let ((t9-2 (-> (find-parent-state) code))) (if t9-2 ((the-as (function none :behavior battlecontroller) t9-2)))))) + (call-parent-state-handler code))) (defmethod battlecontroller-method-27 ((this citb-battlecontroller)) (call-parent-method this) diff --git a/goal_src/jak1/levels/citadel/citb-drop-plat.gc b/goal_src/jak1/levels/citadel/citb-drop-plat.gc index 6df877e8f6..3f8b131de8 100644 --- a/goal_src/jak1/levels/citadel/citb-drop-plat.gc +++ b/goal_src/jak1/levels/citadel/citb-drop-plat.gc @@ -59,6 +59,7 @@ (drop-plat-rise draw-control) drop-plat-spawn)) + (defstate drop-plat-idle (drop-plat) :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block)) @@ -231,6 +232,7 @@ (deftype handle-inline-array (inline-array-class) ((data handle :dynamic))) + (set! (-> handle-inline-array heap-base) (the-as uint 8)) (deftype citb-drop-plat (process-drawable) @@ -251,9 +253,10 @@ citb-drop-plat-active citb-drop-plat-idle)) -(defmethod relocate ((this citb-drop-plat) (arg0 int)) - (if (nonzero? (-> this child-array)) (&+! (-> this child-array) arg0)) - (the-as citb-drop-plat ((method-of-type process-drawable relocate) this arg0))) + +(defmethod relocate ((this citb-drop-plat) (offset int)) + (if (nonzero? (-> this child-array)) (&+! (-> this child-array) offset)) + (the-as citb-drop-plat ((method-of-type process-drawable relocate) this offset))) (defbehavior citb-drop-plat-spawn-children citb-drop-plat () (local-vars (s0-0 int) (sv-48 process) (sv-64 int)) @@ -286,7 +289,7 @@ (t0-0 (-> self duration))) ((the-as (function process function vector int int int none) t9-7) a0-8 a1-5 a2-4 sv-64 (the-as int t0-0) s0-0)) (-> sv-48 ppointer))))))) - (let ((s2-1 (current-time))) (until (time-elapsed? s2-1 (seconds 0.12)) (suspend))) + (suspend-for (seconds 0.12)) (+! s5-0 s4-0)))) (set-time! (-> self drop-time)) 0 diff --git a/goal_src/jak1/levels/common/battlecontroller.gc b/goal_src/jak1/levels/common/battlecontroller.gc index 07fe5f52c3..a15f5103fd 100644 --- a/goal_src/jak1/levels/common/battlecontroller.gc +++ b/goal_src/jak1/levels/common/battlecontroller.gc @@ -13,6 +13,7 @@ (state int8) (enabled symbol))) + (deftype battlecontroller-creature-type (structure) ((type2 type) (percent float) @@ -22,6 +23,7 @@ (pickup-count int8)) :allow-misaligned) + (deftype battlecontroller (process-drawable) ((final-pickup-spawn-point vector :inline) (activate-distance float) @@ -54,6 +56,7 @@ (battlecontroller-method-27 (_type_) none) (cleanup-if-finished! (_type_) none))) + (defbehavior battlecontroller-spawners-full? battlecontroller () (dotimes (v1-0 (-> self spawner-count)) (if (= (-> self spawner-array v1-0 creature) #f) (return #f))) @@ -301,7 +304,7 @@ battlecontroller-default-event-handler (let ((v1-8 (-> self child))) (while v1-8 (+! gp-0 1) (set! v1-8 (-> v1-8 0 brother)) (nop!) (nop!))) (if (and (zero? gp-0) (= (-> self spawn-count) (-> self max-spawn-count))) (go-virtual battlecontroller-die)) (when (< gp-0 (-> self target-count)) - (let ((gp-1 (current-time))) (until (time-elapsed? gp-1 (-> self spawn-period)) (suspend))) + (suspend-for (-> self spawn-period)) (battlecontroller-spawn-creature-random-spawner)))) (suspend))) :post #f) @@ -373,11 +376,11 @@ battlecontroller-default-event-handler (process-entity-status! self (entity-perm-status dead) #t)) :post #f) -(defmethod relocate ((this battlecontroller) (arg0 int)) +(defmethod relocate ((this battlecontroller) (offset int)) (dotimes (v1-0 (-> this spawner-count)) - (let ((a0-3 (-> this spawner-array v1-0))) (if (nonzero? (-> a0-3 path)) (&+! (-> a0-3 path) arg0)))) - (if (nonzero? (-> this path-spawn)) (&+! (-> this path-spawn) arg0)) - (call-parent-method this arg0)) + (let ((a0-3 (-> this spawner-array v1-0))) (if (nonzero? (-> a0-3 path)) (&+! (-> a0-3 path) offset)))) + (if (nonzero? (-> this path-spawn)) (&+! (-> this path-spawn) offset)) + (call-parent-method this offset)) (defmethod deactivate ((this battlecontroller)) (with-pp diff --git a/goal_src/jak1/levels/finalboss/final-door.gc b/goal_src/jak1/levels/finalboss/final-door.gc index bc0ba7ac4f..c7cd44675d 100644 --- a/goal_src/jak1/levels/finalboss/final-door.gc +++ b/goal_src/jak1/levels/finalboss/final-door.gc @@ -11,6 +11,7 @@ (deftype fin-door (process-hidden) ()) + (deftype final-door (process-drawable) () (:state-methods idle) @@ -18,6 +19,7 @@ (final-door-method-21 (_type_) none) (open (symbol) _type_ :state))) + (defskelgroup *power-left-sg* power-left power-left-lod0-jg @@ -110,8 +112,10 @@ (deftype power-left (final-door) ()) + (deftype power-right (final-door) ()) + (defstate idle (power-left) :virtual #t :code @@ -151,6 +155,7 @@ (jump () _type_ :state) (idle () _type_ :state))) + (defstate jump (powercellalt) :virtual #t :code @@ -263,7 +268,7 @@ (t9-16 (the-as powercellalt sv-144) s1-0 'powercellalt (the-as pointer #x70004000))) (run-now-in-process sv-144 powercellalt-init-by-other s4-3 s3-1 sv-160 s0-0) (-> sv-144 ppointer)))) - (let ((s1-1 (current-time))) (until (time-elapsed? s1-1 (seconds 0.1)) (suspend))) + (suspend-for (seconds 0.1)) (when (handle->process arg1) (let ((s1-2 (handle->process arg1)) (s0-1 (+ s2-0 4))) @@ -274,8 +279,8 @@ (t9-20 (the-as powercellalt sv-176) s1-2 'powercellalt (the-as pointer #x70004000))) (run-now-in-process sv-176 powercellalt-init-by-other s4-3 s3-1 sv-192 s0-1) (-> sv-176 ppointer)))) - (let ((s1-3 (current-time))) (until (time-elapsed? s1-3 (seconds 0.1)) (suspend))))) - (let ((gp-1 (current-time))) (until (time-elapsed? gp-1 (seconds 2)) (suspend))) + (suspend-for (seconds 0.1)))) + (suspend-for (seconds 2)) (let ((v0-22 (entity-by-name "sage-finalboss-1")) (a1-26 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-26 from) self) diff --git a/goal_src/jak1/levels/finalboss/sage-finalboss.gc b/goal_src/jak1/levels/finalboss/sage-finalboss.gc index 3af6147864..ebe5186e3d 100644 --- a/goal_src/jak1/levels/finalboss/sage-finalboss.gc +++ b/goal_src/jak1/levels/finalboss/sage-finalboss.gc @@ -47,6 +47,7 @@ (speed float) (touch-time time-frame))) + (defmethod get-unlit-skel ((this plat-eco-finalboss)) *plat-eco-finalboss-unlit-sg*) @@ -114,6 +115,7 @@ (active symbol)) :allow-misaligned) + (deftype sage-finalboss (process-taskable) ((redsage handle) (bluesage handle) @@ -135,11 +137,12 @@ (:states sage-finalboss-credits)) -(defmethod relocate ((this sage-finalboss) (arg0 int)) + +(defmethod relocate ((this sage-finalboss) (offset int)) (dotimes (v1-0 9) - (if (nonzero? (-> this particle v1-0 part)) (&+! (-> this particle v1-0 part) arg0))) - (if (nonzero? (-> this particle-whiteout)) (&+! (-> this particle-whiteout) arg0)) - (the-as sage-finalboss ((method-of-type process-taskable relocate) this arg0))) + (if (nonzero? (-> this particle v1-0 part)) (&+! (-> this particle v1-0 part) offset))) + (if (nonzero? (-> this particle-whiteout)) (&+! (-> this particle-whiteout) offset)) + (the-as sage-finalboss ((method-of-type process-taskable relocate) this offset))) (defmethod deactivate ((this sage-finalboss)) (dotimes (s5-0 9) @@ -619,7 +622,7 @@ (remove-setting! 'music) (apply-settings *setting-control*) (set-blackout-frames (seconds 0.05)) - (let ((gp-1 (current-time))) (until (time-elapsed? gp-1 (seconds 0.05)) (suspend))) + (suspend-for (seconds 0.05)) (go-virtual hidden))) (defmethod should-display? ((this sage-finalboss)) diff --git a/goal_src/jak1/levels/flut_common/flutflut.gc b/goal_src/jak1/levels/flut_common/flutflut.gc index bc3162e70e..f2785a9907 100644 --- a/goal_src/jak1/levels/flut_common/flutflut.gc +++ b/goal_src/jak1/levels/flut_common/flutflut.gc @@ -29,10 +29,11 @@ (pickup (state flutflut)) wait-for-return)) -(defmethod relocate ((this flutflut) (arg0 int)) + +(defmethod relocate ((this flutflut) (offset int)) (countdown (v1-0 2) - (if (-> this path-data v1-0) (&+! (-> this path-data v1-0) arg0))) - (the-as flutflut ((method-of-type process-drawable relocate) this arg0))) + (if (-> this path-data v1-0) (&+! (-> this path-data v1-0) offset))) + (the-as flutflut ((method-of-type process-drawable relocate) this offset))) (define *flutflut-shadow-control* (new 'static @@ -156,11 +157,8 @@ (let ((v1-35 gp-0)) (set! (-> v1-35 height) (the float 80))) (set! (-> gp-0 flags) (font-flags shadow kerning large)) (print-game-text (lookup-text! *common-text* (text-id press-to-use) #f) gp-0 #f 128 22)) - (if *allow-flutflut-anywhere* ;; if "self" is passed instead of #f, deloading level/flutflut will crash - (if (and (cpad-pressed? 0 circle) (send-event *target* 'change-mode 'flut #f)) - (go-virtual pickup (method-of-object self wait-for-return))) (if (and (cpad-pressed? 0 circle) (send-event *target* 'change-mode 'flut self)) - (go-virtual pickup (method-of-object self wait-for-return)))))) + (go-virtual pickup (method-of-object self wait-for-return))))) (flutflut-effect) (suspend) (ja :num! (loop!)))) @@ -193,7 +191,7 @@ (while (and *target* (logtest? (-> *target* control root-prim prim-core action) (collide-action flut))) (flutflut-effect) (suspend)) - (let ((s5-0 (current-time))) (until (time-elapsed? s5-0 (seconds 1)) (flutflut-effect) (suspend))) + (suspend-for (seconds 1) (flutflut-effect)) (go arg0))) (defstate wait-for-return (flutflut) diff --git a/goal_src/jak1/levels/flut_common/target-flut.gc b/goal_src/jak1/levels/flut_common/target-flut.gc index 9c0ea39d2b..7f6ab936a0 100644 --- a/goal_src/jak1/levels/flut_common/target-flut.gc +++ b/goal_src/jak1/levels/flut_common/target-flut.gc @@ -18,6 +18,7 @@ (stick-lock basic) (flap-sound-id sound-id))) + (deftype flut-bank (basic) ((jump-height-min meters) (jump-height-max meters) @@ -26,6 +27,7 @@ (air-attack-speed meters) (ground-timeout time-frame))) + (define *FLUT-bank* (new 'static 'flut-bank @@ -335,7 +337,9 @@ (set! (-> self flut stick-lock) #f) (set! (-> self flut flap-sound-id) (new-sound-id)) (set! (-> self flut entity) #f) - (let ((v1-11 (handle->process arg0))) (if v1-11 (set! (-> self flut entity) (-> v1-11 entity)))) + (let ((v1-11 (handle->process arg0))) + (if (and (not *allow-flutflut-anywhere*) v1-11) ;; OG-modbase dont track entity, prevents crash on level deload + (set! (-> self flut entity) (-> v1-11 entity)))) (target-collide-set! 'flut (the-as float 0.0)) (set! (-> self control transv quad) (the-as uint128 0)) (set! (-> self control unknown-float01) 0.0) @@ -385,8 +389,7 @@ (behavior () (if (move-legs?) (go target-flut-walk)) ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + (if (and (recently-pressed? x) (can-jump? #f)) (go target-flut-jump (-> *FLUT-bank* jump-height-min) (-> *FLUT-bank* jump-height-max))) (if (can-hands? #t) (go target-flut-running-attack)) (if (and (not (logtest? (-> self control status) (cshape-moving-flags onsurf))) @@ -437,8 +440,7 @@ (behavior () (if (not (move-legs?)) (go target-flut-stance)) ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + (if (and (recently-pressed? x) (can-jump? #f)) (go target-flut-jump (-> *FLUT-bank* jump-height-min) (-> *FLUT-bank* jump-height-max))) (if (can-hands? #t) (go target-flut-running-attack)) (if (and (not (logtest? (-> self control status) (cshape-moving-flags onsurf))) @@ -545,7 +547,7 @@ (behavior () (set! (-> self control unknown-float123) (fmax (-> self control unknown-float123) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton 6))))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton (abutton-idx x)))))) ;; og:preserve-this abutton indexing (if (logtest? (-> self control status) (cshape-moving-flags onsurf)) (go target-flut-hit-ground)) (if (and (cpad-pressed? (-> self control unknown-cpad-info00 number) x) (< (vector-dot (-> self control dynam gravity-normal) (-> self control transv)) 40960.0) @@ -690,10 +692,9 @@ (-> target-flut-start exit) :trans - (behavior () - ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + (behavior () + ;; og:preserve-this - High FPS Fix + (if (and (recently-pressed? x) (can-jump? #f)) (go target-flut-jump (-> *FLUT-bank* jump-height-min) (-> *FLUT-bank* jump-height-max))) (if (move-legs?) (go target-flut-walk)) (if (and (not (logtest? (-> self control status) (cshape-moving-flags onsurf))) @@ -1087,7 +1088,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-known-safe-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) (until (time-elapsed? s3-1 (seconds 1)) (suspend))) + (suspend-for (seconds 1)) (move-to-point! (-> self control) s4-1)) (set! (-> (&-> (-> self control) unknown-qword00) 0) (-> self control trans quad)) (send-event *camera* 'teleport) @@ -1162,24 +1163,22 @@ (vector+! (-> self control transv) (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) f30-0) (vector-float*! gp-3 gp-3 (/ f0-4 f1-3)))))) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 1)) - (target-flut-falling-anim-trans) - (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) - (let ((s5-2 (new-stack-vector0)) - (f30-1 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv))))) - 0.0 - (vector-! s5-2 - (-> self control transv) - (vector-float*! s5-2 (-> self control dynam gravity-normal) (the-as float f30-1))) - (let* ((f0-10 (vector-length s5-2)) - (f1-4 f0-10)) - (if (< (the-as float (-> self control unknown-uint20)) (the-as float f30-1)) (set! f30-1 (-> self control unknown-uint20))) - (vector+! (-> self control transv) - (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f30-1)) - (vector-float*! s5-2 s5-2 (/ f0-10 f1-4))))) - (target-flut-post-post) - (suspend))) + (suspend-for (seconds 1) + (target-flut-falling-anim-trans) + (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) + (let ((s5-2 (new-stack-vector0)) + (f30-1 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv))))) + 0.0 + (vector-! s5-2 + (-> self control transv) + (vector-float*! s5-2 (-> self control dynam gravity-normal) (the-as float f30-1))) + (let* ((f0-10 (vector-length s5-2)) + (f1-4 f0-10)) + (if (< (the-as float (-> self control unknown-uint20)) (the-as float f30-1)) (set! f30-1 (-> self control unknown-uint20))) + (vector+! (-> self control transv) + (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f30-1)) + (vector-float*! s5-2 s5-2 (/ f0-10 f1-4))))) + (target-flut-post-post)) (camera-change-to (the-as string 'base) 0 #f)) (else (set! (-> self control unknown-surface00) *neutral-mods*) diff --git a/goal_src/jak1/levels/jungle/darkvine.gc b/goal_src/jak1/levels/jungle/darkvine.gc index 608dfabde3..8ce47ceaaf 100644 --- a/goal_src/jak1/levels/jungle/darkvine.gc +++ b/goal_src/jak1/levels/jungle/darkvine.gc @@ -23,6 +23,7 @@ darkvine-idle darkvine-retreat)) + (defmethod run-logic? ((this darkvine)) (or (not (logtest? (-> this mask) (process-mask actor-pause))) (or (and (nonzero? (-> this draw)) @@ -167,7 +168,7 @@ (suspend) (ja :num! (seek!))) (ja-channel-set! 0) - (let ((gp-0 (current-time))) (until (time-elapsed? gp-0 (seconds 2)) (suspend))) + (suspend-for (seconds 2)) (process-spawn part-tracker :init part-tracker-init @@ -179,7 +180,7 @@ (-> self root trans) :to *entity-pool*) - (let ((gp-2 (current-time))) (until (time-elapsed? gp-2 (seconds 0.5)) (suspend))) + (suspend-for (seconds 0.5)) (set! (-> self dangerous) #t) (logior! (-> self mask) (process-mask actor-pause)) (ja-channel-set! 1) diff --git a/goal_src/jak1/levels/jungle/fisher.gc b/goal_src/jak1/levels/jungle/fisher.gc index 6937772412..7dcd04c95f 100644 --- a/goal_src/jak1/levels/jungle/fisher.gc +++ b/goal_src/jak1/levels/jungle/fisher.gc @@ -15,6 +15,7 @@ (max-caught int32) (max-missed int32))) + (define *FISHER-bank* (new 'static 'fisher-bank :width (meters 3.3) :net-radius (meters 0.7) :max-caught #xc8 :max-missed 20)) @@ -148,6 +149,7 @@ (powerup-percent float)) :allow-misaligned) + (define *fisher-params* (new 'static 'boxed-array @@ -696,6 +698,7 @@ fisher-done fisher-playing)) + (deftype fisher-fish (process-drawable) ((dir vector :inline) (offset float) @@ -708,6 +711,7 @@ fisher-fish-die fisher-fish-fall)) + (defskelgroup *catch-fisha-sg* catch-fisha catch-fisha-lod0-jg @@ -1084,7 +1088,7 @@ (-> gp-2 user-uint8 6))) (process-spawn-function process (lambda :behavior process () - (let ((gp-0 (current-time))) (until (time-elapsed? gp-0 (seconds 0.1)) (suspend))) + (suspend-for (seconds 0.1)) (ambient-hint-spawn "st-lose" (the-as vector #f) *entity-pool* 'stinger) (none))) (send-event *target* 'lose)))) @@ -1400,13 +1404,13 @@ (launch-particles (-> *part-id-table* 828) gp-0) (launch-particles (-> *part-id-table* 2013) gp-0) (fisher-fish-water gp-0 (+ 32768.0 (vector-y-angle (-> self node-list data 80 bone transform vector 1)))))) - (let ((t9-14 (-> (find-parent-state) trans))) (if t9-14 (t9-14))))) + (call-parent-state-handler trans))) (defstate idle (fisher) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) (if t9-1 (t9-1))) + (call-parent-state-handler trans) (when (task-complete? *game-info* (-> self entity extra perm task)) (when (nonzero? (-> *cpad-list* cpads 0 button0-rel 0)) (let ((v1-9 (-> self cheat-temp))) diff --git a/goal_src/jak1/levels/jungle/jungle-elevator.gc b/goal_src/jak1/levels/jungle/jungle-elevator.gc index 9e9140d126..cb790ddb35 100644 --- a/goal_src/jak1/levels/jungle/jungle-elevator.gc +++ b/goal_src/jak1/levels/jungle/jungle-elevator.gc @@ -10,6 +10,7 @@ (teleport-if-below-y float) (teleport-if-above-y float))) + (defmethod can-activate? ((this jungle-elevator)) (and ((method-of-type plat-button can-activate?) this) (task-complete? *game-info* (game-task jungle-tower)))) @@ -31,7 +32,7 @@ (let ((s5-0 (new 'stack-no-clear 'vector)) (gp-0 (new 'stack-no-clear 'vector))) (set! (-> s5-0 quad) (-> self root trans quad)) - (let ((t9-1 (-> (find-parent-state) trans))) (if t9-1 (t9-1))) + (call-parent-state-handler trans) (vector-! gp-0 (-> self root trans) s5-0) (when (< (-> self path-pos) 0.9) (move-by-vector! (-> *target* control) gp-0) diff --git a/goal_src/jak1/levels/jungle/jungle-mirrors.gc b/goal_src/jak1/levels/jungle/jungle-mirrors.gc index c935d53dbf..e3dc34a44f 100644 --- a/goal_src/jak1/levels/jungle/jungle-mirrors.gc +++ b/goal_src/jak1/levels/jungle/jungle-mirrors.gc @@ -493,10 +493,11 @@ periscope-wait-for-player periscope-wait-for-power-input)) -(defmethod relocate ((this periscope) (arg0 int)) - (if (nonzero? (-> this grips)) (&+! (-> this grips) arg0)) - (if (nonzero? (-> this part-aligned)) (&+! (-> this part-aligned) arg0)) - (the-as periscope ((method-of-type process-drawable relocate) this arg0))) + +(defmethod relocate ((this periscope) (offset int)) + (if (nonzero? (-> this grips)) (&+! (-> this grips) offset)) + (if (nonzero? (-> this part-aligned)) (&+! (-> this part-aligned) offset)) + (the-as periscope ((method-of-type process-drawable relocate) this offset))) (defmethod deactivate ((this periscope)) (if (nonzero? (-> this part-aligned)) (kill-and-free-particles (-> this part-aligned))) @@ -509,6 +510,7 @@ (:states reflector-idle)) + (deftype reflector-origin (process-drawable) ((reflector-trans vector :inline) (next-reflector-trans vector :inline) @@ -518,12 +520,14 @@ (:states reflector-origin-idle)) + (deftype reflector-mirror (process-drawable) ((root collide-shape :override) (beam-end vector :inline)) (:states (reflector-mirror-broken symbol) reflector-mirror-idle)) + (defskelgroup *periscope-base-sg* periscope periscope-base-lod0-jg @@ -1436,7 +1440,7 @@ (ambient-hint-spawn "gamcam21" (the-as vector #f) *entity-pool* 'camera) (let ((v1-11 (manipy-spawn (-> self root trans) (-> self entity) *reflector-mirror-break-sg* #f :to self))) (send-event (ppointer->process v1-11) 'anim-mode 'play1)) - (let ((gp-2 (current-time))) (until (time-elapsed? gp-2 (seconds 0.5)) (suspend))) + (suspend-for (seconds 0.5)) (process-grab? *target*) (while (or (-> self child) (-> *setting-control* current ambient)) (suspend)) diff --git a/goal_src/jak1/levels/jungleb/jungleb-obs.gc b/goal_src/jak1/levels/jungleb/jungleb-obs.gc index fe50c22ab6..30dc79f301 100644 --- a/goal_src/jak1/levels/jungleb/jungleb-obs.gc +++ b/goal_src/jak1/levels/jungleb/jungleb-obs.gc @@ -14,6 +14,7 @@ (:states (eggtop-close symbol) eggtop-idle)) + (defskelgroup *eggtop-sg* eggtop eggtop-lod0-jg @@ -204,11 +205,11 @@ (lambda :behavior camera-tracker () (while (not (process-grab? *target*)) (suspend)) - (let ((gp-0 (current-time))) (until (time-elapsed? gp-0 (seconds 1)) (suspend))) + (suspend-for (seconds 1)) (send-event *camera* 'blend-from-as-fixed) (camera-look-at (the-as pair "ecovent-171") (the-as uint 0)) (camera-change-to "camera-223" 0 #f) - (let ((gp-1 (current-time))) (until (time-elapsed? gp-1 (seconds 3)) (suspend))) + (suspend-for (seconds 3)) (while (not (process-release? (handle->process (-> self grab-target)))) (suspend)) (send-event *camera* 'blend-from-as-fixed) @@ -271,6 +272,7 @@ (deftype jng-iris-door (eco-door) ()) + (defskelgroup *jng-iris-door-sg* jng-iris-door jng-iris-door-lod0-jg diff --git a/goal_src/jak1/levels/jungleb/plant-boss.gc b/goal_src/jak1/levels/jungleb/plant-boss.gc index 8324ca5e94..711a59cdd5 100644 --- a/goal_src/jak1/levels/jungleb/plant-boss.gc +++ b/goal_src/jak1/levels/jungleb/plant-boss.gc @@ -40,13 +40,14 @@ plant-boss-spawn plant-boss-vulnerable)) -(defmethod relocate ((this plant-boss) (arg0 int)) - (if (nonzero? (-> this neck)) (&+! (-> this neck) arg0)) - (if (nonzero? (-> this body)) (&+! (-> this body) arg0)) + +(defmethod relocate ((this plant-boss) (offset int)) + (if (nonzero? (-> this neck)) (&+! (-> this neck) offset)) + (if (nonzero? (-> this body)) (&+! (-> this body) offset)) (dotimes (v1-8 3) - (if (nonzero? (-> this attack-prim v1-8)) (&+! (-> this attack-prim v1-8) arg0)) - (if (nonzero? (-> this death-prim v1-8)) (&+! (-> this death-prim v1-8) arg0))) - (call-parent-method this arg0)) + (if (nonzero? (-> this attack-prim v1-8)) (&+! (-> this attack-prim v1-8) offset)) + (if (nonzero? (-> this death-prim v1-8)) (&+! (-> this death-prim v1-8) offset))) + (call-parent-method this offset)) (deftype plant-boss-arm (process-drawable) ((root collide-shape :override) @@ -64,6 +65,7 @@ (plant-boss-vine-hit basic) plant-boss-vine-idle)) + (deftype plant-boss-leaf (process-drawable) ((root collide-shape-moving :override) (side int32) @@ -77,6 +79,7 @@ (plant-boss-leaf-open symbol) (plant-boss-leaf-open-idle symbol))) + (defskelgroup *plant-boss-sg* plant-boss plant-boss-main-lod0-jg @@ -356,11 +359,8 @@ :code (behavior ((arg0 symbol)) (when (not arg0) - (let ((f30-0 (rand-vu-float-range (the-as float 0.0) (the-as float 1.0))) - (gp-0 (current-time))) - (until (time-elapsed? gp-0 (the int (* 300.0 f30-0))) - (ja :num! (loop!)) - (suspend))) + (let ((f30-0 (rand-vu-float-range (the-as float 0.0) (the-as float 1.0)))) + (suspend-for (the int (* 300.0 f30-0)) (ja :num! (loop!)))) (ja-channel-push! 1 (seconds 0.25)) (ja-no-eval :group! plant-boss-vine-die-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) @@ -387,11 +387,7 @@ (defstate plant-boss-root-die (plant-boss-arm) :code (behavior ((arg0 symbol)) - (when (not arg0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 4)) - (+! (-> self root trans z) (* -4096.0 (seconds-per-frame))) - (suspend))))) + (if (not arg0) (suspend-for (seconds 4) (+! (-> self root trans z) (* -4096.0 (seconds-per-frame)))))) :post ja-post) (defbehavior plant-boss-arm-init plant-boss-arm ((arg0 vector) (arg1 float) (arg2 int)) @@ -733,7 +729,7 @@ (while (not (send-event *camera* 'intro-done?)) (suspend)) (camera-change-to "camera-222" 600 #f) - (let ((gp-0 (current-time))) (until (time-elapsed? gp-0 (seconds 2)) (suspend))) + (suspend-for (seconds 2)) (while (not (process-release? (handle->process (-> self grab-target)))) (suspend)) (send-event *camera* 'blend-from-as-fixed) @@ -1203,11 +1199,7 @@ (behavior () (ja-channel-set! 1) (ja :group! plant-boss-main-die-ja :num! max) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 5)) - (transform-post) - (do-push-aways! (-> self root)) - (suspend))) + (suspend-for (seconds 5) (transform-post) (do-push-aways! (-> self root))) (loop (logior! (-> self mask) (process-mask sleep)) (suspend)))) diff --git a/goal_src/jak1/levels/maincave/baby-spider.gc b/goal_src/jak1/levels/maincave/baby-spider.gc index b231467314..ef91eee63c 100644 --- a/goal_src/jak1/levels/maincave/baby-spider.gc +++ b/goal_src/jak1/levels/maincave/baby-spider.gc @@ -23,6 +23,7 @@ (init! (_type_ symbol symbol symbol symbol int int symbol) none) (set-delay! (_type_ time-frame) none))) + (deftype baby-spider (nav-enemy) ((die-if-not-visible? symbol) (hack-move-above-ground? symbol) @@ -45,6 +46,7 @@ baby-spider-hatching baby-spider-resume)) + (defskelgroup *baby-spider-sg* baby-spider baby-spider-lod0-jg @@ -380,13 +382,8 @@ baby-spider-default-event-handler (ja :num! (seek! max f30-0))) (ja-no-eval :num! (loop!)) (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) - (let ((gp-0 (rand-vu-int-range 300 600)) - (s5-0 (current-time))) - (until (time-elapsed? s5-0 gp-0) - (ja :num-func num-func-identity :frame-num 0.0) - (ja-blend-eval) - (suspend) - (suspend))))))) + (let ((gp-0 (rand-vu-int-range 300 600))) + (suspend-for gp-0 (ja :num-func num-func-identity :frame-num 0.0) (ja-blend-eval) (suspend))))))) (defstate nav-enemy-give-up (baby-spider) :virtual #t diff --git a/goal_src/jak1/levels/maincave/dark-crystal.gc b/goal_src/jak1/levels/maincave/dark-crystal.gc index 423949601e..62dd41fa07 100644 --- a/goal_src/jak1/levels/maincave/dark-crystal.gc +++ b/goal_src/jak1/levels/maincave/dark-crystal.gc @@ -25,6 +25,7 @@ dark-crystal-idle dark-crystal-spawn-fuel-cell)) + (defskelgroup *dark-crystal-sg* dark-crystal dark-crystal-lod0-jg @@ -459,7 +460,7 @@ (-> self root trans) :to *entity-pool*) - (let ((s5-4 (current-time))) (until (time-elapsed? s5-4 (seconds 0.25)) (suspend))) + (suspend-for (seconds 0.25)) (if gp-1 (go dark-crystal-spawn-fuel-cell))) (cleanup-for-death self) (until (not (-> self child)) diff --git a/goal_src/jak1/levels/misty/babak-with-cannon.gc b/goal_src/jak1/levels/misty/babak-with-cannon.gc index 866ee65c86..29263e6a7c 100644 --- a/goal_src/jak1/levels/misty/babak-with-cannon.gc +++ b/goal_src/jak1/levels/misty/babak-with-cannon.gc @@ -15,6 +15,7 @@ babak-with-cannon-jump-onto-cannon babak-with-cannon-shooting)) + nav-enemy-default-event-handler (defstate nav-enemy-idle (babak-with-cannon) @@ -206,7 +207,7 @@ nav-enemy-default-event-handler (behavior () (if (and *target* (= (-> *target* current-level name) 'beach)) (spool-push *art-control* "beachcam-cannon" 0 self -1.0)) (if (and *target* (= (-> *target* current-level name) 'misty)) (spool-push *art-control* "mistycam-cannon" 0 self -1.0)) - (let ((t9-3 (-> (find-parent-state) trans))) (if t9-3 (t9-3))))) + (call-parent-state-handler trans))) (defstate nav-enemy-fuel-cell (babak-with-cannon) :virtual #t diff --git a/goal_src/jak1/levels/misty/balloonlurker.gc b/goal_src/jak1/levels/misty/balloonlurker.gc index ef6ce49ef1..e7deb7bce8 100644 --- a/goal_src/jak1/levels/misty/balloonlurker.gc +++ b/goal_src/jak1/levels/misty/balloonlurker.gc @@ -211,6 +211,7 @@ (explosion-force float) (mine-weight float))) + (define *BALLOONLURKER-bank* (new 'static 'balloonlurker-bank @@ -281,6 +282,7 @@ (balloonlurker-mine-explode int) balloonlurker-patrol)) + (deftype balloonlurker-pilot (process-drawable) ((root collide-shape-moving :override) (parent-override (pointer balloonlurker) :overlay-at parent)) @@ -291,6 +293,7 @@ balloonlurker-pilot-die balloonlurker-pilot-idle)) + (defskelgroup *balloonlurker-sg* balloonlurker balloonlurker-lod0-jg @@ -586,7 +589,7 @@ (apply-all (-> self link) actor-link-dead-hook (& sv-16)) (when (and sv-16 sv-24) (process-grab? *target*) - (let ((gp-0 (current-time))) (until (time-elapsed? gp-0 (seconds 1)) (suspend))) + (suspend-for (seconds 1)) (process-release? *target*) (while (let ((a1-4 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-4 from) self) @@ -607,12 +610,12 @@ (suspend))) :post balloonlurker-post) -(defmethod relocate ((this balloonlurker) (arg0 int)) - (if (nonzero? (-> this propeller)) (&+! (-> this propeller) arg0)) - (if (nonzero? (-> this rudder)) (&+! (-> this rudder) arg0)) - (if (nonzero? (-> this mine 0)) (&+! (-> this mine 0) arg0)) - (if (nonzero? (-> this mine 1)) (&+! (-> this mine 1) arg0)) - (call-parent-method this arg0)) +(defmethod relocate ((this balloonlurker) (offset int)) + (if (nonzero? (-> this propeller)) (&+! (-> this propeller) offset)) + (if (nonzero? (-> this rudder)) (&+! (-> this rudder) offset)) + (if (nonzero? (-> this mine 0)) (&+! (-> this mine 0) offset)) + (if (nonzero? (-> this mine 1)) (&+! (-> this mine 1) offset)) + (call-parent-method this offset)) (defstate balloonlurker-pilot-idle (balloonlurker-pilot) :event diff --git a/goal_src/jak1/levels/misty/misty-warehouse.gc b/goal_src/jak1/levels/misty/misty-warehouse.gc index cffe44e544..852e98920b 100644 --- a/goal_src/jak1/levels/misty/misty-warehouse.gc +++ b/goal_src/jak1/levels/misty/misty-warehouse.gc @@ -15,6 +15,7 @@ silostep-idle (silostep-rise symbol))) + (defskelgroup *silostep-sg* silostep silostep-lod0-jg @@ -45,7 +46,7 @@ (while (not (process-grab? *target*)) (suspend)) (camera-change-to "camera-160" 150 #f) - (let ((gp-0 (current-time))) (until (time-elapsed? gp-0 (seconds 3)) (suspend))) + (suspend-for (seconds 3)) (while (not (process-release? (handle->process (-> self grab-target)))) (suspend)) (camera-change-to (the-as string 'base) 150 #f) @@ -62,7 +63,7 @@ (v1-1 (get-reminder gp-0 0))) (save-reminder gp-0 (logior v1-1 2) 0)) (set-time! (-> self state-time)) - (let ((gp-1 (current-time))) (until (time-elapsed? gp-1 (seconds 1)) (suspend))) + (suspend-for (seconds 1)) (sound-play "arena-steps") (send-to-all-after (-> self link) 'trigger-rise) (go silostep-rise #f)) @@ -124,6 +125,7 @@ (deftype rounddoor (eco-door) ()) + (defmethod eco-door-method-24 ((this rounddoor)) (let ((s5-0 (new 'process 'collide-shape this (collide-list-enum hit-by-others)))) (let ((s4-0 (new 'process 'collide-shape-prim-mesh s5-0 (the-as uint 0) (the-as uint 0)))) diff --git a/goal_src/jak1/levels/misty/mistycannon.gc b/goal_src/jak1/levels/misty/mistycannon.gc index 3124999c13..c2fb6a7189 100644 --- a/goal_src/jak1/levels/misty/mistycannon.gc +++ b/goal_src/jak1/levels/misty/mistycannon.gc @@ -13,6 +13,7 @@ (range float) (speed float))) + (defun angle-tracker-apply-move! ((arg0 angle-tracker) (arg1 float)) (let* ((f0-2 (* arg1 (-> arg0 speed) (seconds-per-frame))) (f0-3 (+ (-> arg0 value) f0-2))) @@ -530,9 +531,10 @@ mistycannon-missile-idle mistycannon-missile-in-water)) -(defmethod relocate ((this mistycannon-missile) (arg0 int)) - (if (nonzero? (-> this part2)) (&+! (-> this part2) arg0)) - (the-as mistycannon-missile ((method-of-type process-drawable relocate) this arg0))) + +(defmethod relocate ((this mistycannon-missile) (offset int)) + (if (nonzero? (-> this part2)) (&+! (-> this part2) offset)) + (the-as mistycannon-missile ((method-of-type process-drawable relocate) this offset))) (defmethod deactivate ((this mistycannon-missile)) (if (nonzero? (-> this part2)) (kill-and-free-particles (-> this part2))) @@ -720,10 +722,7 @@ (find-overlapping-shapes (-> self root) a1-3)) (suspend) (clear-collide-with-as (-> self root)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 3)) - (spawn (-> self part2) (-> self root trans)) - (suspend))) + (suspend-for (seconds 3) (spawn (-> self part2) (-> self root trans))) (kill-and-free-particles (-> self part2)) (deactivate self)) :post ja-post) @@ -748,6 +747,7 @@ (muzzle-time float) (blast-radius float))) + (defbehavior mistycannon-missile-init-by-other mistycannon-missile ((arg0 mistycannon-init-data) (arg1 entity-actor)) (logior! (-> self mask) (process-mask projectile)) (logclear! (-> self mask) (process-mask actor-pause)) @@ -829,6 +829,7 @@ mistycannon-waiting-for-player mistycannon-waiting-for-player-to-fuck-off)) + (defbehavior mistycannon-pick-random-target-point mistycannon () (let ((f30-0 (* (sqrtf (rand-vu)) (-> self center-point w))) (f28-1 (* 65536.0 (rand-vu)))) @@ -965,6 +966,7 @@ ((s1 float) (s2 float))) + (defun solve-missile-tilt ((arg0 quadratic-solution) (arg1 float) (arg2 float) (arg3 float) (arg4 float)) (let* ((f1-3 (* 0.5 arg2 arg2 arg4)) (f0-3 f1-3) @@ -986,6 +988,7 @@ (speed float) (time float))) + (defun solve-missile-velocity ((arg0 trajectory-params) (arg1 float)) (set! (-> arg0 theta) arg1) (let ((f0-4 (* (- (* (-> arg0 x) (tan arg1)) (-> arg0 y)) (/ 2.0 (-> arg0 gravity))))) diff --git a/goal_src/jak1/levels/ogre/flying-lurker.gc b/goal_src/jak1/levels/ogre/flying-lurker.gc index 9e3528c249..f6185b2034 100644 --- a/goal_src/jak1/levels/ogre/flying-lurker.gc +++ b/goal_src/jak1/levels/ogre/flying-lurker.gc @@ -24,6 +24,7 @@ plunger-lurker-idle plunger-lurker-plunge)) + (defskelgroup *plunger-lurker-sg* plunger-lurker plunger-lurker-lod0-jg @@ -235,6 +236,7 @@ flying-lurker-sleep flying-lurker-start)) + (defskelgroup *flying-lurker-sg* flying-lurker flying-lurker-lod0-jg @@ -607,7 +609,7 @@ (process-release? *target*) (process-spawn-function process (lambda :behavior process () - (let ((gp-0 (current-time))) (until (time-elapsed? gp-0 (seconds 0.1)) (suspend))) + (suspend-for (seconds 0.1)) (level-hint-spawn (text-id ogre-race-hint) "asstvb24" (the-as entity #f) *entity-pool* (game-task none)) (none)) :to @@ -761,7 +763,7 @@ (if (= (get-task-status (game-task plunger-lurker-hit)) (task-status invalid)) (go flying-lurker-die)) (when (and *target* (>= 172032.0 (vector-vector-xz-distance (-> self root trans) (-> *target* control trans)))) (process-grab? *target*) - (let ((s5-0 (current-time))) (until (time-elapsed? s5-0 (seconds 1)) (suspend))) + (suspend-for (seconds 1)) (process-release? *target*) (send-event self 'saw-player)) (suspend) diff --git a/goal_src/jak1/levels/ogre/ogreboss.gc b/goal_src/jak1/levels/ogre/ogreboss.gc index 4df1790955..142c6928ab 100644 --- a/goal_src/jak1/levels/ogre/ogreboss.gc +++ b/goal_src/jak1/levels/ogre/ogreboss.gc @@ -106,6 +106,7 @@ ogreboss-missile-impact ogreboss-missile-seek)) + (defstate ogreboss-missile-idle (ogreboss-missile) :enter (behavior () @@ -272,6 +273,7 @@ (blast-radius float) (pickup-type pickup-type))) + (defbehavior ogreboss-missile-init-by-other ogreboss-missile ((arg0 ogreboss-missile-init-data) (arg1 entity-actor)) (set! (-> self entity) arg1) (let ((s5-0 (new 'process 'collide-shape-moving self (collide-list-enum hit-by-player)))) @@ -338,6 +340,7 @@ ogreboss-super-boulder-roll ogreboss-super-boulder-throw)) + (defbehavior ogreboss-super-boulder-event-handler ogreboss-super-boulder ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) (case arg2 ;; og:preserve-this PAL patch here @@ -532,9 +535,9 @@ (transform-post) 0)) -(defmethod relocate ((this ogreboss-super-boulder) (arg0 int)) - (if (nonzero? (-> this joint)) (&+! (-> this joint) arg0)) - (call-parent-method this arg0)) +(defmethod relocate ((this ogreboss-super-boulder) (offset int)) + (if (nonzero? (-> this joint)) (&+! (-> this joint) offset)) + (call-parent-method this offset)) (defstate ogreboss-super-boulder-killed-player (ogreboss-super-boulder) :code @@ -594,6 +597,7 @@ (:states ogreboss-bounce-boulder-idle)) + (defbehavior ogreboss-bounce-boulder-event-handler ogreboss-bounce-boulder ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) (case arg2 (('touch) @@ -722,6 +726,7 @@ ogreboss-stage3-throw ogreboss-wait-for-player)) + (defbehavior ogreboss-inc-try-count ogreboss () (when (not (-> self try-counted)) (set! (-> self try-counted) #t) @@ -757,7 +762,7 @@ (until (ja-done? 0) (suspend) (ja :num! (seek! (ja-aframe (the-as float 140.0) 0)))) - (let ((gp-2 (current-time))) (until (time-elapsed? gp-2 (seconds 0.167)) (suspend))) + (suspend-for (seconds 0.167)) (ja-no-eval :group! ogreboss-idle-ja :num! @@ -767,7 +772,7 @@ (until (ja-done? 0) (suspend) (ja :num! (seek! (ja-aframe (the-as float 168.0) 0)))) - (let ((gp-5 (current-time))) (until (time-elapsed? gp-5 (seconds 0.167)) (suspend))) + (suspend-for (seconds 0.167)) (ja-no-eval :group! ogreboss-idle-ja :num! (seek!) :frame-num (ja-aframe (the-as float 168.0) 0)) (until (ja-done? 0) (suspend) @@ -945,7 +950,7 @@ (ja :num! (seek! max arg1))))) (logior! (-> self draw status) (draw-status hidden)) (set! (-> self submerged) #t) - (let ((s5-1 (current-time))) (until (time-elapsed? s5-1 arg0) (suspend)))) + (suspend-for arg0)) 0 (none)) diff --git a/goal_src/jak1/levels/racer_common/racer-states.gc b/goal_src/jak1/levels/racer_common/racer-states.gc index 42ecf184c8..2eb6545ab1 100644 --- a/goal_src/jak1/levels/racer_common/racer-states.gc +++ b/goal_src/jak1/levels/racer_common/racer-states.gc @@ -127,7 +127,9 @@ (set! (-> self racer boost-sound-id) (new 'static 'sound-id)) (set! (-> self racer scrape-sound-id) (new-sound-id)) (set! (-> self racer entity) #f) - (let ((v1-28 (handle->process arg0))) (if v1-28 (set! (-> self racer entity) (-> v1-28 entity)))) + (let ((v1-28 (handle->process arg0))) + (if (and (not *allow-zoomer-anywhere*) v1-28) ;; OG-modbase dont track entity, prevents crash on level deload + (set! (-> self racer entity) (-> v1-28 entity)))) (set! (-> self control surf) *race-track-surface*) (set! (-> self control reaction) racer-collision-reaction) (vector-reset! (-> self racer rot)) @@ -248,8 +250,8 @@ (target-racing-center-anim) ((-> target-racing-start exit))) :trans - (behavior () - ;; og:preserve-this - High FPS Fix + (behavior () + ;; og:preserve-this - High FPS Fix (if (and (recently-pressed? l1 r1) (or (not (time-elapsed? (-> self control unknown-dword11) (seconds 0.1))) (< (vector-dot (-> self control dynam gravity-normal) @@ -369,7 +371,7 @@ (behavior () (set! (-> self control unknown-float123) (fmax (-> self control unknown-float123) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton 6))))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton (abutton-idx x)))))) ;; og:preserve-this abutton indexing (cond ((cpad-pressed? (-> self control unknown-cpad-info00 number) l1 r1) (set-time! (-> self racer slide-down-time 0))) ((not (cpad-hold? (-> self control unknown-cpad-info00 number) l1 r1)) (set! (-> self racer slide-down-time 0) 0) 0) @@ -432,7 +434,7 @@ (behavior () (set! (-> self control unknown-float123) (fmax (-> self control unknown-float123) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton 6))))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton (abutton-idx x)))))) ;; og:preserve-this abutton indexing ;; og:preserve-this - High FPS Fix (if (and (recently-pressed? l1 r1) (or (not (time-elapsed? (-> self control unknown-dword11) (seconds 0.2))) @@ -718,7 +720,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((gp-6 (current-time))) (until (time-elapsed? gp-6 (seconds 2)) (suspend)))) + (suspend-for (seconds 2))) (('endlessfall) (sound-play "death-fall") (camera-change-to (the-as string cam-endlessfall) 30 #f) @@ -734,21 +736,19 @@ (vector+! (-> self control transv) (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) f2-2) (vector-float*! gp-8 gp-8 (/ f0-29 f1-9))))) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 0.75)) - (vector-seek! (-> self draw color-mult) *zero-vector* (* 1.5 (seconds-per-frame))) - (set-forward-vel (* 0.96 (-> self control unknown-float01))) - (let ((s5-3 (new-stack-vector0)) - (f28-0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) - 0.0 - (vector-! s5-3 (-> self control transv) (vector-float*! s5-3 (-> self control dynam gravity-normal) f28-0)) - (let* ((f0-38 (vector-length s5-3)) - (f1-12 f0-38)) - (if (< f30-0 f28-0) (set! f28-0 f30-0)) - (vector+! (-> self control transv) - (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) f28-0) - (vector-float*! s5-3 s5-3 (/ f0-38 f1-12))))) - (suspend)))) + (suspend-for (seconds 0.75) + (vector-seek! (-> self draw color-mult) *zero-vector* (* 1.5 (seconds-per-frame))) + (set-forward-vel (* 0.96 (-> self control unknown-float01))) + (let ((s5-3 (new-stack-vector0)) + (f28-0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) + 0.0 + (vector-! s5-3 (-> self control transv) (vector-float*! s5-3 (-> self control dynam gravity-normal) f28-0)) + (let* ((f0-38 (vector-length s5-3)) + (f1-12 f0-38)) + (if (< f30-0 f28-0) (set! f28-0 f30-0)) + (vector+! (-> self control transv) + (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) f28-0) + (vector-float*! s5-3 s5-3 (/ f0-38 f1-12))))))) (camera-change-to (the-as string 'base) 0 #f))) (set! (-> self control transv quad) (the-as uint128 0)) (set! (-> self control unknown-float01) 0.0) @@ -871,15 +871,13 @@ (ja :chan 1 :group! eichar-racer-turn2-ja :num! (chan 0)) (ja :chan 2 :group! eichar-racer-dig-ja :num! (chan 0)) (ja :chan 3 :group! eichar-racer-dig2-ja :num! (chan 0))) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.5)) - (set! (-> self racer stick-lock) #t) - (set-forward-vel (* 0.9 (-> self control unknown-float01))) - (set! (-> self racer turn-anim-targ) 0.0) - (set! (-> self racer turn-anim-targ) 0.0) - (target-racing-turn-anim) - (seek! (-> self control unknown-vector11 y) 6144.0 (* 3.0 (seconds-per-frame))) - (suspend))) + (suspend-for (seconds 0.5) + (set! (-> self racer stick-lock) #t) + (set-forward-vel (* 0.9 (-> self control unknown-float01))) + (set! (-> self racer turn-anim-targ) 0.0) + (set! (-> self racer turn-anim-targ) 0.0) + (target-racing-turn-anim) + (seek! (-> self control unknown-vector11 y) 6144.0 (* 3.0 (seconds-per-frame)))) (go target-racing-get-off-jump arg0)) :post target-racing-post) diff --git a/goal_src/jak1/levels/racer_common/racer.gc b/goal_src/jak1/levels/racer_common/racer.gc index a6832411f8..bf1bb6eaaa 100644 --- a/goal_src/jak1/levels/racer_common/racer.gc +++ b/goal_src/jak1/levels/racer_common/racer.gc @@ -5,7 +5,6 @@ (require "engine/common-obs/generic-obs.gc") (require "engine/entity/ambient.gc") (require "engine/game/task/task-control.gc") - (define-extern *allow-zoomer-anywhere* symbol) (define-extern blocking-plane-destroy (function none)) @@ -33,10 +32,11 @@ (pickup (state collectable)) wait-for-return)) -(defmethod relocate ((this racer) (arg0 int)) + +(defmethod relocate ((this racer) (offset int)) (countdown (v1-0 2) - (if (-> this path-data v1-0) (&+! (-> this path-data v1-0) arg0))) - (the-as racer ((method-of-type process-drawable relocate) this arg0))) + (if (-> this path-data v1-0) (&+! (-> this path-data v1-0) offset))) + (the-as racer ((method-of-type process-drawable relocate) this offset))) (defskelgroup *racer-sg* racer @@ -154,38 +154,33 @@ (blocking-plane-destroy) (if (not *allow-zoomer-anywhere*) (blocking-plane-spawn (-> self path-target))) (none)) ;; mod-base-change - :exit - (-> (method-of-type racer wait-for-start) - exit) + :exit (-> (method-of-type racer wait-for-start) exit) :code - (behavior () - (ja-channel-set! 1) - (ja :group! racer-racer-idle-ja) - (set! (-> self root root-prim prim-core action) (collide-action solid attackable-unused)) - (set! (-> self root root-prim prim-core offense) (collide-offense indestructible)) - 0.0 - (let ((f30-0 (if (= (-> self condition) 4) 61440.0 20480.0))) - (loop - (if (and *target* (logtest? (-> *target* control root-prim prim-core action) (collide-action racer))) - (go-virtual wait-for-return)) - (when (and (and *target* (>= f30-0 (vector-vector-distance (-> self root trans) (-> *target* control trans)))) - (and (not (movie?)) (not (level-hint-displayed?)))) - (hide-hud) - (level-hint-surpress!) - (kill-current-level-hint '() '(sidekick voicebox) 'exit) - (when (and (hud-hidden?) (can-grab-display? self)) - (let ((gp-0 (new 'stack 'font-context *font-default-matrix* 32 160 0.0 (font-color default) (font-flags shadow kerning)))) - (let ((v1-24 gp-0)) (set! (-> v1-24 width) (the float 440))) - (let ((v1-25 gp-0)) (set! (-> v1-25 height) (the float 80))) - (set! (-> gp-0 flags) (font-flags shadow kerning large)) - (print-game-text (lookup-text! *common-text* (text-id press-to-use) #f) gp-0 #f 128 22)) - (if *allow-zoomer-anywhere* ;; if "self" is passed instead of #f, deloading level/zoomer will crash ;;mod-base-change - (if (and (or (cpad-pressed? 0 circle) (= (-> self condition) 4)) (send-event *target* 'change-mode 'racing #f)) - (go-virtual pickup (the-as (state collectable) (method-of-object self wait-for-return)))) - (if (and (or (cpad-pressed? 0 circle) (= (-> self condition) 4)) (send-event *target* 'change-mode 'racing self)) - (go-virtual pickup (the-as (state collectable) (method-of-object self wait-for-return))))))) - (racer-effect) - (suspend)))) + (behavior () + (ja-channel-set! 1) + (ja :group! racer-racer-idle-ja) + (set! (-> self root root-prim prim-core action) (collide-action solid attackable-unused)) + (set! (-> self root root-prim prim-core offense) (collide-offense indestructible)) + 0.0 + (let ((f30-0 (if (= (-> self condition) 4) 61440.0 20480.0))) + (loop + (if (and *target* (logtest? (-> *target* control root-prim prim-core action) (collide-action racer))) + (go-virtual wait-for-return)) + (when (and (and *target* (>= f30-0 (vector-vector-distance (-> self root trans) (-> *target* control trans)))) + (and (not (movie?)) (not (level-hint-displayed?)))) + (hide-hud) + (level-hint-surpress!) + (kill-current-level-hint '() '(sidekick voicebox) 'exit) + (when (and (hud-hidden?) (can-grab-display? self)) + (let ((gp-0 (new 'stack 'font-context *font-default-matrix* 32 160 0.0 (font-color default) (font-flags shadow kerning)))) + (let ((v1-24 gp-0)) (set! (-> v1-24 width) (the float 440))) + (let ((v1-25 gp-0)) (set! (-> v1-25 height) (the float 80))) + (set! (-> gp-0 flags) (font-flags shadow kerning large)) + (print-game-text (lookup-text! *common-text* (text-id press-to-use) #f) gp-0 #f 128 22)) + (if (and (or (cpad-pressed? 0 circle) (= (-> self condition) 4)) (send-event *target* 'change-mode 'racing self)) + (go-virtual pickup (the-as (state collectable) (method-of-object self wait-for-return)))))) + (racer-effect) + (suspend)))) :post ja-post) (defstate pickup (racer) @@ -226,7 +221,7 @@ (while (and *target* (logtest? (-> *target* control root-prim prim-core action) (collide-action racer))) (racer-effect) (suspend)) - (let ((s5-0 (current-time))) (until (time-elapsed? s5-0 (seconds 1)) (racer-effect) (suspend))) + (suspend-for (seconds 1) (racer-effect)) (go arg0))) (defstate wait-for-return (racer) diff --git a/goal_src/jak1/levels/racer_common/target-racer.gc b/goal_src/jak1/levels/racer_common/target-racer.gc index 47649762c6..463777dca4 100644 --- a/goal_src/jak1/levels/racer_common/target-racer.gc +++ b/goal_src/jak1/levels/racer_common/target-racer.gc @@ -748,23 +748,23 @@ (f28-1 (* f28-0 (cond ((zero? v1-17) - (- (fmax (analog-input (the-as int (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton 8)) + (- (fmax (analog-input (the-as int (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton (abutton-idx l1))) ;; og:preserve-this abutton indexing 0.0 32.0 255.0 1.0) - (analog-input (the-as int (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton 9)) + (analog-input (the-as int (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton (abutton-idx r1))) ;; og:preserve-this abutton indexing 0.0 32.0 255.0 1.0)))) ((= v1-17 1) - (fmax (analog-input (the-as int (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton 8)) + (fmax (analog-input (the-as int (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton (abutton-idx l1))) ;; og:preserve-this abutton indexing 0.0 32.0 255.0 1.0) - (analog-input (the-as int (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton 9)) + (analog-input (the-as int (-> *cpad-list* cpads (-> self control unknown-cpad-info00 number) abutton (abutton-idx r1))) ;; og:preserve-this abutton indexing 0.0 32.0 255.0 diff --git a/goal_src/jak1/levels/snow/snow-obs.gc b/goal_src/jak1/levels/snow/snow-obs.gc index 8c86148af1..f3d3bf3c56 100644 --- a/goal_src/jak1/levels/snow/snow-obs.gc +++ b/goal_src/jak1/levels/snow/snow-obs.gc @@ -12,6 +12,7 @@ (deftype snowcam (pov-camera) ((seq uint64))) + (defskelgroup *snowcam-sg* snowcam snowcam-lod0-jg @@ -42,7 +43,7 @@ (until (ja-done? 0) (suspend) (ja :num! (seek!))) - (let ((gp-0 (current-time))) (until (time-elapsed? gp-0 (seconds 4.5)) (suspend)))) + (suspend-for (seconds 4.5))) ((= v1-0 1) (let ((gp-2 (ppointer->handle (process-spawn fuel-cell :init @@ -82,6 +83,7 @@ snow-eggtop-idle-down snow-eggtop-idle-up)) + (defskelgroup *snow-eggtop-sg* snow-eggtop snow-eggtop-lod0-jg @@ -370,6 +372,7 @@ (:states snowpusher-idle)) + (defskelgroup *snowpusher-sg* snowpusher snowpusher-lod0-jg @@ -451,6 +454,7 @@ (:states snow-spatula-idle)) + (defskelgroup *snow-spatula-sg* snow-spatula snow-spatula-lod0-jg @@ -525,6 +529,7 @@ snow-fort-gate-idle-closed snow-fort-gate-idle-open)) + (defskelgroup *snow-fort-gate-sg* snow-fort-gate snow-fort-gate-lod0-jg @@ -768,10 +773,10 @@ ((method-of-type process-drawable deactivate) this) (none)) -(defmethod relocate ((this snow-fort-gate) (arg0 int)) - (if (nonzero? (-> this part2)) (&+! (-> this part2) arg0)) - (if (nonzero? (-> this part3)) (&+! (-> this part3) arg0)) - (call-parent-method this arg0)) +(defmethod relocate ((this snow-fort-gate) (offset int)) + (if (nonzero? (-> this part2)) (&+! (-> this part2) offset)) + (if (nonzero? (-> this part3)) (&+! (-> this part3) offset)) + (call-parent-method this offset)) (defmethod init-from-entity! ((this snow-fort-gate) (arg0 entity-actor)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-others)))) @@ -817,6 +822,7 @@ snow-gears-idle snow-gears-stopped)) + (defskelgroup *snow-gears-sg* snow-gears snow-gears-lod0-jg @@ -981,6 +987,7 @@ snow-switch-idle-down snow-switch-idle-up)) + (defskelgroup *snow-switch-sg* snow-switch snow-switch-lod0-jg @@ -1120,6 +1127,7 @@ snow-log-hidden snow-log-wait-for-master)) + (defskelgroup *snow-log-sg* snow-log snow-log-lod0-jg @@ -1258,6 +1266,7 @@ snow-log-button-idle-down snow-log-button-idle-up)) + (defbehavior snow-log-button-event-handler snow-log-button ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) (local-vars (v0-2 basic)) (case arg2 diff --git a/goal_src/jak1/levels/snow/target-ice.gc b/goal_src/jak1/levels/snow/target-ice.gc index 5d86c024f7..d5c2a8b6ef 100644 --- a/goal_src/jak1/levels/snow/target-ice.gc +++ b/goal_src/jak1/levels/snow/target-ice.gc @@ -22,13 +22,10 @@ (remove-exit) (go target-duck-stance)) ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + (if (and (recently-pressed? x) (can-jump? #f)) (go target-jump (-> *TARGET-bank* jump-height-min) (-> *TARGET-bank* jump-height-max) (the-as surface #f))) ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? circle) - (can-feet?)) - (go target-attack)) + (if (and (recently-pressed? circle) (can-feet?)) (go target-attack)) (if (can-hands? #t) (go target-running-attack)) (slide-down-test) (fall-test)) @@ -134,13 +131,10 @@ (remove-exit) (go target-ice-stance)) ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + (if (and (recently-pressed? x) (can-jump? #f)) (go target-jump (-> *TARGET-bank* jump-height-min) (-> *TARGET-bank* jump-height-max) (the-as surface #f))) - ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? circle) - (can-feet?)) - (go target-attack)) + ;; og:preserve-this - High FPS Fix + (if (and (recently-pressed? circle) (can-feet?)) (go target-attack)) (if (can-hands? #t) (go target-running-attack)) (slide-down-test) (fall-test)) diff --git a/goal_src/jak1/levels/sunken/target-tube.gc b/goal_src/jak1/levels/sunken/target-tube.gc index 00c81fab3c..888a5ce531 100644 --- a/goal_src/jak1/levels/sunken/target-tube.gc +++ b/goal_src/jak1/levels/sunken/target-tube.gc @@ -435,10 +435,9 @@ (-> target-tube-start exit) :trans - (behavior () + (behavior () ;; og:preserve-this - High FPS Fix - (if (and (recently-pressed? x) - (can-jump? #f)) + (if (and (recently-pressed? x) (can-jump? #f)) (go target-tube-jump (-> *TARGET-bank* tube-jump-height-min) (-> *TARGET-bank* tube-jump-height-max)))) :code (behavior () diff --git a/goal_src/jak1/levels/swamp/billy.gc b/goal_src/jak1/levels/swamp/billy.gc index 49db5ee9e7..6541815595 100644 --- a/goal_src/jak1/levels/swamp/billy.gc +++ b/goal_src/jak1/levels/swamp/billy.gc @@ -26,10 +26,11 @@ billy-done billy-playing)) -(defmethod relocate ((this billy) (arg0 int)) + +(defmethod relocate ((this billy) (offset int)) (countdown (v1-0 3) - (if (nonzero? (-> this path-data v1-0)) (&+! (-> this path-data v1-0) arg0))) - (call-parent-method this arg0)) + (if (nonzero? (-> this path-data v1-0)) (&+! (-> this path-data v1-0) offset))) + (call-parent-method this offset)) (deftype billy-snack (process-drawable) ((num-rats int32)) @@ -37,6 +38,7 @@ billy-snack-eat billy-snack-idle)) + (defskelgroup *farthy-snack-sg* farthy-snack farthy-snack-lod0-jg @@ -88,6 +90,7 @@ billy-rat-eat billy-rat-salivate)) + (defun rat-about-to-eat? ((arg0 billy-rat) (arg1 billy)) (the-as symbol (and (= (-> arg0 dest-type) 2) (> (-> arg1 num-snacks) 0) (handle->process (-> arg0 snack))))) @@ -152,7 +155,7 @@ :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) (if t9-1 (t9-1))) + (call-parent-state-handler enter) (when (logtest? (nav-control-flags navcf19) (-> self nav flags)) (logclear! (-> self nav flags) (nav-control-flags navcf19)) (if (rat-about-to-eat? self (-> self billy 0)) diff --git a/goal_src/jak1/levels/swamp/swamp-rat.gc b/goal_src/jak1/levels/swamp/swamp-rat.gc index dfdbefb7a0..e0ed3f87c2 100644 --- a/goal_src/jak1/levels/swamp/swamp-rat.gc +++ b/goal_src/jak1/levels/swamp/swamp-rat.gc @@ -26,6 +26,7 @@ (:states swamp-rat-spawn)) + (defskelgroup *swamp-rat-sg* swamp-rat swamp-rat-lod0-jg @@ -183,13 +184,8 @@ swamp-rat-default-event-handler (ja :num! (seek! max f30-0))) (ja-no-eval :num! (loop!)) (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) - (let ((gp-0 (rand-vu-int-range 300 600)) - (s5-0 (current-time))) - (until (time-elapsed? s5-0 gp-0) - (ja :num-func num-func-identity :frame-num 0.0) - (ja-blend-eval) - (suspend) - (suspend))))))) + (let ((gp-0 (rand-vu-int-range 300 600))) + (suspend-for gp-0 (ja :num-func num-func-identity :frame-num 0.0) (ja-blend-eval) (suspend))))))) (defstate nav-enemy-give-up (swamp-rat) :virtual #t diff --git a/goal_src/jak1/levels/test-zone/test-zone-obs.gc b/goal_src/jak1/levels/test-zone/test-zone-obs.gc index 1228f017db..919591ac2f 100644 --- a/goal_src/jak1/levels/test-zone/test-zone-obs.gc +++ b/goal_src/jak1/levels/test-zone/test-zone-obs.gc @@ -1,6 +1,5 @@ ;;-*-Lisp-*- (in-package goal) - (deftype test-actor (process-drawable) ((root collide-shape-moving :override) (birth-time time-frame) @@ -120,4 +119,4 @@ ; ) ; ) (suspend))) - :post transform-post) + :post transform-post) \ No newline at end of file diff --git a/goal_src/jak1/levels/title/title-obs.gc b/goal_src/jak1/levels/title/title-obs.gc index aea57628e7..c9bfa92d81 100644 --- a/goal_src/jak1/levels/title/title-obs.gc +++ b/goal_src/jak1/levels/title/title-obs.gc @@ -24,9 +24,10 @@ hidden ndi)) -(defmethod relocate ((this logo) (arg0 int)) - (if (nonzero? (-> this main-joint)) (&+! (-> this main-joint) arg0)) - (the-as logo ((method-of-type process-drawable relocate) this arg0))) + +(defmethod relocate ((this logo) (offset int)) + (if (nonzero? (-> this main-joint)) (&+! (-> this main-joint) offset)) + (the-as logo ((method-of-type process-drawable relocate) this offset))) (deftype logo-slave (process-drawable) ((parent-process (pointer logo) :overlay-at parent) @@ -34,9 +35,10 @@ (:state-methods idle)) -(defmethod relocate ((this logo-slave) (arg0 int)) - (if (nonzero? (-> this main-joint)) (&+! (-> this main-joint) arg0)) - (the-as logo-slave ((method-of-type process-drawable relocate) this arg0))) + +(defmethod relocate ((this logo-slave) (offset int)) + (if (nonzero? (-> this main-joint)) (&+! (-> this main-joint) offset)) + (the-as logo-slave ((method-of-type process-drawable relocate) this offset))) (defskelgroup *logo-sg* logo @@ -324,7 +326,7 @@ (let ((gp-0 *master-mode*)) (set! *master-mode* 'game) (clear-rec *art-control*) (set! *master-mode* gp-0)) (loop (when (and (none-reserved? *art-control*) (not (paused?))) - (let ((gp-1 (current-time))) (until (time-elapsed? gp-1 (seconds 0.1)) (set! *camera-look-through-other* 2) (suspend))) + (suspend-for (seconds 0.1) (set! *camera-look-through-other* 2)) (go-virtual idle)) (set! *camera-look-through-other* 2) (suspend)))) @@ -534,7 +536,7 @@ (while (!= (file-status *art-control* "ndi-intro" 0) 'active) (set-blackout-frames (seconds 0.05)) (suspend)) - (let ((s5-1 (current-time))) (until (time-elapsed? s5-1 (seconds 0.25)) (set-blackout-frames (seconds 0.05)) (suspend))))) + (suspend-for (seconds 0.25) (set-blackout-frames (seconds 0.05))))) (label cfg-8) (let ((s5-2 (new 'stack-no-clear 'mc-slot-info))) (mc-get-slot-info 0 s5-2) @@ -560,7 +562,7 @@ (apply-settings *setting-control*) (while *progress-process* (suspend)) - (let ((gp-2 (current-time))) (until (time-elapsed? gp-2 (seconds 0.01)) (suspend))) + (suspend-for (seconds 0.01)) (goto cfg-41)))) (label cfg-41) (let ((gp-3 (entity-by-name "logo-1"))) diff --git a/goal_src/jak1/levels/training/training-obs.gc b/goal_src/jak1/levels/training/training-obs.gc index f762c7f3aa..c073fe525a 100644 --- a/goal_src/jak1/levels/training/training-obs.gc +++ b/goal_src/jak1/levels/training/training-obs.gc @@ -12,6 +12,7 @@ (deftype training-water (water-anim) ()) + (define ripple-for-training-water (new 'static 'ripple-wave-set @@ -54,9 +55,10 @@ (:state-methods idle)) -(defmethod relocate ((this training-cam) (arg0 int)) - (if (nonzero? (-> this root)) (&+! (-> this root) arg0)) - (the-as training-cam ((method-of-type process relocate) this arg0))) + +(defmethod relocate ((this training-cam) (offset int)) + (if (nonzero? (-> this root)) (&+! (-> this root) offset)) + (the-as training-cam ((method-of-type process relocate) this offset))) (defstate idle (training-cam) :virtual #t @@ -125,7 +127,7 @@ (when (not (task-complete? *game-info* (game-task training-climb))) (clear-text-seen! *game-info* (text-id training-double-jump)) (level-hint-spawn (text-id training-double-jump) "sagevb27" (the-as entity #f) *entity-pool* (game-task none)) - (let ((gp-8 (current-time))) (until (time-elapsed? gp-8 (seconds 30)) (suspend))) + (suspend-for (seconds 30)) (process-entity-status! self (entity-perm-status bit-3) #f) (go-virtual idle))))) (while (-> self child) @@ -154,6 +156,7 @@ (deftype tra-pontoon (rigid-body-platform) ((anchor-point vector :inline))) + (defmethod init-from-entity! ((this tra-pontoon) (arg0 entity-actor)) (logior! (-> this mask) (process-mask platform)) (rigid-body-platform-method-30 this) @@ -254,6 +257,7 @@ (deftype tra-iris-door (eco-door) ()) + (defskelgroup *tra-iris-door-sg* jng-iris-door jng-iris-door-lod0-jg @@ -440,6 +444,7 @@ idle (hit float vector symbol))) + (deftype scarecrow-b (process-drawable) ((root collide-shape :override) (incomming-attack-id uint64) @@ -448,6 +453,7 @@ idle (hit float vector symbol))) + (defskelgroup *scarecrow-a-sg* scarecrow-a scarecrow-a-lod0-jg diff --git a/goal_src/jak1/levels/village1/fishermans-boat.gc b/goal_src/jak1/levels/village1/fishermans-boat.gc index e1cc6515ec..384971aeb2 100644 --- a/goal_src/jak1/levels/village1/fishermans-boat.gc +++ b/goal_src/jak1/levels/village1/fishermans-boat.gc @@ -42,6 +42,7 @@ ((local-pos vector :inline) (normal vector :inline))) + (deftype vehicle-path (structure) ((point-array vector 10 :inline) (point-count int32)) @@ -52,6 +53,7 @@ (add-point! (_type_ float float float float) none) (debug-draw (_type_) symbol))) + (defmethod get-point-count ((this vehicle-path)) (-> this point-count)) @@ -215,8 +217,9 @@ (vehicle-controller-method-15 (_type_ collide-shape-moving) none) (vehicle-controller-method-16 (_type_) none))) -(defmethod relocate ((this vehicle-controller) (arg0 int)) - (if (nonzero? (-> this path)) (&+! (-> this path) arg0)) + +(defmethod relocate ((this vehicle-controller) (offset int)) + (if (nonzero? (-> this path)) (&+! (-> this path) offset)) (the-as vehicle-controller 0)) (defmethod vehicle-controller-method-12 ((this vehicle-controller) (arg0 int) (arg1 vector)) @@ -398,6 +401,7 @@ fishermans-boat-ride-to-misty fishermans-boat-ride-to-village1)) + (defskelgroup *fishermans-boat-sg* fishermans-boat fishermans-boat-lod0-jg @@ -924,21 +928,17 @@ (suspend)) (vector-z-quaternion! gp-0 (-> self root-overlay quat)) (vehicle-controller-method-10 (-> self controller) gp-0 (-> self controller throttle) s5-0) - (let ((s3-0 (current-time))) - (until (time-elapsed? s3-0 (seconds 1)) - (fishermans-boat-set-throttle-by-speed f30-0) - (suspend) - (suspend)))) + (suspend-for (seconds 1) (fishermans-boat-set-throttle-by-speed f30-0) (suspend))) (vector-z-quaternion! gp-0 (-> self root-overlay quat)) (vehicle-controller-method-10 (-> self controller) gp-0 (-> self controller throttle) s5-0) (+! s5-0 1))) (go fishermans-boat-player-control)) :post fishermans-boat-post) -(defmethod relocate ((this fishermans-boat) (arg0 int)) - (relocate (-> this controller) arg0) - (if (nonzero? (-> this propeller)) (&+! (-> this propeller) arg0)) - (call-parent-method this arg0)) +(defmethod relocate ((this fishermans-boat) (offset int)) + (relocate (-> this controller) offset) + (if (nonzero? (-> this propeller)) (&+! (-> this propeller) offset)) + (call-parent-method this offset)) (defmethod rigid-body-platform-method-30 ((this fishermans-boat)) (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum hit-by-others)))) @@ -1115,7 +1115,7 @@ (apply-settings *setting-control*) (process-spawn-function process (lambda :behavior fishermans-boat () - (let ((gp-0 (current-time))) (until (time-elapsed? gp-0 (seconds 1)) (suspend))) + (suspend-for (seconds 1)) (while (or (-> *setting-control* current ambient) (-> *setting-control* current hint) (-> *setting-control* current movie)) (suspend)) (suspend) diff --git a/goal_src/jak1/levels/village2/sunken-elevator.gc b/goal_src/jak1/levels/village2/sunken-elevator.gc index b00ea0f2a0..e6c99a6054 100644 --- a/goal_src/jak1/levels/village2/sunken-elevator.gc +++ b/goal_src/jak1/levels/village2/sunken-elevator.gc @@ -11,6 +11,7 @@ (teleport-if-below-y float) (teleport-if-above-y float))) + (defskelgroup *sunken-elevator-sg* sunken-elevator sunken-elevator-lod0-jg @@ -99,7 +100,7 @@ (gp-0 (new 'stack-no-clear 'vector))) (set! *teleport* #t) (set! (-> s5-0 quad) (-> self root trans quad)) - (let ((t9-1 (-> (find-parent-state) trans))) (if t9-1 (t9-1))) + (call-parent-state-handler trans) (vector-! gp-0 (-> self root trans) s5-0) (when (< (-> self path-pos) 0.9) (move-by-vector! (-> *target* control) gp-0) diff --git a/goal_src/jak1/levels/village2/village2-obs.gc b/goal_src/jak1/levels/village2/village2-obs.gc index b8831fea79..413a305ea9 100644 --- a/goal_src/jak1/levels/village2/village2-obs.gc +++ b/goal_src/jak1/levels/village2/village2-obs.gc @@ -10,6 +10,7 @@ (deftype village2cam (pov-camera) ((seq uint64))) + (defskelgroup *village2cam-sg* village2cam village2cam-lod0-jg @@ -76,6 +77,7 @@ pontoon-die pontoon-hidden)) + (defstate pontoon-hidden (pontoon) :enter (behavior () @@ -193,8 +195,10 @@ (deftype pontoonfive (pontoon) ()) + (deftype pontoonten (pontoon) ()) + (defskelgroup *pontoonfive-sg* pontoonfive pontoonfive-lod0-jg @@ -375,6 +379,7 @@ (:states (allpontoons-be-clone handle) allpontoons-idle)) + (defskelgroup *allpontoons-sg* allpontoons allpontoons-lod0-jg @@ -443,6 +448,7 @@ fireboulder-hover fireboulder-idle)) + (defskelgroup *fireboulder-sg* fireboulder fireboulder-lod0-jg @@ -621,6 +627,7 @@ (:states ceilingflag-idle)) + (defskelgroup *ceilingflag-sg* ceilingflag ceilingflag-geo-jg @@ -654,6 +661,7 @@ exit-chamber-dummy-idle exit-chamber-dummy-wait-to-appear)) + (defskelgroup *exit-chamber-dummy-sg* exit-chamber-dummy exit-chamber-dummy-lod0-jg @@ -723,6 +731,7 @@ ogreboss-village2-idle ogreboss-village2-throw)) + (defskelgroup *ogreboss-village2-sg* ogreboss-village2 ogreboss-village2-lod0-jg @@ -1054,12 +1063,12 @@ (until (ja-done? 0) (suspend) (ja :num! (seek! (ja-aframe 140.0 0)))) - (let ((gp-2 (current-time))) (until (time-elapsed? gp-2 (seconds 0.167)) (suspend))) + (suspend-for (seconds 0.167)) (ja-no-eval :group! ogreboss-village2-idle-ja :num! (seek! (ja-aframe 168.0 0)) :frame-num (ja-aframe 140.0 0)) (until (ja-done? 0) (suspend) (ja :num! (seek! (ja-aframe 168.0 0)))) - (let ((gp-5 (current-time))) (until (time-elapsed? gp-5 (seconds 0.167)) (suspend))) + (suspend-for (seconds 0.167)) (ja-no-eval :group! ogreboss-village2-idle-ja :num! (seek!) :frame-num (ja-aframe 168.0 0)) (until (ja-done? 0) (suspend) @@ -1116,8 +1125,10 @@ (deftype villageb-ogreboss (ogreboss-village2) ()) + (deftype villageb-water (water-anim) ()) + (define ripple-for-villageb-water (new 'static 'ripple-wave-set diff --git a/goal_src/jak1/levels/village_common/villagep-obs.gc b/goal_src/jak1/levels/village_common/villagep-obs.gc index bca52f2023..c1c14d6032 100644 --- a/goal_src/jak1/levels/village_common/villagep-obs.gc +++ b/goal_src/jak1/levels/village_common/villagep-obs.gc @@ -11,6 +11,7 @@ (deftype warpgate (process-hidden) ()) + (defstate target-warp-in (target) :event target-generic-event-handler :enter @@ -31,7 +32,7 @@ (ja-channel-set! 0) (vector-reset! (-> self control transv)) (move-to-point! (-> self control) (-> self control unknown-vector102)) - (let ((gp-0 (current-time))) (until (time-elapsed? gp-0 (seconds 1)) (suspend))) + (suspend-for (seconds 1)) (let ((gp-1 (new-stack-vector0))) (let ((f0-1 (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) 0.0 @@ -270,6 +271,7 @@ (:methods (pressable? (_type_) symbol))) + (defskelgroup *warp-gate-switch-sg* warp-gate-switch warp-gate-switch-lod0-jg @@ -484,9 +486,10 @@ (:state-methods idle)) -(defmethod relocate ((this village-cam) (arg0 int)) - (if (nonzero? (-> this root-override)) (&+! (-> this root-override) arg0)) - (the-as village-cam ((method-of-type process relocate) this arg0))) + +(defmethod relocate ((this village-cam) (offset int)) + (if (nonzero? (-> this root-override)) (&+! (-> this root-override) offset)) + (the-as village-cam ((method-of-type process relocate) this offset))) (defstate idle (village-cam) :virtual #t @@ -627,7 +630,7 @@ (let ((a0-70 (-> self entity extra perm))) (when (= (-> a0-70 user-uint8 0) 1) (remove-setting! 'allow-progress) - (let ((gp-3 (current-time))) (until (time-elapsed? gp-3 (seconds 300)) (suspend))) + (suspend-for (seconds 300)) (go-virtual idle)))) (process-entity-status! self (entity-perm-status bit-3) #f) (process-entity-status! self (entity-perm-status dead) #t) diff --git a/goal_src/jak1/pc/features/autosplit-h.gc b/goal_src/jak1/pc/features/autosplit-h.gc index 5235c324bc..6267e3f99e 100644 --- a/goal_src/jak1/pc/features/autosplit-h.gc +++ b/goal_src/jak1/pc/features/autosplit-h.gc @@ -1,9 +1,7 @@ ;;-*-Lisp-*- (in-package goal) - (require "kernel-defs.gc") - ;; LiveSplit ASL requires all settings to initalized _before_ you connect the process ;; Therefore everything has to be laid out in a predictable fashion before hand ;; So this is a lot of hard-coding, but not too bad when just copied from the debug menu code @@ -172,8 +170,10 @@ (com-rolling-moles uint8) (com-rolling-race uint8) ;; end marker just to make things look nice in a memory view - (end-marker uint8 4))) + (end-marker uint8 4))) (define-extern *autosplit-info-jak1* autosplit-info-jak1) + (define-extern update-autosplit-info-jak1 (function none)) + (define-extern update-autosplit-jak1-new-game (function none)) diff --git a/goal_src/jak1/pc/features/autosplit.gc b/goal_src/jak1/pc/features/autosplit.gc index 2e2489f420..00bdab8dc3 100644 --- a/goal_src/jak1/pc/features/autosplit.gc +++ b/goal_src/jak1/pc/features/autosplit.gc @@ -4,6 +4,8 @@ (require "pc/features/autosplit-h.gc") (define *autosplit-info-jak1* (new 'static 'autosplit-info-jak1)) +(define-extern *has-landed?* symbol) + ;; Setup markers (charp<-string (-> *autosplit-info-jak1* end-marker) "end") @@ -277,10 +279,10 @@ (if (task-closed? (game-task rolling-moles) (task-status need-reminder)) 1 0)) (set! (-> *autosplit-info-jak1* com-rolling-race) (if (task-closed? (game-task rolling-race) (task-status need-reminder)) 1 0)) - ;; end (none)) (defun update-autosplit-jak1-new-game () + (false! *has-landed?*) (set! (-> *autosplit-info-jak1* game-hash) (pc-get-unix-timestamp)) (none)) diff --git a/goal_src/jak1/pc/features/speedruns.gc b/goal_src/jak1/pc/features/speedruns.gc index 95c30d57ce..10d70fc8d8 100644 --- a/goal_src/jak1/pc/features/speedruns.gc +++ b/goal_src/jak1/pc/features/speedruns.gc @@ -6,6 +6,8 @@ (require "pc/features/autosplit-h.gc") (define *speedrun-info* (new 'static 'speedrun-info-jak1 :should-display? #t :needs-post-blackout-setup? #f)) +(define *has-landed?* #f) + (define-extern *mod-version-text* string) (define *hub1-cell-list* @@ -184,10 +186,8 @@ (set! (-> *pc-settings* ps2-actor-vis?) #t) ;; ensure FPS set to `60` (when (!= (-> *pc-settings* target-fps) 60) - (set-frame-rate! *pc-settings* 60 #t) - ) - (none) - ) + (set-frame-rate! *pc-settings* 60 #t)) + (none)) (defun start-speedrun ((category speedrun-category)) ;; randomize game id so the autosplitter knows to restart @@ -450,14 +450,20 @@ (defun speedrun-draw-settings () "Draw speedrun related settings in the bottom left corner" (when (and (-> *pc-settings* speedrunner-mode?) (not (paused?)) (-> *speedrun-info* should-display?)) + ;; check if we've landed (either we're on ground/surface/water, or about to target-hit-ground) + (when (and *target* + (or (logtest? (-> *target* control status) (cshape-moving-flags onground onsurf on-water)) + (= (-> *target* next-state name) 'target-hit-ground))) + (true! *has-landed?*)) (with-dma-buffer-add-bucket ((buf (-> (current-frame) global-buf)) (bucket-id subtitle)) - (draw-string-xy (string-format "Speedrunner Mode ~%ModBase ~S ~%Category: ~S ~%Cutscene Skips ~A" - *mod-version-text* + (draw-string-xy (string-format "Speedrunner Mode ~%ModBase ~S / ~S ~%Category: ~S ~%Cutscene Skips ~A~%Has Landed? ~A" + *pc-settings-built-sha* *mod-version-text* (enum->string speedrun-category (-> *speedrun-info* category)) - (-> *pc-settings* skip-movies?)) + (-> *pc-settings* skip-movies?) + *has-landed?*) buf 0 - (- 220 (* 8 4)) + (- 220 (* 8 5)) (font-color flat-yellow) (font-flags shadow kerning)))) (none)) diff --git a/goal_src/jak1/pc/pckernel-common.gc b/goal_src/jak1/pc/pckernel-common.gc index 7235b4ef44..ea009f30c8 100644 --- a/goal_src/jak1/pc/pckernel-common.gc +++ b/goal_src/jak1/pc/pckernel-common.gc @@ -36,14 +36,14 @@ (let ((display-mode (pc-get-display-mode))) (cond ((= display-mode 'windowed) - (set! (-> obj window-width) width) - (set! (-> obj window-height) height) - (format 0 "Setting window size to ~D x ~D~%" width height) - (pc-set-window-size! (max PC_MIN_WIDTH (-> obj window-width)) (max PC_MIN_HEIGHT (-> obj window-height)))) + (set! (-> obj window-width) width) + (set! (-> obj window-height) height) + (format 0 "Setting window size to ~D x ~D~%" width height) + (pc-set-window-size! (max PC_MIN_WIDTH (-> obj window-width)) (max PC_MIN_HEIGHT (-> obj window-height)))) (else - (format 0 "Setting borderless/fullscreen size to ~D x ~D~%" width height) - (set! (-> obj width) width) - (set! (-> obj height) height)))) + (format 0 "Setting borderless/fullscreen size to ~D x ~D~%" width height) + (set! (-> obj width) width) + (set! (-> obj height) height)))) (none)) (defmethod set-aspect! ((obj pc-settings) (aw int) (ah int)) @@ -412,30 +412,30 @@ (let ((version PC_KERNEL_VERSION)) (with-settings-scope (file) (case-str (file-stream-read-word file) - (("settings") - (set! version (the pckernel-version (file-stream-read-int file))) - (cond - ((and (= (-> version major) PC_KERNEL_VER_MAJOR) (= (-> version minor) PC_KERNEL_VER_MINOR)) - ;; minor or no difference - ) - (else - ;; major difference - (format 0 - "PC kernel version mismatch! Got ~D.~D vs ~D.~D~%" - PC_KERNEL_VER_MAJOR - PC_KERNEL_VER_MINOR - (-> version major) - (-> version minor)) - (file-stream-close file) - (return #f))) - (dosettings (file) (handle-input-settings obj file)) - ;; upgrade settings if minor changes - ;; remember to delete this when major changes to the version number are made - (when (and (= PC_KERNEL_VER_MAJOR 1) - (= PC_KERNEL_VER_MINOR 10) - (or (> 3 (-> version build)) (and (= 3 (-> version build)) (> 1 (-> version revision))))) - ;; 1.10 upgrade: turn envmap on - (set! (-> obj force-envmap?) #t)))))) + (("settings") + (set! version (the pckernel-version (file-stream-read-int file))) + (cond + ((and (= (-> version major) PC_KERNEL_VER_MAJOR) (= (-> version minor) PC_KERNEL_VER_MINOR)) + ;; minor or no difference + ) + (else + ;; major difference + (format 0 + "PC kernel version mismatch! Got ~D.~D vs ~D.~D~%" + PC_KERNEL_VER_MAJOR + PC_KERNEL_VER_MINOR + (-> version major) + (-> version minor)) + (file-stream-close file) + (return #f))) + (dosettings (file) (handle-input-settings obj file)) + ;; upgrade settings if minor changes + ;; remember to delete this when major changes to the version number are made + (when (and (= PC_KERNEL_VER_MAJOR 1) + (= PC_KERNEL_VER_MINOR 10) + (or (> 3 (-> version build)) (and (= 3 (-> version build)) (> 1 (-> version revision))))) + ;; 1.10 upgrade: turn envmap on + (set! (-> obj force-envmap?) #t)))))) (file-stream-close file)) (format 0 "pc settings file read: ~A~%" filename) ;; restore the windowed mode resolution properly @@ -446,108 +446,113 @@ (defmethod handle-input-settings ((obj pc-settings) (file file-stream)) "handle the text parsing input for the 'settings' group" (case-str *pc-temp-string* - (("fps") (set-frame-rate! obj (file-stream-read-int file) #t)) - (("window-size") - (set! (-> obj window-width) (file-stream-read-int file)) - (set! (-> obj window-height) (file-stream-read-int file))) - (("game-size") - ;; Check to see if the game-size is a valid resolution on this persons device - ;; on some machines, this has been proven to cause the black-screen issue https://github.com/open-goal/jak-project/issues/3563 - ;; Correlating with logs like: - ;; - OpenGL error 0x502 S8246 T824C: GL_INVALID_OPERATION error generated. Source and destination dimensions must be identical with the current filtering modes. - (let* ((saved-width (file-stream-read-int file)) - (saved-height (file-stream-read-int file)) - (supported-resolution? (pc-is-supported-resolution? saved-width saved-height))) - (cond - (supported-resolution? - (format 0 "[PC Settings]: Valid game-size resolution ~D x ~D~%" saved-width saved-height) - (set! (-> obj width) saved-width) - (set! (-> obj height) saved-height)) - (else - (pc-get-active-display-size (&-> obj width) (&-> obj height)) - (format 0 "[PC Settings]: Invalid game-size resolution ~D x ~D, defaulting to ~D x ~D~%" saved-width saved-height (-> obj width) (-> obj height)))))) - (("msaa") (set! (-> obj gfx-msaa) (file-stream-read-int file))) - (("aspect-state") - ;; game aspect - (set-game-setting! obj 'aspect-ratio (file-stream-read-symbol file)) - ;; aspect ratio - (set! (-> obj aspect-custom-x) (file-stream-read-int file)) - (set! (-> obj aspect-custom-y) (file-stream-read-int file)) - ;; aspect auto - (set! (-> obj aspect-ratio-auto?) (file-stream-read-symbol file)) - (unless (-> obj aspect-ratio-auto?) - (set-aspect! obj (-> obj aspect-custom-x) (-> obj aspect-custom-y)))) - ;; TODO - moved to C++, has to remain because settings parsing can't handle - ;; unexpected keys - (("display-mode") (file-stream-read-symbol file)) - ;; TODO - moved to C++, has to remain because settings parsing can't handle - ;; unexpected keys - (("monitor") (file-stream-read-int file)) - (("letterbox") (set! (-> obj letterbox?) (file-stream-read-symbol file))) - (("vsync") (set! (-> obj vsync?) (file-stream-read-symbol file))) - (("font-scale") (set! (-> obj font-scale) (file-stream-read-float file))) - (("audio-latency-ms") (set! (-> obj audio-latency-ms) (file-stream-read-int file))) - (("audio-pan-override") (set! (-> obj audio-pan-override) (file-stream-read-float file))) - (("audio-volume-override") (set! (-> obj audio-volume-override) (file-stream-read-float file))) - (("audio-channel-nb") (set! (-> obj audio-channel-nb) (file-stream-read-int file))) - (("gfx-renderer") (set! (-> obj gfx-renderer) (the-as pc-gfx-renderer (file-stream-read-int file)))) - (("gfx-resolution") (set! (-> obj gfx-resolution) (file-stream-read-float file))) - (("gfx-anisotropy") (set! (-> obj gfx-anisotropy) (file-stream-read-float file))) - (("shrub-dist-mod") (set! (-> obj shrub-dist-mod) (file-stream-read-float file))) - (("lod-dist-mod") (set! (-> obj lod-dist-mod) (file-stream-read-float file))) - (("lod-force-tfrag") (set! (-> obj lod-force-tfrag) (file-stream-read-int file))) - (("lod-force-tie") (set! (-> obj lod-force-tie) (file-stream-read-int file))) - (("lod-force-ocean") (set! (-> obj lod-force-ocean) (file-stream-read-int file))) - (("lod-force-actor") (set! (-> obj lod-force-actor) (file-stream-read-int file))) - (("game-language") (set-game-language! obj (the-as language-enum (file-stream-read-int file)))) - (("subtitle-speaker") (set! (-> obj subtitle-speaker?) (file-stream-read-symbol file))) - (("territory") (set! (-> obj territory) (file-stream-read-int file))) - (("ignore-controller-win-unfocused?") (set-ignore-controller-in-bg! obj (file-stream-read-symbol file))) - (("controller-hp-led?") (set! (-> obj controller-led-hp?) (file-stream-read-symbol file))) - (("controller-eco-led?") (set! (-> obj controller-led-eco?) (file-stream-read-symbol file))) - (("controller-heat-led?") (set! (-> obj controller-led-heat?) (file-stream-read-symbol file))) - (("stick-deadzone") (set! (-> obj stick-deadzone) (file-stream-read-float file))) - ;; TODO - remove this eventually, setting moved into json input-settings - ;; has to stay here or the settings parsing code explodes - (("keyboard-enabled?") (file-stream-read-symbol file)) - (("mouse-enabled?") (set! (-> obj mouse-enabled?) (file-stream-read-symbol file))) - (("mouse-camera?") (set! (-> obj mouse-camera?) (file-stream-read-symbol file))) - (("mouse-xsens") (set! (-> obj mouse-xsens) (file-stream-read-float file))) - (("mouse-ysens") (set! (-> obj mouse-ysens) (file-stream-read-float file))) - (("mouse-movement?") (set! (-> obj mouse-movement?) (file-stream-read-symbol file))) - (("auto-hide-cursor?") (set! (-> obj auto-hide-cursor?) (file-stream-read-symbol file))) - (("ps2-read-speed?") (set! (-> obj ps2-read-speed?) (file-stream-read-symbol file))) - (("ps2-parts?") (set! (-> obj ps2-parts?) (file-stream-read-symbol file))) - (("ps2-music?") (set! (-> obj ps2-music?) (file-stream-read-symbol file))) - (("ps2-se?") (set! (-> obj ps2-se?) (file-stream-read-symbol file))) - (("ps2-hints?") (set! (-> obj ps2-hints?) (file-stream-read-symbol file))) - (("ps2-shadow?") (set! (-> obj ps2-shadow?) (file-stream-read-symbol file))) - (("ps2-lod-dist?") (set! (-> obj ps2-lod-dist?) (file-stream-read-symbol file))) - (("force-envmap?") (set! (-> obj force-envmap?) (file-stream-read-symbol file))) - (("force-actors?") (set! (-> obj ps2-actor-vis?) (not (file-stream-read-symbol file)))) - (("music-fade?") (file-stream-read-symbol file)) ;; TODO remove - (("use-vis?") (set! (-> obj use-vis?) (file-stream-read-symbol file))) - (("hinttitles?") (set! (-> obj hinttitles?) (file-stream-read-symbol file))) - (("discord-rpc?") (set! (-> obj discord-rpc?) (file-stream-read-symbol file))) - (("speedrunner-mode?") (set! (-> obj speedrunner-mode?) (file-stream-read-symbol file))) - (("cutscene-skips?") (file-stream-read-symbol file)) ;; TODO remove - (("first-camera-h-inverted?") (set! (-> obj first-camera-h-inverted?) (file-stream-read-symbol file))) - (("first-camera-v-inverted?") (set! (-> obj first-camera-v-inverted?) (file-stream-read-symbol file))) - (("third-camera-h-inverted?") (set! (-> obj third-camera-h-inverted?) (file-stream-read-symbol file))) - (("third-camera-v-inverted?") (set! (-> obj third-camera-v-inverted?) (file-stream-read-symbol file))) - (("music-fadein?") (set! (-> obj music-fadein?) (file-stream-read-symbol file))) - (("music-fadeout?") (set! (-> obj music-fadeout?) (file-stream-read-symbol file))) - (("controller-led-brightness") (set! (-> obj controller-led-brightness) (file-stream-read-float file))) - (("controller-led-min-brightness") (set! (-> obj controller-led-min-brightness) (file-stream-read-float file))) - (("controller-led-max-brightness") (set! (-> obj controller-led-max-brightness) (file-stream-read-float file))) - (("memcard-volume-sfx") (set! (-> obj memcard-volume-sfx) (file-stream-read-float file))) - (("memcard-volume-music") (set! (-> obj memcard-volume-music) (file-stream-read-float file))) - (("memcard-volume-dialog") (set! (-> obj memcard-volume-dialog) (file-stream-read-float file))) - (("memcard-vibration?") (set! (-> obj memcard-vibration?) (file-stream-read-symbol file))) - ;; debug - (("debug-font-scale") (set! (-> obj debug-font-scale) (file-stream-read-float file))) - (("debug-font-scale-auto?") (set! (-> obj debug-font-scale-auto?) (file-stream-read-symbol file))) - (("panic") (when (file-stream-read-symbol file) (reset obj #t) (return #f)))) + (("fps") (set-frame-rate! obj (file-stream-read-int file) #t)) + (("window-size") + (set! (-> obj window-width) (file-stream-read-int file)) + (set! (-> obj window-height) (file-stream-read-int file))) + (("game-size") + ;; Check to see if the game-size is a valid resolution on this persons device + ;; on some machines, this has been proven to cause the black-screen issue https://github.com/open-goal/jak-project/issues/3563 + ;; Correlating with logs like: + ;; - OpenGL error 0x502 S8246 T824C: GL_INVALID_OPERATION error generated. Source and destination dimensions must be identical with the current filtering modes. + (let* ((saved-width (file-stream-read-int file)) + (saved-height (file-stream-read-int file)) + (supported-resolution? (pc-is-supported-resolution? saved-width saved-height))) + (cond + (supported-resolution? + (format 0 "[PC Settings]: Valid game-size resolution ~D x ~D~%" saved-width saved-height) + (set! (-> obj width) saved-width) + (set! (-> obj height) saved-height)) + (else + (pc-get-active-display-size (&-> obj width) (&-> obj height)) + (format 0 + "[PC Settings]: Invalid game-size resolution ~D x ~D, defaulting to ~D x ~D~%" + saved-width + saved-height + (-> obj width) + (-> obj height)))))) + (("msaa") (set! (-> obj gfx-msaa) (file-stream-read-int file))) + (("aspect-state") + ;; game aspect + (set-game-setting! obj 'aspect-ratio (file-stream-read-symbol file)) + ;; aspect ratio + (set! (-> obj aspect-custom-x) (file-stream-read-int file)) + (set! (-> obj aspect-custom-y) (file-stream-read-int file)) + ;; aspect auto + (set! (-> obj aspect-ratio-auto?) (file-stream-read-symbol file)) + (unless (-> obj aspect-ratio-auto?) + (set-aspect! obj (-> obj aspect-custom-x) (-> obj aspect-custom-y)))) + ;; TODO - moved to C++, has to remain because settings parsing can't handle + ;; unexpected keys + (("display-mode") (file-stream-read-symbol file)) + ;; TODO - moved to C++, has to remain because settings parsing can't handle + ;; unexpected keys + (("monitor") (file-stream-read-int file)) + (("letterbox") (set! (-> obj letterbox?) (file-stream-read-symbol file))) + (("vsync") (set! (-> obj vsync?) (file-stream-read-symbol file))) + (("font-scale") (set! (-> obj font-scale) (file-stream-read-float file))) + (("audio-latency-ms") (set! (-> obj audio-latency-ms) (file-stream-read-int file))) + (("audio-pan-override") (set! (-> obj audio-pan-override) (file-stream-read-float file))) + (("audio-volume-override") (set! (-> obj audio-volume-override) (file-stream-read-float file))) + (("audio-channel-nb") (set! (-> obj audio-channel-nb) (file-stream-read-int file))) + (("gfx-renderer") (set! (-> obj gfx-renderer) (the-as pc-gfx-renderer (file-stream-read-int file)))) + (("gfx-resolution") (set! (-> obj gfx-resolution) (file-stream-read-float file))) + (("gfx-anisotropy") (set! (-> obj gfx-anisotropy) (file-stream-read-float file))) + (("shrub-dist-mod") (set! (-> obj shrub-dist-mod) (file-stream-read-float file))) + (("lod-dist-mod") (set! (-> obj lod-dist-mod) (file-stream-read-float file))) + (("lod-force-tfrag") (set! (-> obj lod-force-tfrag) (file-stream-read-int file))) + (("lod-force-tie") (set! (-> obj lod-force-tie) (file-stream-read-int file))) + (("lod-force-ocean") (set! (-> obj lod-force-ocean) (file-stream-read-int file))) + (("lod-force-actor") (set! (-> obj lod-force-actor) (file-stream-read-int file))) + (("game-language") (set-game-language! obj (the-as language-enum (file-stream-read-int file)))) + (("subtitle-speaker") (set! (-> obj subtitle-speaker?) (file-stream-read-symbol file))) + (("territory") (set! (-> obj territory) (file-stream-read-int file))) + (("ignore-controller-win-unfocused?") (set-ignore-controller-in-bg! obj (file-stream-read-symbol file))) + (("controller-hp-led?") (set! (-> obj controller-led-hp?) (file-stream-read-symbol file))) + (("controller-eco-led?") (set! (-> obj controller-led-eco?) (file-stream-read-symbol file))) + (("controller-heat-led?") (set! (-> obj controller-led-heat?) (file-stream-read-symbol file))) + (("stick-deadzone") (set! (-> obj stick-deadzone) (file-stream-read-float file))) + ;; TODO - remove this eventually, setting moved into json input-settings + ;; has to stay here or the settings parsing code explodes + (("keyboard-enabled?") (file-stream-read-symbol file)) + (("mouse-enabled?") (set! (-> obj mouse-enabled?) (file-stream-read-symbol file))) + (("mouse-camera?") (set! (-> obj mouse-camera?) (file-stream-read-symbol file))) + (("mouse-xsens") (set! (-> obj mouse-xsens) (file-stream-read-float file))) + (("mouse-ysens") (set! (-> obj mouse-ysens) (file-stream-read-float file))) + (("mouse-movement?") (set! (-> obj mouse-movement?) (file-stream-read-symbol file))) + (("auto-hide-cursor?") (set! (-> obj auto-hide-cursor?) (file-stream-read-symbol file))) + (("ps2-read-speed?") (set! (-> obj ps2-read-speed?) (file-stream-read-symbol file))) + (("ps2-parts?") (set! (-> obj ps2-parts?) (file-stream-read-symbol file))) + (("ps2-music?") (set! (-> obj ps2-music?) (file-stream-read-symbol file))) + (("ps2-se?") (set! (-> obj ps2-se?) (file-stream-read-symbol file))) + (("ps2-hints?") (set! (-> obj ps2-hints?) (file-stream-read-symbol file))) + (("ps2-shadow?") (set! (-> obj ps2-shadow?) (file-stream-read-symbol file))) + (("ps2-lod-dist?") (set! (-> obj ps2-lod-dist?) (file-stream-read-symbol file))) + (("force-envmap?") (set! (-> obj force-envmap?) (file-stream-read-symbol file))) + (("force-actors?") (set! (-> obj ps2-actor-vis?) (not (file-stream-read-symbol file)))) + (("music-fade?") (file-stream-read-symbol file)) ;; TODO remove + (("use-vis?") (set! (-> obj use-vis?) (file-stream-read-symbol file))) + (("hinttitles?") (set! (-> obj hinttitles?) (file-stream-read-symbol file))) + (("discord-rpc?") (set! (-> obj discord-rpc?) (file-stream-read-symbol file))) + (("speedrunner-mode?") (set! (-> obj speedrunner-mode?) (file-stream-read-symbol file))) + (("cutscene-skips?") (file-stream-read-symbol file)) ;; TODO remove + (("first-camera-h-inverted?") (set! (-> obj first-camera-h-inverted?) (file-stream-read-symbol file))) + (("first-camera-v-inverted?") (set! (-> obj first-camera-v-inverted?) (file-stream-read-symbol file))) + (("third-camera-h-inverted?") (set! (-> obj third-camera-h-inverted?) (file-stream-read-symbol file))) + (("third-camera-v-inverted?") (set! (-> obj third-camera-v-inverted?) (file-stream-read-symbol file))) + (("music-fadein?") (set! (-> obj music-fadein?) (file-stream-read-symbol file))) + (("music-fadeout?") (set! (-> obj music-fadeout?) (file-stream-read-symbol file))) + (("controller-led-brightness") (set! (-> obj controller-led-brightness) (file-stream-read-float file))) + (("controller-led-min-brightness") (set! (-> obj controller-led-min-brightness) (file-stream-read-float file))) + (("controller-led-max-brightness") (set! (-> obj controller-led-max-brightness) (file-stream-read-float file))) + (("memcard-volume-sfx") (set! (-> obj memcard-volume-sfx) (file-stream-read-float file))) + (("memcard-volume-music") (set! (-> obj memcard-volume-music) (file-stream-read-float file))) + (("memcard-volume-dialog") (set! (-> obj memcard-volume-dialog) (file-stream-read-float file))) + (("memcard-vibration?") (set! (-> obj memcard-vibration?) (file-stream-read-symbol file))) + ;; debug + (("debug-font-scale") (set! (-> obj debug-font-scale) (file-stream-read-float file))) + (("debug-font-scale-auto?") (set! (-> obj debug-font-scale-auto?) (file-stream-read-symbol file))) + (("panic") (when (file-stream-read-symbol file) (reset obj #t) (return #f)))) 0) (defmethod handle-output-settings ((obj pc-settings) (file file-stream)) @@ -644,10 +649,10 @@ (format 0 "[PC] PC Settings found at '~S' but could not be loaded, using defaults!~%" *pc-temp-string-1*) (reset obj #t))) (else - (format 0 "[PC] PC Settings not found at '~S'...initializing with defaults!~%" *pc-temp-string-1*) - (reset obj #t) - ;; save the file so users aren't confused, and so we can debug what the game is producing for them - (commit-to-file obj))) + (format 0 "[PC] PC Settings not found at '~S'...initializing with defaults!~%" *pc-temp-string-1*) + (reset obj #t) + ;; save the file so users aren't confused, and so we can debug what the game is producing for them + (commit-to-file obj))) 0) (defmethod initialize ((obj pc-settings)) diff --git a/goal_src/jak1/pc/pckernel-h.gc b/goal_src/jak1/pc/pckernel-h.gc index 176d94a208..2b449b57ab 100644 --- a/goal_src/jak1/pc/pckernel-h.gc +++ b/goal_src/jak1/pc/pckernel-h.gc @@ -198,8 +198,7 @@ (memcard-volume-sfx float) (memcard-volume-music float) (memcard-volume-dialog float) - (memcard-vibration? symbol) - ) + (memcard-vibration? symbol)) (:methods (new (symbol type) _type_) (initialize (_type_) _type_) @@ -326,12 +325,17 @@ (let* ((saved-width (-> obj width)) (saved-height (-> obj height)) (supported-resolution? (pc-is-supported-resolution? saved-width saved-height))) - (cond - (supported-resolution? - (format 0 "[PC Settings]: Valid default game-size resolution set ~D x ~D~%" saved-width saved-height)) - (else - (pc-get-active-display-size (&-> obj width) (&-> obj height)) - (format 0 "[PC Settings]: Invalid game-size resolution ~D x ~D, defaulting to ~D x ~D~%" saved-width saved-height (-> obj width) (-> obj height))))) + (cond + (supported-resolution? + (format 0 "[PC Settings]: Valid default game-size resolution set ~D x ~D~%" saved-width saved-height)) + (else + (pc-get-active-display-size (&-> obj width) (&-> obj height)) + (format 0 + "[PC Settings]: Invalid game-size resolution ~D x ~D, defaulting to ~D x ~D~%" + saved-width + saved-height + (-> obj width) + (-> obj height))))) (format 0 "[PC Settings]: fullscreen resolution defaulted to ~D x ~D~%" (-> obj width) (-> obj height)) (set! (-> obj gfx-msaa) PC_DEFAULT_MSAA) ;; default msaa 0) @@ -422,8 +426,7 @@ `(debug-font-scale-factor *pc-settings*)) (defmacro fullscreen? () - `(or (= (pc-get-display-mode) 'fullscreen) - (= (pc-get-display-mode) 'borderless))) + `(or (= (pc-get-display-mode) 'fullscreen) (= (pc-get-display-mode) 'borderless))) (defun bcd->dec ((bcd uint)) "Convert a number encoded in BCD to its decimal equivalent" diff --git a/goal_src/jak1/pc/pckernel-impl.gc b/goal_src/jak1/pc/pckernel-impl.gc index d913cd9417..7f098e6561 100644 --- a/goal_src/jak1/pc/pckernel-impl.gc +++ b/goal_src/jak1/pc/pckernel-impl.gc @@ -77,8 +77,7 @@ (extra-hud? symbol) ;; extra hud elements. (secrets pc-game-secrets :inline) ;; hidden goodies and additional secrets! (scenes-seen uint8 PC_SPOOL_LOG_LENGTH) ;; cutscenes that have been seen, by spool-anim (maybe use 8-char name or bits instead?) - (memcard-play-hints? symbol) - )) + (memcard-play-hints? symbol))) (define *pc-settings* (the pc-settings-jak1 #f)) diff --git a/goal_src/jak1/pc/pckernel.gc b/goal_src/jak1/pc/pckernel.gc index 9b0fbae175..eb8e2d66eb 100644 --- a/goal_src/jak1/pc/pckernel.gc +++ b/goal_src/jak1/pc/pckernel.gc @@ -139,8 +139,7 @@ (when (zero? (-> date stat)) (set-time-of-day (+ (the float (bcd->dec (-> date hour))) (/ (the float (bcd->dec (-> date minute))) 60)))))) (pc-set-gfx-hack (pc-gfx-hack no-tex) (logtest? (-> obj cheats) (pc-cheats no-tex))) - (if (or (pc-cheats? (-> obj cheats) mirror) - *PC-MIRROR-MODE-SET*) + (if (or (pc-cheats? (-> obj cheats) mirror) *PC-MIRROR-MODE-SET*) (sound-set-mirror-mode (sound-mirror-mode mirrored)) (sound-set-mirror-mode (sound-mirror-mode normal))) ;; run cheats end!!! @@ -437,36 +436,36 @@ "handle the text parsing input for the 'settings' group" ((method-of-type pc-settings handle-input-settings) obj file) (case-str *pc-temp-string* - (("money-starburst?") (set! (-> obj money-starburst?) (file-stream-read-symbol file))) - (("extra-hud?") (set! (-> obj extra-hud?) (file-stream-read-symbol file))) - (("skip-movies?") (set! (-> obj skip-movies?) (file-stream-read-symbol file))) - (("subtitles?") (set! (-> obj subtitles?) (file-stream-read-symbol file))) - (("subtitle-language") (set! (-> obj subtitle-language) (the-as pc-language (file-stream-read-int file)))) - (("text-language") (set! (-> obj text-language) (the-as pc-language (file-stream-read-int file)))) - (("scenes-seen") (dotimes (i PC_SPOOL_LOG_LENGTH) (set! (-> obj scenes-seen i) (file-stream-read-int file)))) - (("memcard-play-hints?") (set! (-> obj memcard-play-hints?) (file-stream-read-symbol file))) - (("secrets") - (dosettings (file) - (case-str *pc-temp-string* - (("hard-rats?") (set! (-> obj secrets hard-rats?) (file-stream-read-symbol file))) - (("hero-mode?") (set! (-> obj secrets hero-mode?) (file-stream-read-symbol file))) - (("hud-map?") (set! (-> obj secrets hud-map?) (file-stream-read-symbol file))) - (("hud-counters?") (set! (-> obj secrets hud-counters?) (file-stream-read-symbol file))) - (("hud-watch?") (set! (-> obj secrets hud-watch?) (file-stream-read-symbol file))) - (("watch-12hr?") (set! (-> obj secrets watch-12hr?) (file-stream-read-symbol file))) - (("art") (set! (-> obj secrets art) (the-as pc-jak1-concept-art (file-stream-read-int file)))) - (("hard-fish-hiscore") (set! (-> obj secrets hard-fish-hiscore) (file-stream-read-int file))) - (("hard-rats-hiscore") (set! (-> obj secrets hard-rats-hiscore) (file-stream-read-int file))) - (("hard-rats-hiwave") (set! (-> obj secrets hard-rats-hiwave) (file-stream-read-int file))) - (("cheats") - (set! (-> obj cheats-known) (the pc-cheats (file-stream-read-int file))) - (set! (-> obj cheats) (logand (-> obj cheats-known) (file-stream-read-int file)))) - (("music") - (dotimes (i PC_MUSIC_LOG_LENGTH) - (when (!= #x29 (file-stream-get-next-char-ret file)) - (with-settings-scope (file) - (set! (-> obj secrets music i name) (file-stream-read-symbol file)) - (set! (-> obj secrets music i flava-mask) (file-stream-read-int file)))))))))) + (("money-starburst?") (set! (-> obj money-starburst?) (file-stream-read-symbol file))) + (("extra-hud?") (set! (-> obj extra-hud?) (file-stream-read-symbol file))) + (("skip-movies?") (set! (-> obj skip-movies?) (file-stream-read-symbol file))) + (("subtitles?") (set! (-> obj subtitles?) (file-stream-read-symbol file))) + (("subtitle-language") (set! (-> obj subtitle-language) (the-as pc-language (file-stream-read-int file)))) + (("text-language") (set! (-> obj text-language) (the-as pc-language (file-stream-read-int file)))) + (("scenes-seen") (dotimes (i PC_SPOOL_LOG_LENGTH) (set! (-> obj scenes-seen i) (file-stream-read-int file)))) + (("memcard-play-hints?") (set! (-> obj memcard-play-hints?) (file-stream-read-symbol file))) + (("secrets") + (dosettings (file) + (case-str *pc-temp-string* + (("hard-rats?") (set! (-> obj secrets hard-rats?) (file-stream-read-symbol file))) + (("hero-mode?") (set! (-> obj secrets hero-mode?) (file-stream-read-symbol file))) + (("hud-map?") (set! (-> obj secrets hud-map?) (file-stream-read-symbol file))) + (("hud-counters?") (set! (-> obj secrets hud-counters?) (file-stream-read-symbol file))) + (("hud-watch?") (set! (-> obj secrets hud-watch?) (file-stream-read-symbol file))) + (("watch-12hr?") (set! (-> obj secrets watch-12hr?) (file-stream-read-symbol file))) + (("art") (set! (-> obj secrets art) (the-as pc-jak1-concept-art (file-stream-read-int file)))) + (("hard-fish-hiscore") (set! (-> obj secrets hard-fish-hiscore) (file-stream-read-int file))) + (("hard-rats-hiscore") (set! (-> obj secrets hard-rats-hiscore) (file-stream-read-int file))) + (("hard-rats-hiwave") (set! (-> obj secrets hard-rats-hiwave) (file-stream-read-int file))) + (("cheats") + (set! (-> obj cheats-known) (the pc-cheats (file-stream-read-int file))) + (set! (-> obj cheats) (logand (-> obj cheats-known) (file-stream-read-int file)))) + (("music") + (dotimes (i PC_MUSIC_LOG_LENGTH) + (when (!= #x29 (file-stream-get-next-char-ret file)) + (with-settings-scope (file) + (set! (-> obj secrets music i name) (file-stream-read-symbol file)) + (set! (-> obj secrets music i flava-mask) (file-stream-read-int file)))))))))) 0) (defmethod handle-output-settings ((obj pc-settings-jak1) (file file-stream)) diff --git a/goal_src/jak1/pc/progress-pc.gc b/goal_src/jak1/pc/progress-pc.gc index df48efbbfc..1ed36ec075 100644 --- a/goal_src/jak1/pc/progress-pc.gc +++ b/goal_src/jak1/pc/progress-pc.gc @@ -225,10 +225,14 @@ :name (text-id input-options) :scale #t :param3 (game-option-menu input-options)) - (new 'static 'game-option :option-type (game-option-type on-off) :name (text-id play-hints) :scale #t - :on-confirm - (lambda () - (set! (-> *setting-control* default play-hints) (-> *pc-settings* memcard-play-hints?)))) + (new 'static + 'game-option + :option-type (game-option-type on-off) + :name (text-id play-hints) + :scale #t + :on-confirm + (lambda () + (set! (-> *setting-control* default play-hints) (-> *pc-settings* memcard-play-hints?)))) (new 'static 'game-option :option-type (game-option-type on-off) :name (text-id subtitles) :scale #t) (new 'static 'game-option :option-type (game-option-type on-off) :name (text-id hinttitles) :scale #t) (new 'static 'game-option :option-type (game-option-type language) :name (text-id language) :scale #t) @@ -649,8 +653,12 @@ (new 'static 'game-option :option-type (game-option-type lod-fg) :name (text-id lod-fg) :scale #t) (new 'static 'game-option :option-type (game-option-type on-off) :name (text-id ps2-parts) :scale #t) (new 'static 'game-option :option-type (game-option-type on-off) :name (text-id force-envmap) :scale #t) - (new 'static 'game-option :option-type (game-option-type on-off) :name (text-id force-actors) :scale #t - :option-disabled-func + (new 'static + 'game-option + :option-type (game-option-type on-off) + :name (text-id force-actors) + :scale #t + :option-disabled-func (lambda () (-> *pc-settings* speedrunner-mode?))) (new 'static 'game-option :option-type (game-option-type button) :name (text-id back) :scale #t))) @@ -1171,7 +1179,7 @@ (let ((window-width 0) (window-height 0) (window-aspect-ratio 0.0) - (num-resolutions (pc-get-num-resolutions)) + (num-resolutions (pc-get-num-resolutions (= (pc-get-display-mode) 'windowed))) (num-resolutions-added 0)) (when (> num-resolutions 0) (pc-get-window-size (& window-width) (& window-height)) @@ -1180,7 +1188,7 @@ (let ((res-width 0) (res-height 0) (res-aspect-ratio 0.0)) - (pc-get-resolution i (& res-width) (& res-height)) + (pc-get-resolution i (= (pc-get-display-mode) 'windowed) (& res-width) (& res-height)) (set! res-aspect-ratio (/ (the float res-width) (the float res-height))) ;; Ignore those that aren't relevant to the current window's aspect ratio ;; we only do this when we aren't in windowed mode, because in windowed mode @@ -1420,362 +1428,378 @@ (defun pc-sprite-adjust-left ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 20.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 4.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) -6.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) -10.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) -14.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) -16.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) -25.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) -26.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) -37.0) - (else - (+ 121.37227965381875 - (* -145.13874571806738 aspect-ratio) - (* 48.695824268929236 aspect-ratio aspect-ratio) - (* -5.737940185600177 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 20.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 4.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) -6.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) -10.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) -14.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) -16.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) -25.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) -26.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) -37.0) + (else + (+ 121.37227965381875 + (* -145.13874571806738 aspect-ratio) + (* 48.695824268929236 aspect-ratio aspect-ratio) + (* -5.737940185600177 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-right ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) -33.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) -6.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 12.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 18.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 26.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 29.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 45.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 46.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 65.0) - (else - (+ -205.4294994422315 - (* 245.07283711809043 aspect-ratio) - (* -81.04347133064093 aspect-ratio aspect-ratio) - (* 9.423126530695802 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) -33.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) -6.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 12.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 18.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 26.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 29.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 45.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 46.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 65.0) + (else + (+ -205.4294994422315 + (* 245.07283711809043 aspect-ratio) + (* -81.04347133064093 aspect-ratio aspect-ratio) + (* 9.423126530695802 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-cross-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) -20.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) -5.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 5.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 8.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 15.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 17.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 30.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 30.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 45.0) - (else - (+ -98.75041386103345 - (* 104.4004528706783 aspect-ratio) - (* -27.27525895954647 aspect-ratio aspect-ratio) - (* 2.6112419651912617 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) -20.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) -5.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 5.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 8.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 15.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 17.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 30.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 30.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 45.0) + (else + (+ -98.75041386103345 + (* 104.4004528706783 aspect-ratio) + (* -27.27525895954647 aspect-ratio aspect-ratio) + (* 2.6112419651912617 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-cross-y ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) -20.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 5.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 10.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 10.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 20.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 20.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 25.0) - (else - (+ -92.55990871923132 - (* 104.71302956908977 aspect-ratio) - (* -32.46993312399963 aspect-ratio aspect-ratio) - (* 3.4672700107735115 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) -20.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 5.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 10.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 10.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 20.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 20.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 25.0) + (else + (+ -92.55990871923132 + (* 104.71302956908977 aspect-ratio) + (* -32.46993312399963 aspect-ratio aspect-ratio) + (* 3.4672700107735115 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-square-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) -5.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 5.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 5.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 8.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 8.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 15.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 15.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 17.0) - (else - (+ -22.034620779370684 - (* 15.66980500404166 aspect-ratio) - (* 2.6395010789749374 aspect-ratio aspect-ratio) - (* -1.1122480459486384 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) -5.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 5.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 5.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 8.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 8.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 15.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 15.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 17.0) + (else + (+ -22.034620779370684 + (* 15.66980500404166 aspect-ratio) + (* 2.6395010789749374 aspect-ratio aspect-ratio) + (* -1.1122480459486384 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-square-y ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) -10.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 10.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 10.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 15.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 15.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 15.0) - (else - (+ -35.887413062108386 - (* 28.768844269882614 aspect-ratio) - (* -0.854904339304392 aspect-ratio aspect-ratio) - (* -0.9020647898186882 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) -10.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 10.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 10.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 15.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 15.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 15.0) + (else + (+ -35.887413062108386 + (* 28.768844269882614 aspect-ratio) + (* -0.854904339304392 aspect-ratio aspect-ratio) + (* -0.9020647898186882 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-triangle-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 2.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 2.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 3.0) - (else - (+ 9.074933988821043 - (* -16.012653345486786 aspect-ratio) - (* 8.413647131791468 aspect-ratio aspect-ratio) - (* -1.2341491172835792 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 2.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 2.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 3.0) + (else + (+ 9.074933988821043 + (* -16.012653345486786 aspect-ratio) + (* 8.413647131791468 aspect-ratio aspect-ratio) + (* -1.2341491172835792 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-triangle-y ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 5.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 5.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 5.0) - (else - (+ 24.319264777517994 - (* -43.26989970602368 aspect-ratio) - (* 23.07604741978599 aspect-ratio aspect-ratio) - (* -3.494974989657488 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 5.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 5.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 5.0) + (else + (+ 24.319264777517994 + (* -43.26989970602368 aspect-ratio) + (* 23.07604741978599 aspect-ratio aspect-ratio) + (* -3.494974989657488 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-circle-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 2.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 2.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 5.0) - (else - (+ 7.769390144448719 - (* -13.422040271641388 aspect-ratio) - (* 6.780103459545601 aspect-ratio aspect-ratio) - (* -0.9064673601247457 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 2.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 2.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 5.0) + (else + (+ 7.769390144448719 + (* -13.422040271641388 aspect-ratio) + (* 6.780103459545601 aspect-ratio aspect-ratio) + (* -0.9064673601247457 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-circle-y ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) -7.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) -7.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) -10.0) - (else - (+ -32.088654921966715 - (* 56.69193997766507 aspect-ratio) - (* -29.856150879331594 aspect-ratio aspect-ratio) - (* 4.401442349782235 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) -7.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) -7.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) -10.0) + (else + (+ -32.088654921966715 + (* 56.69193997766507 aspect-ratio) + (* -29.856150879331594 aspect-ratio aspect-ratio) + (* 4.401442349782235 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-percent-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 12.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 12.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 15.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 15.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 18.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 18.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 25.0) - (else - (+ -46.209527361482614 - (* 59.19334582683605 aspect-ratio) - (* -17.978708435875035 aspect-ratio aspect-ratio) - (* 1.9546083242648873 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 12.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 12.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 15.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 15.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 18.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 18.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 25.0) + (else + (+ -46.209527361482614 + (* 59.19334582683605 aspect-ratio) + (* -17.978708435875035 aspect-ratio aspect-ratio) + (* 1.9546083242648873 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-autosave-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 10.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 10.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 10.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 10.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 15.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 15.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 18.0) - (else - (+ -25.454818080453748 - (* 28.58764000115764 aspect-ratio) - (* -5.122397663089315 aspect-ratio aspect-ratio) - (* 0.1450488213340339 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 10.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 10.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 10.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 10.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 15.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 15.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 18.0) + (else + (+ -25.454818080453748 + (* 28.58764000115764 aspect-ratio) + (* -5.122397663089315 aspect-ratio aspect-ratio) + (* 0.1450488213340339 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-orb-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 5.0) - (else - (+ -3.26385961093079 - (* 6.476532684613467 aspect-ratio) - (* -4.083859180614655 aspect-ratio aspect-ratio) - (* 0.819204392897082 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 5.0) + (else + (+ -3.26385961093079 + (* 6.476532684613467 aspect-ratio) + (* -4.083859180614655 aspect-ratio aspect-ratio) + (* 0.819204392897082 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-orb-glow-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 4.0) - (else - (+ -2.6110876887446324 - (* 5.181226147690773 aspect-ratio) - (* -3.267087344491723 aspect-ratio aspect-ratio) - (* 0.6553635143176653 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 4.0) + (else + (+ -2.6110876887446324 + (* 5.181226147690773 aspect-ratio) + (* -3.267087344491723 aspect-ratio aspect-ratio) + (* 0.6553635143176653 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-orb-text-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 10.0) - (else - (+ -6.52771922186158 - (* 12.953065369226934 aspect-ratio) - (* -8.16771836122931 aspect-ratio aspect-ratio) - (* 1.638408785794164 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 10.0) + (else + (+ -6.52771922186158 + (* 12.953065369226934 aspect-ratio) + (* -8.16771836122931 aspect-ratio aspect-ratio) + (* 1.638408785794164 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-cell-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) -10.0) - (else - (+ 6.52771922186158 - (* -12.953065369226934 aspect-ratio) - (* 8.16771836122931 aspect-ratio aspect-ratio) - (* -1.638408785794164 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) -10.0) + (else + (+ 6.52771922186158 + (* -12.953065369226934 aspect-ratio) + (* 8.16771836122931 aspect-ratio aspect-ratio) + (* -1.638408785794164 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-cell-text-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 2.0) - (else - (+ -1.3055438443723162 - (* 2.5906130738453865 aspect-ratio) - (* -1.6335436722458616 aspect-ratio aspect-ratio) - (* 0.32768175715883263 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 2.0) + (else + (+ -1.3055438443723162 + (* 2.5906130738453865 aspect-ratio) + (* -1.6335436722458616 aspect-ratio aspect-ratio) + (* 0.32768175715883263 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-buzzer-text-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) -5.0) - (else - (+ 3.26385961093079 - (* -6.476532684613467 aspect-ratio) - (* 4.083859180614655 aspect-ratio aspect-ratio) - (* -0.819204392897082 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) -5.0) + (else + (+ 3.26385961093079 + (* -6.476532684613467 aspect-ratio) + (* 4.083859180614655 aspect-ratio aspect-ratio) + (* -0.819204392897082 aspect-ratio aspect-ratio aspect-ratio))))) (defun pc-sprite-adjust-options-text-x ((aspect-ratio float)) (cond - ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) - ((fequal-epsilon? aspect-ratio 3.56 0.01) 3.0) - (else - (+ -1.9583157665584714 - (* 3.885919610768078 aspect-ratio) - (* -2.450315508368792 aspect-ratio aspect-ratio) - (* 0.491522635738249 aspect-ratio aspect-ratio aspect-ratio))))) + ((fequal-epsilon? aspect-ratio 1.0 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.25 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.5 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.6 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.78 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 1.85 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.33 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 2.35 0.01) 0.0) + ((fequal-epsilon? aspect-ratio 3.56 0.01) 3.0) + (else + (+ -1.9583157665584714 + (* 3.885919610768078 aspect-ratio) + (* -2.450315508368792 aspect-ratio aspect-ratio) + (* 0.491522635738249 aspect-ratio aspect-ratio aspect-ratio))))) (define *PC-CROSS-X-ADJUST* 0.0) + (define *PC-CROSS-Y-ADJUST* 0.0) + (define *PC-SQUARE-X-ADJUST* 0.0) + (define *PC-SQUARE-Y-ADJUST* 0.0) + (define *PC-TRIANGLE-X-ADJUST* 0.0) + (define *PC-TRIANGLE-Y-ADJUST* 0.0) + (define *PC-CIRCLE-X-ADJUST* 0.0) + (define *PC-CIRCLE-Y-ADJUST* 0.0) + (define *PC-PERCENT-X-ADJUST* 0.0) + (define *PC-AUTOSAVE-X-ADJUST* 0.0) + (define *PC-ORB-X-ADJUST* 0.0) + (define *PC-ORB-GLOW-X-ADJUST* 0.0) + (define *PC-ORB-TEXT-X-ADJUST* 0.0) + (define *PC-CELL-X-ADJUST* 0.0) + (define *PC-CELL-TEXT-X-ADJUST* 0.0) + (define *PC-BUZZER-TEXT-X-ADJUST* 0.0) + (define *PC-OPTIONS-TEXT-X-ADJUST* 0.0) (defmethod adjust-ratios ((this progress) (aspect symbol) (video-mode symbol)) @@ -1878,7 +1902,11 @@ (let ((s4-2 (new 'stack 'font-context *font-default-matrix* - (the int (+ *PC-OPTIONS-TEXT-X-ADJUST* (- 423.0 (the float (/ (-> this left-x-offset) 2))) f30-0 (the float (adjust-pos s5-0 150)))) + (the int + (+ *PC-OPTIONS-TEXT-X-ADJUST* + (- 423.0 (the float (/ (-> this left-x-offset) 2))) + f30-0 + (the float (adjust-pos s5-0 150)))) 131 0.0 (font-color default) @@ -1893,7 +1921,9 @@ (let ((v1-36 s4-2)) (set! (-> v1-36 scale) 1.3)) (let ((a0-31 s4-2)) (set! (-> a0-31 color) (font-color progress-percent))) (set! (-> s4-2 origin x) - (+ *PC-PERCENT-X-ADJUST* (- 435.0 (the float (if (< (-> *progress-process* 0 completion-percentage) 10.0) 93 80))) f30-0)) + (+ *PC-PERCENT-X-ADJUST* + (- 435.0 (the float (if (< (-> *progress-process* 0 completion-percentage) 10.0) 93 80))) + f30-0)) (set! (-> s4-2 origin y) 180.0) (set! (-> s4-2 flags) (font-flags shadow kerning middle middle-vert large)) (let ((s3-3 print-game-text)) @@ -1947,13 +1977,15 @@ (let* ((f28-2 (* 0.00024414062 (the float (-> *progress-process* 0 in-out-position)))) (f30-1 (* 300.0 f28-2))) (set! (-> this particles 18 init-pos x) - (+ *PC-ORB-GLOW-X-ADJUST* (the float (+ (the int (the float (adjust-pos s5-0 50))) 394 (the int f30-1) (-> this right-x-offset))))) + (+ *PC-ORB-GLOW-X-ADJUST* + (the float (+ (the int (the float (adjust-pos s5-0 50))) 394 (the int f30-1) (-> this right-x-offset))))) (set! (-> this particles 18 init-pos y) (the float (- 40 (the int (* 80.0 f28-2))))) (set! (-> this icons 5 icon-x) (+ (the int *PC-ORB-X-ADJUST*) (the int (the float (adjust-pos s5-0 50))) 393 (the int f30-1) (-> this right-x-offset))) (set! (-> this icons 5 icon-y) (- (-> this small-orb-y-offset) (the int (* 80.0 f28-2)))) (set! (-> this particles 16 init-pos x) - (+ *PC-CELL-X-ADJUST* (the float (+ (the int (the float (adjust-pos s5-0 100))) 425 (the int f30-1) (-> this right-x-offset))))) + (+ *PC-CELL-X-ADJUST* + (the float (+ (the int (the float (adjust-pos s5-0 100))) 425 (the int f30-1) (-> this right-x-offset))))) (set! (-> this particles 16 init-pos y) (the float (- 112 (the int (* 60.0 f28-2))))) (set! (-> this particles 17 init-pos x) (the float @@ -1965,7 +1997,6 @@ 0 (none)) - (defun init-game-options ((obj progress)) "Set the options for all of the menus." ;; start off by making them all invalid diff --git a/goal_src/jak2/engine/ambient/ambient.gc b/goal_src/jak2/engine/ambient/ambient.gc index ce996c5ff1..2c79157a32 100644 --- a/goal_src/jak2/engine/ambient/ambient.gc +++ b/goal_src/jak2/engine/ambient/ambient.gc @@ -121,7 +121,7 @@ (defmethod play-communicator-speech! ((this talker-speech-class)) "Plays the provided [[talker-speech-class]] -@TODO - understand the array from [[game-info]] better" + @TODO - understand the array from [[game-info]] better" (set! (-> *game-info* unknown-pad6 (+ (* (-> this speech) 2) 1)) (the-as uint #xffff)) 0 (none) @@ -258,6 +258,7 @@ ) (defmethod deactivate ((this talker)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (send-event (handle->process (-> this voicebox)) 'die) (call-parent-method this) (none) @@ -346,11 +347,7 @@ (defstate idle (talker) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (the-as time-frame (-> self message delay))) - (suspend) - ) - ) + (suspend-for (the-as time-frame (-> self message delay))) (case (-> self message channel) (((gui-channel voicebox)) (if *target* @@ -477,7 +474,10 @@ (and (nonzero? (-> self message-id)) (= (get-status *gui-control* (-> self message-id)) (gui-status active)) (or (not (time-elapsed? (-> self state-time) (the-as time-frame (-> self message text-duration)))) - (and (logtest? (-> self message flags) 16) (-> self region) (point-in-region-debug! (-> self region) (target-pos 0))) + (and (logtest? (-> self message flags) 16) + (-> self region) + (point-in-region-debug! (-> self region) (target-pos 0)) + ) ) ) (not (time-elapsed? (-> self state-time) (seconds 0.05))) @@ -512,11 +512,7 @@ ) ) (when (and (logtest? (-> self message flags) 8) (not (-> self save?))) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (set! (-> self save?) #t) (auto-save-user) ) diff --git a/goal_src/jak2/engine/camera/cam-layout.gc b/goal_src/jak2/engine/camera/cam-layout.gc index 77f40f10dc..7b40b58516 100644 --- a/goal_src/jak2/engine/camera/cam-layout.gc +++ b/goal_src/jak2/engine/camera/cam-layout.gc @@ -764,14 +764,14 @@ (when (logtest? (-> *camera* settings master-options) (cam-master-options READ_BUTTONS)) (if (cpad-hold? arg2 r1) (set! (-> arg1 y) - (+ 0.5 (analog-input (the-as int (-> *cpad-list* cpads arg2 abutton 9)) 0.0 32.0 230.0 0.5) (-> arg1 y)) + (+ 0.5 (analog-input (the-as int (-> *cpad-list* cpads arg2 abutton (abutton-idx r1))) 0.0 32.0 230.0 0.5) (-> arg1 y)) ;; og:preserve-this abutton indexing ) ) ) (when (logtest? (-> *camera* settings master-options) (cam-master-options READ_BUTTONS)) (if (cpad-hold? arg2 l1) (set! (-> arg1 y) - (- (-> arg1 y) (+ 0.5 (analog-input (the-as int (-> *cpad-list* cpads arg2 abutton 8)) 0.0 32.0 230.0 0.5))) + (- (-> arg1 y) (+ 0.5 (analog-input (the-as int (-> *cpad-list* cpads arg2 abutton (abutton-idx l1))) 0.0 32.0 230.0 0.5))) ;; og:preserve-this abutton indexing ) ) ) diff --git a/goal_src/jak2/engine/camera/cam-states-dbg.gc b/goal_src/jak2/engine/camera/cam-states-dbg.gc index a2735e1254..8062a4e738 100644 --- a/goal_src/jak2/engine/camera/cam-states-dbg.gc +++ b/goal_src/jak2/engine/camera/cam-states-dbg.gc @@ -155,7 +155,7 @@ (if (cpad-hold? arg3 x) (set! (-> arg0 x) (- (-> arg0 x) (+ (-> *CAM_FREE-bank* rot-speed) (analog-input - (the-as int (-> *cpad-list* cpads arg3 abutton 6)) + (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx x))) ;; og:preserve-this abutton indexing 0.0 32.0 230.0 @@ -169,7 +169,7 @@ (when (logtest? (-> *camera* settings master-options) (cam-master-options READ_BUTTONS)) (if (cpad-hold? arg3 triangle) (+! (-> arg0 x) (+ (-> *CAM_FREE-bank* rot-speed) (analog-input - (the-as int (-> *cpad-list* cpads arg3 abutton 4)) + (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx triangle))) ;; og:preserve-this abutton indexing 0.0 32.0 230.0 @@ -182,7 +182,7 @@ (when (logtest? (-> *camera* settings master-options) (cam-master-options READ_BUTTONS)) (if (cpad-hold? arg3 square) (+! (-> arg0 y) (+ (-> *CAM_FREE-bank* rot-speed) (analog-input - (the-as int (-> *cpad-list* cpads arg3 abutton 7)) + (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx square))) ;; og:preserve-this abutton indexing 0.0 32.0 230.0 @@ -196,7 +196,7 @@ (if (cpad-hold? arg3 circle) (set! (-> arg0 y) (- (-> arg0 y) (+ (-> *CAM_FREE-bank* rot-speed) (analog-input - (the-as int (-> *cpad-list* cpads arg3 abutton 5)) + (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx circle))) ;; og:preserve-this abutton indexing 0.0 32.0 230.0 @@ -212,7 +212,7 @@ (when (logtest? (-> *camera* settings master-options) (cam-master-options READ_BUTTONS)) (if (cpad-hold? arg3 l2) (+! (-> arg0 z) (+ (-> *CAM_FREE-bank* rot-speed) (analog-input - (the-as int (-> *cpad-list* cpads arg3 abutton 10)) + (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx l2))) ;; og:preserve-this abutton indexing 0.0 32.0 230.0 @@ -226,7 +226,7 @@ (if (cpad-hold? arg3 r2) (set! (-> arg0 z) (- (-> arg0 z) (+ (-> *CAM_FREE-bank* rot-speed) (analog-input - (the-as int (-> *cpad-list* cpads arg3 abutton 11)) + (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx r2))) ;; og:preserve-this abutton indexing 0.0 32.0 230.0 @@ -243,7 +243,7 @@ (if (cpad-hold? arg3 left) (+! (-> arg1 x) (+ (-> *CAM_FREE-bank* speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 1)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx left))) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)) ;; og:preserve-this abutton indexing ) ) ) @@ -253,7 +253,7 @@ (set! (-> arg1 x) (- (-> arg1 x) (+ (-> *CAM_FREE-bank* speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 0)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx right))) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)) ;; og:preserve-this abutton indexing ) ) ) @@ -263,7 +263,7 @@ (if (cpad-hold? arg3 up) (+! (-> arg1 z) (+ (-> *CAM_FREE-bank* speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 2)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx up))) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)) ;; og:preserve-this abutton indexing ) ) ) @@ -273,7 +273,7 @@ (set! (-> arg1 z) (- (-> arg1 z) (+ (-> *CAM_FREE-bank* speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 3)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx down))) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)) ;; og:preserve-this abutton indexing ) ) ) @@ -288,7 +288,7 @@ (when (logtest? (-> *camera* settings master-options) (cam-master-options READ_BUTTONS)) (if (cpad-hold? arg3 r1) (+! (-> arg1 y) (+ (* 0.2 (-> *CAM_FREE-bank* speed)) (analog-input - (the-as int (-> *cpad-list* cpads arg3 abutton 9)) + (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx r1))) ;; og:preserve-this abutton indexing 0.0 32.0 230.0 @@ -302,7 +302,7 @@ (if (cpad-hold? arg3 l1) (set! (-> arg1 y) (- (-> arg1 y) (+ (* 0.2 (-> *CAM_FREE-bank* speed)) (analog-input - (the-as int (-> *cpad-list* cpads arg3 abutton 8)) + (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx l1))) ;; og:preserve-this abutton indexing 0.0 32.0 230.0 @@ -319,7 +319,7 @@ (if (cpad-hold? arg3 r1) (+! (-> arg1 y) (+ (-> *CAM_FREE-bank* speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 9)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx r1))) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)) ;; og:preserve-this abutton indexing ) ) ) @@ -329,7 +329,7 @@ (set! (-> arg1 y) (- (-> arg1 y) (+ (-> *CAM_FREE-bank* speed) - (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton 8)) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)) + (analog-input (the-as int (-> *cpad-list* cpads arg3 abutton (abutton-idx l1))) 0.0 32.0 230.0 (-> *CAM_FREE-bank* speed)) ;; og:preserve-this abutton indexing ) ) ) diff --git a/goal_src/jak2/engine/camera/cam-states.gc b/goal_src/jak2/engine/camera/cam-states.gc index 8c7379e1f6..ccc6428fb4 100644 --- a/goal_src/jak2/engine/camera/cam-states.gc +++ b/goal_src/jak2/engine/camera/cam-states.gc @@ -2450,7 +2450,7 @@ (if (cpad-hold? (-> *CAMERA-bank* joypad) r1) (+! f30-2 (+ (* 10922.667 (seconds-per-frame)) (analog-input - (the-as int (-> *cpad-list* cpads (-> *CAMERA-bank* joypad) abutton 9)) + (the-as int (-> *cpad-list* cpads (-> *CAMERA-bank* joypad) abutton (abutton-idx r1))) ;; og:preserve-this abutton indexing 0.0 32.0 230.0 @@ -2464,7 +2464,7 @@ (if (cpad-hold? (-> *CAMERA-bank* joypad) l1) (set! f30-2 (- f30-2 (+ (* 10922.667 (seconds-per-frame)) (analog-input - (the-as int (-> *cpad-list* cpads (-> *CAMERA-bank* joypad) abutton 8)) + (the-as int (-> *cpad-list* cpads (-> *CAMERA-bank* joypad) abutton (abutton-idx l1))) ;; og:preserve-this abutton indexing 0.0 32.0 230.0 diff --git a/goal_src/jak2/engine/common_objs/crates.gc b/goal_src/jak2/engine/common_objs/crates.gc index 244d6f7e67..5f6360d316 100644 --- a/goal_src/jak2/engine/common_objs/crates.gc +++ b/goal_src/jak2/engine/common_objs/crates.gc @@ -841,11 +841,7 @@ ) ) (when (not arg0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.04)) - (suspend) - ) - ) + (suspend-for (seconds 0.04)) (logior! (-> self draw status) (draw-control-status no-draw)) (case (-> self look) (('iron) @@ -996,17 +992,9 @@ (drop-pickup (-> self fact) #t *entity-pool* (the-as fact-info #f) arg1) (process-entity-status! self (entity-perm-status dead) #t) (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 5)) - (suspend) - ) - ) + (suspend-for (seconds 5)) (when (logtest? (actor-option cond-respawn) (-> self fact options)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 15)) - (suspend) - ) - ) + (suspend-for (seconds 15)) (go-virtual hide) ) ) @@ -1127,11 +1115,11 @@ (defmethod init-from-entity! ((this crate) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (crate-init! this arg0) (skel-init! this) (crate-method-38 this) diff --git a/goal_src/jak2/engine/common_objs/generic-obs.gc b/goal_src/jak2/engine/common_objs/generic-obs.gc index 3b371cdc8f..7ac5e5c882 100644 --- a/goal_src/jak2/engine/common_objs/generic-obs.gc +++ b/goal_src/jak2/engine/common_objs/generic-obs.gc @@ -229,12 +229,7 @@ (move-along-path self) (suspend) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (move-along-path self) - (suspend) - ) - ) + (suspend-for (seconds 0.5) (move-along-path self)) (go-virtual idle) ) ) @@ -242,11 +237,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this swingpole) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" "Copy defaults from the entity." (stack-size-set! (-> this main-thread) 128) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) @@ -339,11 +334,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this process-hidden) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" "Copy defaults from the entity." (process-entity-status! this (entity-perm-status dead) #t) (go (method-of-object this die)) @@ -1020,6 +1015,7 @@ This commonly includes things such as: ) (defmethod deactivate ((this part-tracker)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (if (nonzero? (-> this part)) (kill-and-free-particles (-> this part)) ) @@ -1091,28 +1087,26 @@ This commonly includes things such as: ) (suspend) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (the-as time-frame (-> self linger-duration))) - (if (-> self linger-callback) - ((-> self linger-callback) self) - ) - (let* ((s5-0 (handle->process (-> self target))) - (v1-30 (if (type? s5-0 process-drawable) - s5-0 - ) - ) - ) - (if (and v1-30 - (nonzero? (-> (the-as process-drawable v1-30) root)) - (nonzero? (-> (the-as process-drawable v1-30) node-list)) - ) - (vector<-cspace! - (-> self root trans) - (-> (the-as process-drawable v1-30) node-list data (-> self target-joint)) - ) - ) + (suspend-for + (the-as time-frame (-> self linger-duration)) + (if (-> self linger-callback) + ((-> self linger-callback) self) ) - (suspend) + (let* ((s5-0 (handle->process (-> self target))) + (v1-30 (if (type? s5-0 process-drawable) + s5-0 + ) + ) + ) + (if (and v1-30 + (nonzero? (-> (the-as process-drawable v1-30) root)) + (nonzero? (-> (the-as process-drawable v1-30) node-list)) + ) + (vector<-cspace! + (-> self root trans) + (-> (the-as process-drawable v1-30) node-list data (-> self target-joint)) + ) + ) ) ) (if (-> self linger-callback) @@ -1736,11 +1730,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this med-res-level) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (stack-size-set! (-> this main-thread) 128) (let ((s4-0 (res-lump-struct arg0 'art-name structure)) (s3-0 (res-lump-struct (-> this entity) 'level structure)) @@ -1763,6 +1757,7 @@ This commonly includes things such as: ) (defmethod deactivate ((this part-spawner)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (if (nonzero? (-> this part)) (kill-and-free-particles (-> this part)) ) @@ -1817,11 +1812,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this part-spawner) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 string)) (stack-size-set! (-> this main-thread) 128) (logior! (-> this mask) (process-mask ambient)) @@ -2422,11 +2417,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this launcher) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (stack-size-set! (-> this main-thread) 128) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((v1-4 (new 'process 'collide-shape-prim-sphere s4-0 (the-as uint 0)))) diff --git a/goal_src/jak2/engine/common_objs/powerups.gc b/goal_src/jak2/engine/common_objs/powerups.gc index c9117b70f8..c415c8a0de 100644 --- a/goal_src/jak2/engine/common_objs/powerups.gc +++ b/goal_src/jak2/engine/common_objs/powerups.gc @@ -20,25 +20,23 @@ (let ((s1-1 (process->handle arg0)) (s2-1 (process->handle arg1)) ) - (let ((s0-0 (current-time))) - (until (time-elapsed? s0-0 (+ arg3 arg4)) - (let ((v1-8 (or (not (handle->process s1-1)) (not (handle->process s2-1))))) - (if v1-8 - (deactivate self) - ) - ) - (let* ((f0-1 (fmax 0.0 (fmin 1.0 (/ (- (the float (- (current-time) s0-0)) (the float arg3)) (the float arg4))))) - (a0-18 (process-drawable-pair-random-point! - (the-as process-drawable (-> s1-1 process 0)) - (the-as process-drawable (-> s2-1 process 0)) - (new-stack-vector0) - f0-1 - ) + (suspend-for + (+ arg3 arg4) + (let ((v1-8 (or (not (handle->process s1-1)) (not (handle->process s2-1))))) + (if v1-8 + (deactivate self) + ) + ) + (let* ((f0-1 (fmax 0.0 (fmin 1.0 (/ (- (the float (- (current-time) time)) (the float arg3)) (the float arg4))))) + (a0-18 (process-drawable-pair-random-point! + (the-as process-drawable (-> s1-1 process 0)) + (the-as process-drawable (-> s2-1 process 0)) + (new-stack-vector0) + f0-1 ) - ) - (arg2 a0-18) - ) - (suspend) + ) + ) + (arg2 a0-18) ) ) (cond @@ -49,12 +47,10 @@ #f ) (else - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 arg5) - (let ((a0-21 (process-drawable-random-point! (the-as process-drawable (-> s2-1 process 0)) (new-stack-vector0)))) - (arg2 a0-21) - ) - (suspend) + (suspend-for + arg5 + (let ((a0-21 (process-drawable-random-point! (the-as process-drawable (-> s2-1 process 0)) (new-stack-vector0)))) + (arg2 a0-21) ) ) ) diff --git a/goal_src/jak2/engine/game/game-info.gc b/goal_src/jak2/engine/game/game-info.gc index eae06b5abc..21d708cddb 100644 --- a/goal_src/jak2/engine/game/game-info.gc +++ b/goal_src/jak2/engine/game/game-info.gc @@ -1653,17 +1653,17 @@ ;; right = 5th bit and 1st index for pressure ;; left = 7th bit and 2nd index for pressure (let ((right-pressed? (logtest? (-> this button0) (pad-buttons right))) - (right-pressure (-> this abutton 0)) + (right-pressure (-> this abutton (abutton-idx right))) ;; og:preserve-this abutton indexing (left-pressed? (logtest? (-> this button0) (pad-buttons left))) - (left-pressure (-> this abutton 1))) + (left-pressure (-> this abutton (abutton-idx left)))) ;; og:preserve-this abutton indexing (when right-pressed? (logclear! (-> this button0) (pad-buttons right)) (logior! (-> this button0) (pad-buttons left))) (when left-pressed? (logclear! (-> this button0) (pad-buttons left)) (logior! (-> this button0) (pad-buttons right))) - (set! (-> this abutton 0) left-pressure) - (set! (-> this abutton 1) right-pressure)))) + (set! (-> this abutton (abutton-idx right)) left-pressure) ;; og:preserve-this abutton indexing + (set! (-> this abutton (abutton-idx left)) right-pressure)))) ;; og:preserve-this abutton indexing 0) (defmethod game-info-method-28 ((this game-info) (arg0 game-score) (arg1 float)) diff --git a/goal_src/jak2/engine/game/task/task-control.gc b/goal_src/jak2/engine/game/task/task-control.gc index 300fce410e..62fa1873a4 100644 --- a/goal_src/jak2/engine/game/task/task-control.gc +++ b/goal_src/jak2/engine/game/task/task-control.gc @@ -1481,6 +1481,7 @@ (defmethod run-logic? ((this fail-mission)) + "Should this process be run? Checked by execute-process-tree." #t ) @@ -1676,6 +1677,7 @@ ) (defmethod deactivate ((this fail-mission)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (set-filter-color! 1.0 1.0 1.0) (sound-group-continue (sound-group sfx music dialog sog3 ambient dialog2 sog6 sog7)) (update-rates! (-> *display* bg-clock) 1.0) @@ -1713,27 +1715,25 @@ ) :code (behavior () (local-vars (a1-10 string)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (let ((f30-0 (lerp-scale 1.0 0.0 (the float (- (current-time) gp-0)) 0.0 270.0))) - (when *sound-player-enable* - (let ((v1-6 (the-as sound-rpc-set-param (get-sound-buffer-entry)))) - (set! (-> v1-6 command) (sound-command set-param)) - (set! (-> v1-6 id) (-> self stinger)) - (set! (-> v1-6 params volume) (the int (* 1024.0 f30-0))) - (set! (-> v1-6 params mask) (the-as uint 1)) - (-> v1-6 id) - ) + (suspend-for + (seconds 1) + (let ((f30-0 (lerp-scale 1.0 0.0 (the float (- (current-time) time)) 0.0 270.0))) + (when *sound-player-enable* + (let ((v1-6 (the-as sound-rpc-set-param (get-sound-buffer-entry)))) + (set! (-> v1-6 command) (sound-command set-param)) + (set! (-> v1-6 id) (-> self stinger)) + (set! (-> v1-6 params volume) (the int (* 1024.0 f30-0))) + (set! (-> v1-6 params mask) (the-as uint 1)) + (-> v1-6 id) ) ) - (let ((f30-1 (lerp-scale 1.0 0.0 (the float (- (current-time) gp-0)) 0.0 300.0))) - (set-filter-color! - (lerp-scale 1.0 1.25 f30-1 0.0 1.0) - (lerp-scale 1.0 0.875 f30-1 0.0 1.0) - (lerp-scale 1.0 0.25 f30-1 0.0 1.0) - ) + ) + (let ((f30-1 (lerp-scale 1.0 0.0 (the float (- (current-time) time)) 0.0 300.0))) + (set-filter-color! + (lerp-scale 1.0 1.25 f30-1 0.0 1.0) + (lerp-scale 1.0 0.875 f30-1 0.0 1.0) + (lerp-scale 1.0 0.25 f30-1 0.0 1.0) ) - (suspend) ) ) (case (-> self message) @@ -1866,15 +1866,16 @@ ) ;; WARN: Return type mismatch process vs task-manager. -(defmethod relocate ((this task-manager) (arg0 int)) +(defmethod relocate ((this task-manager) (offset int)) (if (nonzero? (-> this link)) - (+! (-> this link) arg0) + (+! (-> this link) offset) ) - (the-as task-manager ((method-of-type process relocate) this arg0)) + (the-as task-manager ((method-of-type process relocate) this offset)) ) (defbehavior task-manager-init-by-other task-manager ((arg0 game-task-node-info) (arg1 symbol)) - (stack-size-set! (-> self main-thread) 3072) ;; increased from 1024 + ;; og:preserve-this increased from 1024 + (stack-size-set! (-> self main-thread) 3072) (add-connection *task-manager-engine* self nothing self arg0 #f) (set! (-> self node-info) arg0) (set! (-> self lev-name) arg1) @@ -1951,6 +1952,7 @@ ) (defmethod deactivate ((this task-manager)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (with-pp (let ((s5-0 pp)) (set! pp this) diff --git a/goal_src/jak2/engine/gfx/foreground/foreground.gc b/goal_src/jak2/engine/gfx/foreground/foreground.gc index 03b010e83c..649f2120ac 100644 --- a/goal_src/jak2/engine/gfx/foreground/foreground.gc +++ b/goal_src/jak2/engine/gfx/foreground/foreground.gc @@ -1423,7 +1423,8 @@ ) (cond ((or (nonzero? (-> bucket-info must-use-mercneric-for-clip)) - (or (< 0.0 t-amount) (logtest? (-> geo effect effect-idx effect-bits) (effect-bits cross-fade))) + ;; force envmap mode, even if strength is zero - PC renderer will handle this case. + (or #|(< 0.0 t-amount)|# #t (logtest? (-> geo effect effect-idx effect-bits) (effect-bits cross-fade))) ) (let ((a0-33 (&-> tint-info tint)) (v1-74 (the-as object (-> bucket-info effect effect-idx))) diff --git a/goal_src/jak2/engine/gfx/texture/texture-anim.gc b/goal_src/jak2/engine/gfx/texture/texture-anim.gc index 36498f729c..69fef2edd1 100644 --- a/goal_src/jak2/engine/gfx/texture/texture-anim.gc +++ b/goal_src/jak2/engine/gfx/texture/texture-anim.gc @@ -777,6 +777,34 @@ struct SlimeInput { (the int (-> *toxic-slime-texture-anim-array* array-data 8 tex dest 0))) ) +(defun pc-clut-blender ((bucket bucket-id) (id texture-anim-pc) (anim-array texture-anim-array)) + (let* ((sz (-> anim-array length)) + (qwc (+ 1 (/ (+ 3 sz) 4)))) + (with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf)) + bucket + ) + (pc-texture-anim-flag start-anim-array dma-buf) + (pc-texture-anim-flag-id id dma-buf :qwc qwc) + (let ((morph (-> anim-array array-data 0 frame-time)) + (vec (the vector (-> dma-buf base))) + ) + (set! (-> vec x) morph) + ) + (&+! (-> dma-buf base) 16) + (dotimes (i sz) + (let ((tex (-> anim-array array-data i tex))) + (set! (-> (the (pointer uint32) (-> dma-buf base)) i) + (if tex (-> tex dest 0) + -1) + ) + ) + ) + (&+! (-> dma-buf base) (- (* 16 qwc) 16)) + (pc-texture-anim-flag finish-anim-array dma-buf) + ) + ) + (none) + ) (defun update-texture-anim ((bucket bucket-id) (anim-array texture-anim-array)) @@ -902,96 +930,23 @@ struct SlimeInput { (return #f) ) ((= anim-array *darkjak-texture-anim-array*) - ;; darkjak is simple, and we reimplemented it in C++. - ;; so we just have to send the frame-time value. - ;; (format *stdcon* "doing darkjak~%") - (with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf)) - bucket - ) - (pc-texture-anim-flag start-anim-array dma-buf) - (pc-texture-anim-flag darkjak dma-buf :qwc 1) - (let ((morph (-> anim-array array-data 0 frame-time)) - (vec (the vector (-> dma-buf base))) - ) - (set! (-> vec x) morph) - ) - (&+! (-> dma-buf base) 16) - (pc-texture-anim-flag finish-anim-array dma-buf) - ) + (pc-clut-blender bucket (texture-anim-pc darkjak) anim-array) (return #f) ) - ((= anim-array *jakb-prison-texture-anim-array*) - ;; prison is simple, and we reimplemented it in C++. - ;; so we just have to send the frame-time value. - (with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf)) - bucket - ) - (pc-texture-anim-flag start-anim-array dma-buf) - (pc-texture-anim-flag prison-jak dma-buf :qwc 1) - (let ((morph (-> anim-array array-data 0 frame-time)) - (vec (the vector (-> dma-buf base))) - ) - (set! (-> vec x) morph) - ) - (&+! (-> dma-buf base) 16) - (pc-texture-anim-flag finish-anim-array dma-buf) - ) + (pc-clut-blender bucket (texture-anim-pc prison-jak) anim-array) (return #f) ) - ((= anim-array *darkjak-hires-texture-anim-array*) - ;; oracle is simple, and we reimplemented it in C++. - ;; so we just have to send the frame-time value. - (with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf)) - bucket - ) - (pc-texture-anim-flag start-anim-array dma-buf) - (pc-texture-anim-flag oracle-jak dma-buf :qwc 1) - (let ((morph (-> anim-array array-data 0 frame-time)) - (vec (the vector (-> dma-buf base))) - ) - (set! (-> vec x) morph) - ) - (&+! (-> dma-buf base) 16) - (pc-texture-anim-flag finish-anim-array dma-buf) - ) + (pc-clut-blender bucket (texture-anim-pc oracle-jak) anim-array) (return #f) ) ((= anim-array *darkjak-hires-nest-texture-anim-array*) - ;; oracle is simple, and we reimplemented it in C++. - ;; so we just have to send the frame-time value. - (with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf)) - bucket - ) - (pc-texture-anim-flag start-anim-array dma-buf) - (pc-texture-anim-flag nest-jak dma-buf :qwc 1) - (let ((morph (-> anim-array array-data 0 frame-time)) - (vec (the vector (-> dma-buf base))) - ) - (set! (-> vec x) morph) - ) - (&+! (-> dma-buf base) 16) - (pc-texture-anim-flag finish-anim-array dma-buf) - ) + (pc-clut-blender bucket (texture-anim-pc nest-jak) anim-array) (return #f) ) ((= anim-array *kor-transform-texture-anim-array*) - ;; kor is simple, and we reimplemented it in C++. - ;; so we just have to send the frame-time value. - (with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf)) - bucket - ) - (pc-texture-anim-flag start-anim-array dma-buf) - (pc-texture-anim-flag kor-transform dma-buf :qwc 1) - (let ((morph (-> anim-array array-data 0 frame-time)) - (vec (the vector (-> dma-buf base))) - ) - (set! (-> vec x) morph) - ) - (&+! (-> dma-buf base) 16) - (pc-texture-anim-flag finish-anim-array dma-buf) - ) + ; (pc-clut-blender bucket (texture-anim-pc kor-transform) anim-array) (return #f) ) (else diff --git a/goal_src/jak2/engine/load/loader.gc b/goal_src/jak2/engine/load/loader.gc index e28b79a03c..c1d7ed8fcc 100644 --- a/goal_src/jak2/engine/load/loader.gc +++ b/goal_src/jak2/engine/load/loader.gc @@ -2299,7 +2299,7 @@ ) (set! (-> gp-0 cmd 69) '((65 . wait) (71 . wait) (67 . wait) (66 . wait))) (set! (-> gp-0 cmd 70) '((65 . wait) (90 . hide) (91 . hide) (81 . hide) (80 . hide))) - ;; added this one + ;; og:preserve-this added this one (set! (-> gp-0 cmd (gui-channel subtitle-pc)) '(((the binteger (gui-channel blackout)) . wait) )) (set! (-> gp-0 cmd 80) '((64 . wait) (65 . wait) (80 . wait) (70 . wait))) diff --git a/goal_src/jak2/engine/mods/mod-settings.gc b/goal_src/jak2/engine/mods/mod-settings.gc index 5baaeef235..58f3548ade 100644 --- a/goal_src/jak2/engine/mods/mod-settings.gc +++ b/goal_src/jak2/engine/mods/mod-settings.gc @@ -37,11 +37,14 @@ if the result of rand-vu-int-range is 1, then DANCE! if it is not 1, then Don't ;; Define Settings to use in mods ;;;;;;;;;;;;;;;;;;;;;;;;;; -(define startingDebugContinuePoint "village1-hut") ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Define Custom Settings Variables to use in mods ;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Change #f to #t here to show the input display by default -(define *show-input-display* #f) \ No newline at end of file +(define *show-input-display* #f) + +;; do NOT change %MODVERSIONPLACEHOLDER% below, otherwise the mod-bundling-tools +;; will be unable to automatically add version info to the speedrun display +(define *mod-version-text* "%MODVERSIONPLACEHOLDER%") \ No newline at end of file diff --git a/goal_src/jak2/engine/process-drawable/process-taskable.gc b/goal_src/jak2/engine/process-drawable/process-taskable.gc index 0bdacc82eb..05e1d8baea 100644 --- a/goal_src/jak2/engine/process-drawable/process-taskable.gc +++ b/goal_src/jak2/engine/process-drawable/process-taskable.gc @@ -8,17 +8,17 @@ ;; DECOMP BEGINS ;; WARN: Return type mismatch process-focusable vs process-taskable. -(defmethod relocate ((this process-taskable) (arg0 int)) +(defmethod relocate ((this process-taskable) (offset int)) (if (nonzero? (-> this task)) - (&+! (-> this task) arg0) + (&+! (-> this task) offset) ) - (the-as process-taskable ((method-of-type process-focusable relocate) this arg0)) + (the-as process-taskable ((method-of-type process-focusable relocate) this offset)) ) (defbehavior process-taskable-anim-loop process-taskable ((arg0 (function process-taskable object))) "Takes in a function and loops as long as it's return value is truthy -Seen take in - `true-func` which takes no args TODO - seems fishy -- a `(process-taskable process) lambda" + Seen take in - `true-func` which takes no args TODO - seems fishy + - a `(process-taskable process) lambda" (while (arg0 self) (let ((s5-0 (get-art-elem self))) (when (!= (ja-group) s5-0) @@ -43,7 +43,7 @@ Seen take in - `true-func` which takes no args TODO - seems fishy ;; WARN: Return type mismatch art-joint-anim vs art-element. (defmethod get-art-elem ((this process-taskable)) "Checks various things such the current actor, task status, etc to determine the right art-group data to use -@returns the appropriate [[art-element]] for the given NPC" + @returns the appropriate [[art-element]] for the given NPC" (the-as art-element (if (> (-> this skel active-channels) 0) (-> this skel root-channel 0 frame-group) ) @@ -329,11 +329,7 @@ Seen take in - `true-func` which takes no args TODO - seems fishy :enter (-> (method-of-type process-taskable active) enter) :exit (-> (method-of-type process-taskable active) exit) :code (behavior ((arg0 game-task-event)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (go-virtual hide) ) :post (-> (method-of-type process-taskable idle) post) @@ -418,11 +414,11 @@ Seen take in - `true-func` which takes no args TODO - seems fishy ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this process-taskable) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (stack-size-set! (-> this main-thread) 512) (process-taskable-method-31 this) (process-drawable-from-entity! this arg0) diff --git a/goal_src/jak2/engine/ps2/pad.gc b/goal_src/jak2/engine/ps2/pad.gc index 3b318f657f..72ffad0730 100644 --- a/goal_src/jak2/engine/ps2/pad.gc +++ b/goal_src/jak2/engine/ps2/pad.gc @@ -48,6 +48,21 @@ The cpad-set-buzz! function can be used for vibration. (confirm 24) ) +(defenum abutton-idx + :type uint8 + (right 0) + (left 1) + (up 2) + (down 3) + (triangle 4) + (circle 5) + (x 6) + (square 7) + (l1 8) + (r1 9) + (l2 10) + (r2 11)) + (defenum pad-type (normal 4) (analog 5) @@ -460,73 +475,73 @@ The cpad-set-buzz! function can be used for vibration. (set! (-> history button0-rel 1) (-> pad button0-rel 0)) (when (= (-> pad status) 115) - (set! (-> pad abutton 0) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons right)) + (set! (-> pad abutton (abutton-idx right)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons right)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 1) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons left)) + (set! (-> pad abutton (abutton-idx left)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons left)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 2) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons up)) + (set! (-> pad abutton (abutton-idx up)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons up)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 3) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons down)) + (set! (-> pad abutton (abutton-idx down)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons down)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 6) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons x)) + (set! (-> pad abutton (abutton-idx x)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons x)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 5) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons circle)) + (set! (-> pad abutton (abutton-idx circle)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons circle)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 4) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons triangle)) + (set! (-> pad abutton (abutton-idx triangle)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons triangle)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 7) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons square)) + (set! (-> pad abutton (abutton-idx square)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons square)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 8) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons l1)) + (set! (-> pad abutton (abutton-idx l1)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons l1)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 10) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons l2)) + (set! (-> pad abutton (abutton-idx l2)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons l2)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 9) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons r1)) + (set! (-> pad abutton (abutton-idx r1)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons r1)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 11) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons r2)) + (set! (-> pad abutton (abutton-idx r2)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons r2)) ;; og:preserve-this abutton indexing 255 0 ) diff --git a/goal_src/jak2/engine/sound/gsound-h.gc b/goal_src/jak2/engine/sound/gsound-h.gc index f7fdec9250..b1d988ae4b 100644 --- a/goal_src/jak2/engine/sound/gsound-h.gc +++ b/goal_src/jak2/engine/sound/gsound-h.gc @@ -143,11 +143,31 @@ ) ) -(defmacro sound-play (name &key (id (new-sound-id)) - &key (vol 100.0) &key (pitch 0) &key (bend 0) - &key (group sfx) - &key (position #t)) - `(sound-play-by-name (static-sound-name ,name) ,id (the int (* (/ 1024.0 100.0) ,vol)) (the int (* 1524.0 ,pitch)) ,bend (sound-group ,group) ,position)) +;; og:modbase set to #t to enable sound-replacements. disabled by default to avoid extra PC function calls +;; e.g. replace "skill-pickup" with custom_assets/jak2/audio/sound_replacements/skill-pickup.mp3 +(define *enable-sound-replacements?* #f) +;; og:modbase temp-string to be used by sound-play replacements only +(define *sound-play-temp-string* (new 'global 'string 2048 (the string #f))) +;; same as string-format but will only use the specified temp-string provided when called +(defmacro temp-string-format (temp-str &rest args) + `(begin + (format (clear ,temp-str) ,@args) + ,temp-str)) + +;; og:modbase try to play replacement sound, nonzero results means it wasnt found, so fall back to playing original sound. +;; force-vanilla? flag lets you force vanilla sound for specific caller +(defmacro sound-play (name &key (id (new-sound-id)) &key (vol 100.0) &key (pitch 0) &key (bend 0) &key (group sfx) &key (position #t) &key (force-vanilla? #f)) + `(let ((sound-played? (and *enable-sound-replacements?* (not ,force-vanilla?) + (play-sound-file (temp-string-format *sound-play-temp-string* "sound_replacements/~S.mp3" ,name) 50)))) + ;; the below line would use vanilla volume instead, if you're sure your custom sounds won't be too loud + ;; (the-as sound-id (play-sound-file filepath (the int (* (/ 1024.0 100.0) ,vol)))) + (cond + (sound-played? + ;; Custom sound was found + (the-as sound-id sound-played?)) + (else + ;; Custom sound not found, play the original instead + (sound-play-by-name (static-sound-name ,name) ,id (the int (* (/ 1024.0 100.0) ,vol)) (the int (* 1524.0 ,pitch)) ,bend (sound-group ,group) ,position))))) (defmacro sound-vol (vol) "convert to sound volume units" diff --git a/goal_src/jak2/engine/target/board/board-states.gc b/goal_src/jak2/engine/target/board/board-states.gc index 9af9c4af22..87a68ac7be 100644 --- a/goal_src/jak2/engine/target/board/board-states.gc +++ b/goal_src/jak2/engine/target/board/board-states.gc @@ -997,7 +997,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (mod-var-jump #t #f (cpad-hold? (-> self control cpad number) x) (-> self control transv)) @@ -1545,7 +1545,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (mod-var-jump #t #f (cpad-hold? (-> self control cpad number) x) (-> self control transv)) @@ -1700,7 +1700,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (mod-var-jump #t #f (cpad-hold? (-> self control cpad number) x) (-> self control transv)) @@ -1837,7 +1837,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (mod-var-jump #t #f (cpad-hold? (-> self control cpad number) x) (-> self control transv)) @@ -2980,11 +2980,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (move-to-point! (-> self control) s4-1) ) (set! (-> self control camera-pos quad) (-> self control trans quad)) diff --git a/goal_src/jak2/engine/target/gun/gun-dark-shot.gc b/goal_src/jak2/engine/target/gun/gun-dark-shot.gc index 89f19bb40d..41a36a67c2 100644 --- a/goal_src/jak2/engine/target/gun/gun-dark-shot.gc +++ b/goal_src/jak2/engine/target/gun/gun-dark-shot.gc @@ -642,15 +642,19 @@ (set! (-> gp-1 penetrate-using) (penetrate explode)) (explosion-spawn (the-as process-drawable *default-pool*) explosion gp-1) ) - ;; og:preserve-this stack array -> pointer - (let (;(s3-0 (the-as (array collide-shape) (new 'stack 'array collide-shape 16))) - (s3-0 (the-as (pointer collide-shape) (new 'stack-no-clear 'array 'collide-shape 16))) + (let ((s3-0 (the-as (array collide-shape) ((method-of-type array new) + (the-as symbol (new 'stack-no-clear 'array 'collide-shape 16)) + array + collide-shape + 16 + ) + ) + ) (a1-8 (new 'stack-no-clear 'sphere)) ) (set! (-> a1-8 quad) (-> self root trans quad)) (set! (-> a1-8 r) (-> self blast-radius)) - ;; og:preserve-this stack array -> pointer - (let ((gp-2 (fill-actor-list-for-sphere *actor-hash* a1-8 s3-0 16))) + (let ((gp-2 (fill-actor-list-for-sphere *actor-hash* a1-8 (-> s3-0 data) (-> s3-0 allocated-length)))) (let ((s1-0 (the-as process-drawable #f)) (f30-0 4096000.0) (s4-0 0) @@ -816,11 +820,7 @@ (-> self result-array (+ gp-2 -1)) :to s4-1 ) - (let ((s4-2 (current-time))) - (until (time-elapsed? s4-2 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) ) ) ) diff --git a/goal_src/jak2/engine/target/mech/mech-states.gc b/goal_src/jak2/engine/target/mech/mech-states.gc index e0d1dd9c84..58119ea312 100644 --- a/goal_src/jak2/engine/target/mech/mech-states.gc +++ b/goal_src/jak2/engine/target/mech/mech-states.gc @@ -1002,11 +1002,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (move-to-point! (-> self control) s4-1) ) (set! (-> self control camera-pos quad) (-> self control trans quad)) @@ -1141,12 +1137,7 @@ ) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! jakb-mech-jump-loop-ja :num! (loop! 0.5) :frame-num 0.0) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.8)) - (ja :group! jakb-mech-jump-loop-ja :num! (loop! 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.8) (ja :group! jakb-mech-jump-loop-ja :num! (loop! 0.5))) (remove-setting! 'mode-name) ) (else @@ -1266,11 +1257,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) ) (set! (-> self control transv quad) (the-as uint128 0)) @@ -2282,7 +2269,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) ((-> target-mech-carry-falling trans)) diff --git a/goal_src/jak2/engine/target/mech/mech.gc b/goal_src/jak2/engine/target/mech/mech.gc index eac3407338..1753e74656 100644 --- a/goal_src/jak2/engine/target/mech/mech.gc +++ b/goal_src/jak2/engine/target/mech/mech.gc @@ -237,12 +237,7 @@ (mech-method-24 self) (suspend) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (mech-method-24 self) - (suspend) - ) - ) + (suspend-for (seconds 1) (mech-method-24 self)) (go arg0) ) ) @@ -351,11 +346,11 @@ (defmethod init-from-entity! ((this mech) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (mech-init arg0 (the-as matrix3 #f) (the-as handle #f) 100.0) (none) ) diff --git a/goal_src/jak2/engine/target/target-carry.gc b/goal_src/jak2/engine/target/target-carry.gc index a018cd561e..b8e08d1116 100644 --- a/goal_src/jak2/engine/target/target-carry.gc +++ b/goal_src/jak2/engine/target/target-carry.gc @@ -616,7 +616,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) ((-> target-carry-falling trans)) diff --git a/goal_src/jak2/engine/target/target-death.gc b/goal_src/jak2/engine/target/target-death.gc index 8272bb5725..8e4b69accf 100644 --- a/goal_src/jak2/engine/target/target-death.gc +++ b/goal_src/jak2/engine/target/target-death.gc @@ -310,11 +310,7 @@ ) ) ) - (let ((s5-6 (current-time))) - (until (time-elapsed? s5-6 (seconds 0.05)) - (suspend) - ) - ) + (suspend-for (seconds 0.05)) ) ((logtest? (-> arg0 flags) (continue-flags title)) (go target-title #t) @@ -337,11 +333,7 @@ (intro-play) ) ((logtest? (-> arg0 flags) (continue-flags warp-gate)) - (let ((s5-7 (current-time))) - (until (time-elapsed? s5-7 (seconds 0.05)) - (suspend) - ) - ) + (suspend-for (seconds 0.05)) (let ((s5-8 (new 'static 'vector)) (a2-26 (find-nearest-entity (-> arg0 trans) warp-gate)) ) @@ -371,11 +363,7 @@ (go target-grab 'stance) ) (else - (let ((s5-9 (current-time))) - (until (time-elapsed? s5-9 (seconds 0.05)) - (suspend) - ) - ) + (suspend-for (seconds 0.05)) ) ) (let* ((a0-122 *game-info*) @@ -1026,11 +1014,7 @@ (let ((gp-1 (new-stack-vector0))) (set! (-> gp-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (move-to-point! (-> self control) gp-1) ) (set! (-> self control camera-pos quad) (-> self control trans quad)) @@ -1645,11 +1629,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-3 (current-time))) - (until (time-elapsed? s5-3 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (b! #t cfg-131 :delay (nop!)) (label cfg-79) (b! (not (or (= v1-63 'grenade) (= v1-63 'big-explosion) (= v1-63 'explode))) cfg-122 :delay (empty-form)) @@ -1760,11 +1740,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((s5-7 (current-time))) - (until (time-elapsed? s5-7 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) (b! #t cfg-131 :delay (nop!)) (label cfg-122) @@ -1813,11 +1789,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-10 (current-time))) - (until (time-elapsed? s5-10 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) ) (label cfg-131) @@ -1833,11 +1805,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-11 (current-time))) - (until (time-elapsed? s5-11 (seconds 1.2)) - (suspend) - ) - ) + (suspend-for (seconds 1.2)) ) ((= v1-50 'endlessfall) ((lambda :behavior target @@ -1875,38 +1843,36 @@ (target-falling-anim 30 (seconds 0.33)) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! jakb-launch-jump-loop-ja :num! (loop! 0.5) :frame-num 0.0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.8)) - (when (and (logtest? (-> self control status) (collide-status on-surface)) (!= (-> self control cur-pat event) 2)) - (set! v1-24 'target-hit-ground-hard) - (goto cfg-17) + (suspend-for + (seconds 0.8) + (when (and (logtest? (-> self control status) (collide-status on-surface)) (!= (-> self control cur-pat event) 2)) + (set! v1-24 'target-hit-ground-hard) + (goto cfg-17) + ) + (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) + (let ((v1-49 (new-stack-vector0)) + (f0-7 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) + ) + 0.0 + (vector-! + v1-49 + (-> self control transv) + (vector-float*! v1-49 (-> self control dynam gravity-normal) (the-as float f0-7)) ) - (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) - (let ((v1-49 (new-stack-vector0)) - (f0-7 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) + (let* ((f1-7 (vector-length v1-49)) + (f2-2 f1-7) + ) + (if (< (the-as float (-> self control unknown-word04)) (the-as float f0-7)) + (set! f0-7 (-> self control unknown-word04)) ) - 0.0 - (vector-! - v1-49 + (vector+! (-> self control transv) - (vector-float*! v1-49 (-> self control dynam gravity-normal) (the-as float f0-7)) - ) - (let* ((f1-7 (vector-length v1-49)) - (f2-2 f1-7) - ) - (if (< (the-as float (-> self control unknown-word04)) (the-as float f0-7)) - (set! f0-7 (-> self control unknown-word04)) - ) - (vector+! - (-> self control transv) - (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f0-7)) - (vector-float*! v1-49 v1-49 (/ f1-7 f2-2)) - ) + (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f0-7)) + (vector-float*! v1-49 v1-49 (/ f1-7 f2-2)) ) ) - (ja :group! jakb-launch-jump-loop-ja :num! (loop! 0.5)) - (suspend) ) + (ja :group! jakb-launch-jump-loop-ja :num! (loop! 0.5)) ) (set! v1-24 #f) (label cfg-17) @@ -1921,11 +1887,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) (remove-setting! 'mode-name) (none) @@ -2014,11 +1976,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((s5-13 (current-time))) - (until (time-elapsed? s5-13 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) ((= v1-50 'centipede) (set! (-> self trans-hook) #f) diff --git a/goal_src/jak2/engine/target/target-turret.gc b/goal_src/jak2/engine/target/target-turret.gc index 7dd3d86b8c..aed7aac37e 100644 --- a/goal_src/jak2/engine/target/target-turret.gc +++ b/goal_src/jak2/engine/target/target-turret.gc @@ -714,13 +714,13 @@ ;; WARN: Return type mismatch process-drawable vs base-turret. -(defmethod relocate ((this base-turret) (arg0 int)) +(defmethod relocate ((this base-turret) (offset int)) (countdown (v1-0 4) (if (-> this gun-recoil-jmod v1-0) - (&+! (-> this gun-recoil-jmod v1-0) arg0) + (&+! (-> this gun-recoil-jmod v1-0) offset) ) ) - (the-as base-turret ((method-of-type process-drawable relocate) this arg0)) + (the-as base-turret ((method-of-type process-drawable relocate) this offset)) ) (defmethod base-turret-method-34 ((this base-turret) (arg0 process)) @@ -1250,8 +1250,9 @@ ) ) (when (and (-> self enable-controls) (>= (-> *camera-combiner* interp-val) 1.0)) - (set! (-> self rotyvv) (analog-input (the-as int (-> *cpad-list* cpads 0 leftx)) 128.0 32.0 110.0 -98304.0)) - (set! (-> self rotxvv) (analog-input (the-as int (-> *cpad-list* cpads 0 lefty)) 128.0 32.0 110.0 -65536.0)) + ;; og:preserve-this respect the camera settings + (set! (-> self rotyvv) (analog-input-horizontal-first (the-as int (-> *cpad-list* cpads 0 leftx)) 128.0 32.0 110.0 -98304.0)) + (set! (-> self rotxvv) (analog-input-vertical-first (the-as int (-> *cpad-list* cpads 0 lefty)) 128.0 32.0 110.0 -65536.0)) ) (+! (-> self rotyv) (* (-> self rotyvv) (seconds-per-frame))) (seek! (-> self rotyv) 0.0 (* 32768.0 (seconds-per-frame))) @@ -1457,11 +1458,7 @@ (sound-stop (-> self sound-id 1)) (sound-stop (-> self sound-id 2)) (set! (-> self focus-status) (focus-status disable ignore inactive)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.8)) - (suspend) - ) - ) + (suspend-for (seconds 0.8)) (send-event (handle->process (-> self rider)) 'attack @@ -1979,6 +1976,7 @@ ) (defmethod deactivate ((this base-turret)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (if (valid? (-> this hud) (the-as type #f) "" #t 0) (send-event (handle->process (-> this hud)) 'hide-and-die) ) @@ -1992,11 +1990,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this base-turret) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (turret-init! this arg0 (the-as matrix #f)) (go (method-of-object this idle)) (none) diff --git a/goal_src/jak2/engine/target/target.gc b/goal_src/jak2/engine/target/target.gc index b333343b9d..3b38f56391 100644 --- a/goal_src/jak2/engine/target/target.gc +++ b/goal_src/jak2/engine/target/target.gc @@ -1014,7 +1014,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (let ((t9-0 target-falling-trans) diff --git a/goal_src/jak2/engine/target/target2.gc b/goal_src/jak2/engine/target/target2.gc index c8d777a003..13f2b540ac 100644 --- a/goal_src/jak2/engine/target/target2.gc +++ b/goal_src/jak2/engine/target/target2.gc @@ -50,13 +50,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.3)) - (suspend) - (ja :num! (seek! (ja-aframe 19.0 0) 0.05)) - (suspend) - ) - ) + (suspend-for (seconds 0.3) (suspend) (ja :num! (seek! (ja-aframe 19.0 0) 0.05))) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! jakb-painful-land-ja :num! (seek!) :frame-num (ja-aframe 40.0 0)) (until (ja-done? 0) @@ -1202,12 +1196,7 @@ (until #f (let ((s5-0 (rand-vu-int-range 30 600))) (ja :group! jakb-wall-hide-head-ja) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 s5-0) - (gp-0) - (suspend) - ) - ) + (suspend-for s5-0 (gp-0)) ) (let ((f30-0 (rand-vu-float-range 0.5 1.5))) (cond @@ -1244,13 +1233,8 @@ (suspend) (ja :num! (seek! max f30-0)) ) - (let ((s5-2 (rand-vu-int-range 60 300)) - (s4-2 (current-time)) - ) - (until (time-elapsed? s4-2 s5-2) - (gp-0) - (suspend) - ) + (let ((s5-2 (rand-vu-int-range 60 300))) + (suspend-for s5-2 (gp-0)) ) (ja-no-eval :group! jakb-wall-hide-head-left-ja :num! (seek! 0.0 f30-0) :frame-num max) (until (ja-done? 0) @@ -1266,13 +1250,8 @@ (suspend) (ja :num! (seek! 0.0 f30-0)) ) - (let ((s5-3 (rand-vu-int-range 60 300)) - (s4-3 (current-time)) - ) - (until (time-elapsed? s4-3 s5-3) - (gp-0) - (suspend) - ) + (let ((s5-3 (rand-vu-int-range 60 300))) + (suspend-for s5-3 (gp-0)) ) (ja-no-eval :group! jakb-wall-hide-head-right-ja :num! (seek! max f30-0) :frame-num 0.0) (until (ja-done? 0) diff --git a/goal_src/jak2/engine/ui/text-id-h.gc b/goal_src/jak2/engine/ui/text-id-h.gc index 519c880377..4e72aad11e 100644 --- a/goal_src/jak2/engine/ui/text-id-h.gc +++ b/goal_src/jak2/engine/ui/text-id-h.gc @@ -829,7 +829,8 @@ (progress-graphics-msaa-off #x1338) (progress-graphics-display #x1339) (language-name-finnish #x133a) - + (progress-hint-subtitles #x133b) + ;; mod text (pad-triangle #x2000) (pad-circle #x2001) diff --git a/goal_src/jak2/kernel-defs.gc b/goal_src/jak2/kernel-defs.gc index 4700963c8a..a7e14b7c01 100644 --- a/goal_src/jak2/kernel-defs.gc +++ b/goal_src/jak2/kernel-defs.gc @@ -221,8 +221,8 @@ (define-extern pc-get-display-id (function int)) (define-extern pc-set-display-id! (function int none)) (define-extern pc-set-display-mode! (function symbol none)) -(define-extern pc-get-num-resolutions (function int)) -(define-extern pc-get-resolution (function int (pointer int64) (pointer int64) none)) +(define-extern pc-get-num-resolutions (function symbol int)) +(define-extern pc-get-resolution (function int symbol (pointer int64) (pointer int64) none)) (define-extern pc-is-supported-resolution? (function int int symbol)) (define-extern pc-set-frame-rate (function int none)) @@ -240,7 +240,7 @@ (define-extern pc-init-autosplitter-struct (function none)) ;;main music start -(define-extern play-sound-file (function string int none)) +(define-extern play-sound-file (function string int symbol)) (define-extern play-main-music (function string int none)) (define-extern pause-main-music (function none)) (define-extern stop-main-music (function none)) @@ -248,8 +248,8 @@ (define-extern main-music-volume (function int none)) ;;main music end -(define-extern play-sound-file (function string int none)) -(define-extern stop-sound-file (function none)) +(define-extern stop-sound-file (function string none)) +(define-extern stop-all-sounds (function none)) (define-extern pc-filepath-exists? (function string symbol)) (define-extern pc-mkdir-file-path (function string none)) diff --git a/goal_src/jak2/kernel/gkernel-h.gc b/goal_src/jak2/kernel/gkernel-h.gc index 75bae685cd..6fa57f50ff 100644 --- a/goal_src/jak2/kernel/gkernel-h.gc +++ b/goal_src/jak2/kernel/gkernel-h.gc @@ -724,3 +724,6 @@ (defmacro time-elapsed? (time duration) `(>= (- (current-time) ,time) ,duration) ) + +(defmacro suspend-for (time &rest body) + `(let ((time (current-time))) (until (time-elapsed? time ,time) ,@body (suspend)))) \ No newline at end of file diff --git a/goal_src/jak2/kernel/gstate.gc b/goal_src/jak2/kernel/gstate.gc index 811b74ce6c..db94c4fb61 100644 --- a/goal_src/jak2/kernel/gstate.gc +++ b/goal_src/jak2/kernel/gstate.gc @@ -252,6 +252,12 @@ It type checks the arguments for the entry function. ) ) +(defmacro call-parent-state-handler (handler &key (type (function none)) &rest args) + "Call the parent handler for this state." + `(let ((handler (-> (find-parent-state) ,handler))) + (if handler ((the ,type handler) ,@args)) + ) + ) (defmacro behavior (bindings &rest body) "Define an anonymous behavior for a process state. This may only be used inside a defstate!" diff --git a/goal_src/jak2/levels/atoll/atoll-obs.gc b/goal_src/jak2/levels/atoll/atoll-obs.gc index 6f309b865b..f1b0e376c0 100644 --- a/goal_src/jak2/levels/atoll/atoll-obs.gc +++ b/goal_src/jak2/levels/atoll/atoll-obs.gc @@ -112,6 +112,7 @@ ) (defmethod deactivate ((this piston)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (-> this looping-id)) ((method-of-type process-focusable deactivate) this) (none) @@ -120,11 +121,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this piston) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-64 res-tag)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) @@ -281,11 +282,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this turbine) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag) (sv-32 res-tag)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) @@ -433,11 +434,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this liftcat) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag) (sv-32 res-tag)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) @@ -556,42 +557,24 @@ This commonly includes things such as: ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (the int (-> self cycle-offset))) - (suspend) - ) - ) + (suspend-for (the int (-> self cycle-offset))) (until #f - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (the int (-> self cycle-time))) - (suspend) - ) - ) + (suspend-for (the int (-> self cycle-time))) (activate! (-> self smush) -1.0 60 225 1.0 1.0 (-> self clock)) (sound-play "rot-pipe-wiggle" :position (-> self root trans)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.75)) - (set! (-> self shudder-angle) (* 364.0889 (update! (-> self smush)))) - (suspend) - ) - ) + (suspend-for (seconds 0.75) (set! (-> self shudder-angle) (* 364.0889 (update! (-> self smush))))) (set! (-> self shudder-angle) 0.0) (set-zero! (-> self smush)) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (sound-play "rot-pipe-turn" :position (-> self root trans)) (let* ((f0-7 2.0) (f30-1 (* 16384.0 f0-7)) - (gp-6 (current-time)) ) - (until (time-elapsed? gp-6 (seconds 0.5)) + (suspend-for + (seconds 0.5) (set! (-> self rot-angle) (the float (sar (shl (the int (+ (-> self rot-angle) (* f30-1 (seconds-per-frame)))) 48) 48)) ) - (suspend) ) ) (let ((v1-42 #x4000)) @@ -615,11 +598,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this atollrotpipe) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) @@ -780,32 +763,34 @@ This commonly includes things such as: ) (defmethod run-logic? ((this slider)) + "Should this process be run? Checked by execute-process-tree." #t ) (defmethod deactivate ((this slider)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (the-as sound-id (-> this sound-id))) (call-parent-method this) (none) ) -(defmethod relocate ((this slider) (arg0 int)) +(defmethod relocate ((this slider) (offset int)) (dotimes (v1-0 4) (if (nonzero? (-> this l-bolts v1-0)) - (&+! (-> this l-bolts v1-0) arg0) + (&+! (-> this l-bolts v1-0) offset) ) ) - (call-parent-method this arg0) + (call-parent-method this offset) ) ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this slider) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((v1-2 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) (set! (-> v1-2 prim-core collide-as) (collide-spec obstacle)) @@ -963,11 +948,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this atoll-windmill) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (logior! (-> this mask) (process-mask ambient)) (let ((a1-1 (new 'stack-no-clear 'sync-info-params))) (let ((v1-2 0)) @@ -1032,11 +1017,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this atoll-valve) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (logior! (-> this mask) (process-mask ambient)) (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) @@ -1073,11 +1058,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this atoll-hatch) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (logior! (-> this mask) (process-mask ambient)) (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) @@ -1140,11 +1125,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this atoll-hellcat) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((v1-2 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) (set! (-> v1-2 prim-core collide-as) (collide-spec obstacle)) @@ -1201,11 +1186,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this atoll-mar-symbol) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton diff --git a/goal_src/jak2/levels/atoll/juicer.gc b/goal_src/jak2/levels/atoll/juicer.gc index ba3df807a1..50057f47b7 100644 --- a/goal_src/jak2/levels/atoll/juicer.gc +++ b/goal_src/jak2/levels/atoll/juicer.gc @@ -334,13 +334,13 @@ ) ;; WARN: Return type mismatch projectile vs juicer-shot. -(defmethod relocate ((this juicer-shot) (arg0 int)) +(defmethod relocate ((this juicer-shot) (offset int)) (dotimes (v1-0 5) (if (nonzero? (-> this lightning v1-0)) - (&+! (-> this lightning v1-0) arg0) + (&+! (-> this lightning v1-0) offset) ) ) - (the-as juicer-shot ((method-of-type projectile relocate) this arg0)) + (the-as juicer-shot ((method-of-type projectile relocate) this offset)) ) (defmethod init-proj-settings! ((this juicer-shot)) @@ -679,9 +679,9 @@ (defmethod common-post ((this juicer)) "Does a lot of various things relating to interacting with the target -- tracks when the enemy was last drawn -- looks at the target and handles attacking -@TODO Not extremely well understood yet" + - tracks when the enemy was last drawn + - looks at the target and handles attacking + @TODO Not extremely well understood yet" (let ((t9-0 (method-of-type nav-enemy common-post))) (t9-0 this) ) @@ -713,7 +713,7 @@ (defmethod general-event-handler ((this juicer) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (case arg2 (('hit-flinch) (cond @@ -1275,57 +1275,56 @@ (s5-0 (+ (-> v1-29 attack-id) 1)) ) (set! (-> v1-29 attack-id) s5-0) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 (seconds 0.25)) - (ja-no-eval :group! juicer-attack0-ja :num! (seek!) :frame-num 0.0) - (until (ja-done? 0) - (let ((s3-0 (handle->process (-> self focus handle)))) - (when s3-0 - (when (< 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable s3-0) 0))) - (fire-projectile self (the-as process-focusable s3-0) s5-0) - (current-time) - (if (not gp-0) - (set! gp-0 #t) - ) - ) - ) - ) - (if (and (logtest? (-> self enemy-flags) (enemy-flag victory)) (-> self enemy-info use-victory)) - (go-virtual victory) + (suspend-for + (seconds 0.25) + (ja-no-eval :group! juicer-attack0-ja :num! (seek!) :frame-num 0.0) + (until (ja-done? 0) + (let ((s3-0 (handle->process (-> self focus handle)))) + (when s3-0 + (when (< 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable s3-0) 0))) + (fire-projectile self (the-as process-focusable s3-0) s5-0) + (current-time) + (if (not gp-0) + (set! gp-0 #t) + ) ) - (b! - (not (and (-> self using-turn-anim) (let ((v1-73 (ja-group))) - (not (and v1-73 (= v1-73 juicer-attack-turn-ja))) - ) - ) - ) - cfg-31 - :delay (empty-form) - ) - (ja-channel-push! 1 (seconds 0.05)) - (ja :group! juicer-attack-turn-ja) - (b! #t cfg-42 :delay (nop!)) - (label cfg-31) - (when (and (not (-> self using-turn-anim)) (let ((v1-84 (ja-group))) - (not (and v1-84 (= v1-84 juicer-attack0-ja))) - ) - ) - (ja-channel-push! 1 (seconds 0.05)) - (ja :group! juicer-attack0-ja) ) - (label cfg-42) - (suspend) - (ja :num! (seek!)) ) - (send-event (handle->process (-> self current-projectile)) 'die) - (let ((a0-37 (handle->process (-> self focus handle)))) - (when a0-37 - (if (>= 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable a0-37) 0))) - (go-virtual circling) - ) + (if (and (logtest? (-> self enemy-flags) (enemy-flag victory)) (-> self enemy-info use-victory)) + (go-virtual victory) ) + (b! + (not (and (-> self using-turn-anim) (let ((v1-73 (ja-group))) + (not (and v1-73 (= v1-73 juicer-attack-turn-ja))) + ) + ) + ) + cfg-31 + :delay (empty-form) ) + (ja-channel-push! 1 (seconds 0.05)) + (ja :group! juicer-attack-turn-ja) + (b! #t cfg-42 :delay (nop!)) + (label cfg-31) + (when (and (not (-> self using-turn-anim)) (let ((v1-84 (ja-group))) + (not (and v1-84 (= v1-84 juicer-attack0-ja))) + ) + ) + (ja-channel-push! 1 (seconds 0.05)) + (ja :group! juicer-attack0-ja) + ) + (label cfg-42) (suspend) + (ja :num! (seek!)) + ) + (empty-form) + (send-event (handle->process (-> self current-projectile)) 'die) + (let ((a0-37 (handle->process (-> self focus handle)))) + (when a0-37 + (if (>= 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable a0-37) 0))) + (go-virtual circling) + ) + ) ) ) ) @@ -1730,14 +1729,14 @@ (none) ) -(defmethod relocate ((this juicer) (arg0 int)) +(defmethod relocate ((this juicer) (offset int)) (if (nonzero? (-> this intro-path)) - (&+! (-> this intro-path) arg0) + (&+! (-> this intro-path) offset) ) (if (nonzero? (-> this joint)) - (&+! (-> this joint) arg0) + (&+! (-> this joint) offset) ) - (call-parent-method this arg0) + (call-parent-method this offset) ) (defmethod init-enemy! ((this juicer)) diff --git a/goal_src/jak2/levels/castle/castle-obs.gc b/goal_src/jak2/levels/castle/castle-obs.gc index 4ce33c0385..1a6e6a8b28 100644 --- a/goal_src/jak2/levels/castle/castle-obs.gc +++ b/goal_src/jak2/levels/castle/castle-obs.gc @@ -39,11 +39,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this cas-conveyor) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) (reset-root! this) (set! (-> this path) (new 'process 'path-control this 'path 0.0 (the-as entity #f) #f)) @@ -74,6 +74,7 @@ This commonly includes things such as: ) (defmethod deactivate ((this cas-conveyor)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (-> this sound-id)) (call-parent-method this) (none) @@ -344,11 +345,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this cas-conveyor-switch) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((v1-2 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) @@ -479,11 +480,7 @@ This commonly includes things such as: (sound-play "lightning-node") (suspend) (logior! (-> self entity extra perm status) (entity-perm-status dead)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 4)) - (suspend) - ) - ) + (suspend-for (seconds 4)) (cleanup-for-death self) ) ) @@ -624,11 +621,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this cas-electric-fence) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((v1-2 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) (set! (-> v1-2 prim-core collide-as) (collide-spec obstacle)) @@ -803,10 +800,10 @@ This commonly includes things such as: (defmethod move-between-points ((this cas-elevator) (arg0 vector) (arg1 float) (arg2 float)) "Move between two points on the elevator's path -@param vec TODO not sure -@param point-a The first point fetched from the elevator's path -@param point-b The second point fetched from the path -@see [[path-control]] and [[elevator]]" + @param vec TODO not sure + @param point-a The first point fetched from the elevator's path + @param point-b The second point fetched from the path + @see [[path-control]] and [[elevator]]" (let ((s5-0 (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) arg1 'interp)) (a0-3 (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) arg2 'interp)) (v1-3 (-> this root trans)) @@ -914,6 +911,7 @@ This commonly includes things such as: ) (defmethod deactivate ((this cas-elevator)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (-> this sound-id)) (call-parent-method this) (none) @@ -921,7 +919,7 @@ This commonly includes things such as: (defmethod init-plat! ((this cas-elevator)) "Does any necessary initial platform setup. -For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." + For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." (set! (-> this sound-id) (new-sound-id)) (cas-elevator-method-49 this) (none) @@ -1229,11 +1227,11 @@ For example for an elevator pre-compute the distance between the first and last ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this cas-rot-bridge) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 5) 0))) (set! (-> s4-0 total-prims) (the-as uint 6)) @@ -1456,11 +1454,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this cas-switch) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 2) 0))) @@ -1649,11 +1647,7 @@ This commonly includes things such as: (sound-play "trapdoor") (suspend) (ja-channel-set! 0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event self 'death-end) (while (-> self child) (suspend) @@ -1666,11 +1660,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this cas-trapdoor) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((v1-2 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) (set! (-> v1-2 prim-core collide-as) (collide-spec obstacle)) @@ -1761,11 +1755,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this cas-chain-plat) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((v1-2 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) (set! (-> v1-2 prim-core collide-as) (collide-spec obstacle)) @@ -1875,11 +1869,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this cas-rot-blade) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 2) 0))) (set! (-> s4-0 total-prims) (the-as uint 3)) @@ -1946,6 +1940,7 @@ This commonly includes things such as: ) (defmethod deactivate ((this cas-rot-blade)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (-> this sound-id)) (call-parent-method this) (none) @@ -1982,11 +1977,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this cas-flag-a) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -2029,11 +2024,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this cas-flag-b) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -2136,11 +2131,7 @@ This commonly includes things such as: (suspend) (ja :num! (seek!)) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (while (or (= (-> self spawn-total) -1) (< (-> self spawn-count-total) (-> self spawn-total))) (when (and (< (-> self player-dist) (+ 81920.0 (-> self notice-dist))) (and (< (-> self spawn-count) (-> self spawn-max)) @@ -2176,18 +2167,10 @@ This commonly includes things such as: ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (the int (* 300.0 (rand-vu-float-range 0.5 1.0)))) - (suspend) - ) - ) + (suspend-for (the int (* 300.0 (rand-vu-float-range 0.5 1.0)))) ) (while (> (-> self spawn-count) 0) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.43)) - (suspend) - ) - ) + (suspend-for (seconds 0.43)) ) (process-entity-status! self (entity-perm-status subtask-complete) #t) (cond @@ -2205,11 +2188,7 @@ This commonly includes things such as: (set-setting! 'entity-name a3-4 0.0 0) ) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (dotimes (gp-6 (-> self actor-group 1 length)) (let ((a1-17 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-17 from) (process->ppointer self)) @@ -2239,11 +2218,7 @@ This commonly includes things such as: (set-setting! 'entity-name a3-6 0.0 0) ) ) - (let ((gp-7 (current-time))) - (until (time-elapsed? gp-7 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (let ((gp-8 (-> self actor-group 0))) (dotimes (s5-3 (-> gp-8 length)) (let ((a1-21 (new 'stack-no-clear 'event-message-block))) @@ -2273,11 +2248,7 @@ This commonly includes things such as: (suspend) (ja :num! (seek! 0.0)) ) - (let ((gp-10 (current-time))) - (until (time-elapsed? gp-10 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (remove-setting! 'entity-name) (until (process-release? *target*) (suspend) @@ -2313,11 +2284,7 @@ This commonly includes things such as: (label cfg-14) (not v1-28) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.51)) - (suspend) - ) - ) + (suspend-for (seconds 0.51)) ) (until (process-grab? *target* #f) (suspend) @@ -2327,11 +2294,7 @@ This commonly includes things such as: (set-setting! 'entity-name a3-2 0.0 0) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (task-node-close! (game-task-node castle-break-in-resolution)) (let ((a1-7 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-7 from) (process->ppointer self)) @@ -2367,11 +2330,7 @@ This commonly includes things such as: ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 2.5)) - (suspend) - ) - ) + (suspend-for (seconds 2.5)) (remove-setting! 'entity-name) (until (process-release? *target*) (suspend) @@ -2383,11 +2342,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this cas-robot-door) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" ;; og:preserve-this added (stack-size-set! (-> this main-thread) 512) (local-vars (sv-16 res-tag) (sv-32 res-tag)) @@ -2535,11 +2494,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this lightning-ball) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((v1-2 (new 'process 'collide-shape-prim-sphere s4-0 (the-as uint 0)))) (set! (-> v1-2 prim-core collide-as) (collide-spec obstacle)) diff --git a/goal_src/jak2/levels/castle/pad/caspad-obs.gc b/goal_src/jak2/levels/castle/pad/caspad-obs.gc index 4933ee6a69..a6fb2d2e9b 100644 --- a/goal_src/jak2/levels/castle/pad/caspad-obs.gc +++ b/goal_src/jak2/levels/castle/pad/caspad-obs.gc @@ -28,10 +28,10 @@ (defmethod move-between-points ((this cpad-elevator) (vec vector) (point-a float) (point-b float)) "Move between two points on the elevator's path -@param vec TODO not sure -@param point-a The first point fetched from the elevator's path -@param point-b The second point fetched from the path -@see [[path-control]] and [[elevator]]" + @param vec TODO not sure + @param point-a The first point fetched from the elevator's path + @param point-b The second point fetched from the path + @see [[path-control]] and [[elevator]]" (let ((path-point-a (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) point-a 'interp)) (path-point-b (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) point-b 'interp)) (elevator-trans (-> this root trans)) @@ -66,7 +66,7 @@ (defmethod configure-collision ((this cpad-elevator) (collide-with-jak? symbol)) "Appropriately sets the collision on the elevator -@param collide-with-jak? If set, the elevator will collide with Jak" + @param collide-with-jak? If set, the elevator will collide with Jak" (let ((prim (-> (the-as collide-shape-prim-group (-> this root root-prim)) child 1))) (cond (collide-with-jak? @@ -106,11 +106,7 @@ ) ) :code (behavior () - (let ((frame-counter (current-time))) - (until (time-elapsed? frame-counter (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (logior! (-> self elevator-status) (elevator-status waiting-to-ascend)) (until #f (sound-play "dig-elevate" :id (-> self sound-id)) @@ -147,6 +143,7 @@ ) (defmethod deactivate ((this cpad-elevator)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (-> this sound-id)) (call-parent-method this) (none) @@ -164,7 +161,7 @@ ;; WARN: Return type mismatch sound-id vs none. (defmethod init-plat! ((this cpad-elevator)) "Does any necessary initial platform setup. -For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." + For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." (let ((last-path-index (+ (-> this path curve num-cverts) -1))) (calc-dist-between-points! this 0 last-path-index) (calc-dist-between-points! this last-path-index 0) diff --git a/goal_src/jak2/levels/castle/pad/castle-tasks.gc b/goal_src/jak2/levels/castle/pad/castle-tasks.gc index 68b3f5fcd7..dc47e3c2c5 100644 --- a/goal_src/jak2/levels/castle/pad/castle-tasks.gc +++ b/goal_src/jak2/levels/castle/pad/castle-tasks.gc @@ -23,11 +23,7 @@ (until #f (when (< (vector-vector-distance (target-pos 0) (-> self info end-sphere)) (-> self info end-sphere r)) (send-event (handle->process (-> self arrow)) 'leave) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.007)) - (suspend) - ) - ) + (suspend-for (seconds 0.007)) (go-virtual complete) ) (suspend) diff --git a/goal_src/jak2/levels/castle/roboguard-level.gc b/goal_src/jak2/levels/castle/roboguard-level.gc index 7f6fb9959b..428feb2271 100644 --- a/goal_src/jak2/levels/castle/roboguard-level.gc +++ b/goal_src/jak2/levels/castle/roboguard-level.gc @@ -332,11 +332,7 @@ (defstate ambush (roboguard-level) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (logand! (-> self flags) -9) (logior! (-> self flags) 4) (logior! (-> self nav flags) (nav-control-flag output-sphere-hash)) @@ -398,11 +394,7 @@ (defstate idle (roboguard-level) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (roboguard-level-method-185 self (the-as symbol 0)) ) :code (behavior () @@ -468,11 +460,7 @@ (defstate stare (roboguard-level) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (roboguard-level-method-185 self (the-as symbol 0)) ) :code (behavior () @@ -731,11 +719,7 @@ (defstate die (roboguard-level) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (roboguard-level-method-185 self (the-as symbol 0)) ) :code (behavior () @@ -935,7 +919,7 @@ (defmethod general-event-handler ((this roboguard-level) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (case arg2 (('attack) (cond diff --git a/goal_src/jak2/levels/city/burning-bush/ctywide-bbush.gc b/goal_src/jak2/levels/city/burning-bush/ctywide-bbush.gc index 24a8d0123f..859cae9221 100644 --- a/goal_src/jak2/levels/city/burning-bush/ctywide-bbush.gc +++ b/goal_src/jak2/levels/city/burning-bush/ctywide-bbush.gc @@ -1740,11 +1740,11 @@ ;; WARN: Return type mismatch entity-perm-status vs none. (defmethod init-from-entity! ((this bush-collect) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (process-entity-status! this (entity-perm-status dead) #t) (none) ) @@ -2901,11 +2901,7 @@ This commonly includes things such as: ) (send-event *camera* 'teleport-to-transformq gp-0) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) (remove-setting! 'minimap) (set! (-> *ACTOR-bank* birth-max) 1000) (persist-with-delay *setting-control* 'interp-time (seconds 0.05) 'interp-time 'abs 0.0 0) diff --git a/goal_src/jak2/levels/city/common/pilot-states.gc b/goal_src/jak2/levels/city/common/pilot-states.gc index d1e5237c02..b8e3a81ddd 100644 --- a/goal_src/jak2/levels/city/common/pilot-states.gc +++ b/goal_src/jak2/levels/city/common/pilot-states.gc @@ -823,11 +823,7 @@ (logior! (-> self focus-status) (focus-status dead)) (case arg0 (('melt 'grenade 'explode) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (case arg0 (('dark-eco-pool) (sound-play "death-darkeco") @@ -950,11 +946,7 @@ ) 0 (ja-channel-set! 0) - (let ((s5-7 (current-time))) - (until (time-elapsed? s5-7 (seconds 1.8)) - (suspend) - ) - ) + (suspend-for (seconds 1.8)) ) (('endlessfall) (sound-play "death-fall") @@ -983,11 +975,7 @@ ) ) ) - (let ((s5-9 (current-time))) - (until (time-elapsed? s5-9 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) ) (('bot) (set! (-> self trans-hook) #f) diff --git a/goal_src/jak2/levels/city/ctywide-obs.gc b/goal_src/jak2/levels/city/ctywide-obs.gc index b9e88cc724..c9de9fd6d0 100644 --- a/goal_src/jak2/levels/city/ctywide-obs.gc +++ b/goal_src/jak2/levels/city/ctywide-obs.gc @@ -530,11 +530,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this security-wall) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (ctywide-entity-hack) (set! (-> this breach) #f) (set! (-> this pass) (res-lump-value arg0 'pickup-type int :time -1000000000.0)) @@ -985,11 +985,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this fruit-stand) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (fruit-stand-method-28 this) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -1523,16 +1523,12 @@ This commonly includes things such as: ) ) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (let ((a1-1 (new 'stack-no-clear 'vector))) - (set! (-> a1-1 quad) (-> self root trans quad)) - (+! (-> a1-1 y) 10240.0) - (spawn (-> self part) a1-1) - ) - (suspend) - ) - ) + (suspend-for (seconds 2) (let ((a1-1 (new 'stack-no-clear 'vector))) + (set! (-> a1-1 quad) (-> self root trans quad)) + (+! (-> a1-1 y) 10240.0) + (spawn (-> self part) a1-1) + ) + ) (while (not (-> self button-down?)) (suspend) ) @@ -1567,11 +1563,7 @@ This commonly includes things such as: (suspend) (ja :num! (seek! 32.0 0.5)) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) ) ) (set! (-> self root root-prim specific 0) (-> self root root-prim specific 1)) @@ -1715,11 +1707,7 @@ This commonly includes things such as: (suspend) (ja :num! (seek! (ja-aframe 32.0 0))) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 5)) - (suspend) - ) - ) + (suspend-for (seconds 5)) (set! (-> self root root-prim specific 0) (-> self root root-prim specific 1)) (setup-masks (-> self draw) 2 0) (go-virtual idle) @@ -2009,17 +1997,17 @@ This commonly includes things such as: ) ) -(defmethod relocate ((this cty-guard-turret) (arg0 int)) +(defmethod relocate ((this cty-guard-turret) (offset int)) (if (nonzero? (-> this jm-turret)) - (&+! (-> this jm-turret) arg0) + (&+! (-> this jm-turret) offset) ) (if (nonzero? (-> this jm-gunsL)) - (&+! (-> this jm-gunsL) arg0) + (&+! (-> this jm-gunsL) offset) ) (if (nonzero? (-> this jm-gunsR)) - (&+! (-> this jm-gunsR) arg0) + (&+! (-> this jm-gunsR) offset) ) - (call-parent-method this arg0) + (call-parent-method this offset) ) (defmethod cty-guard-turret-method-32 ((this cty-guard-turret)) @@ -2103,11 +2091,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this cty-guard-turret) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (v1-23 handle)) (with-pp (cty-guard-turret-method-32 this) @@ -2315,11 +2303,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this parking-spot) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (set! (-> this minimap) #f) (set! (-> this vehicle) (the-as handle #f)) @@ -2834,11 +2822,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this propa) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (propa-method-29 this) (process-drawable-from-entity! this arg0) (ctywide-entity-hack) @@ -2871,6 +2859,7 @@ This commonly includes things such as: ) (defmethod run-logic? ((this baron-statue)) + "Should this process be run? Checked by execute-process-tree." #t ) @@ -2882,11 +2871,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this baron-statue) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -3770,20 +3759,21 @@ This commonly includes things such as: ) ;; WARN: Return type mismatch process-focusable vs burning-bush. -(defmethod relocate ((this burning-bush) (arg0 int)) +(defmethod relocate ((this burning-bush) (offset int)) (if (nonzero? (-> this task)) - (&+! (-> this task) arg0) + (&+! (-> this task) offset) ) (if (nonzero? (-> this part-off)) - (&+! (-> this part-off) arg0) + (&+! (-> this part-off) offset) ) (if (nonzero? (-> this part-alert)) - (&+! (-> this part-alert) arg0) + (&+! (-> this part-alert) offset) ) - (the-as burning-bush ((method-of-type process-focusable relocate) this arg0)) + (the-as burning-bush ((method-of-type process-focusable relocate) this offset)) ) (defmethod run-logic? ((this burning-bush)) + "Should this process be run? Checked by execute-process-tree." (or (not (logtest? (-> this mask) (process-mask actor-pause))) (or (and (nonzero? (-> this draw)) (logtest? (-> this draw status) (draw-control-status on-screen)) @@ -3800,11 +3790,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this burning-bush) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (burning-bush-method-30 this) (process-drawable-from-entity! this arg0) (ctywide-entity-hack) @@ -3849,11 +3839,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this barons-ship-lores) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (when (demo?) (process-entity-status! this (entity-perm-status dead) #t) (go empty-state) @@ -3896,17 +3886,17 @@ This commonly includes things such as: (none) ) -(defmethod relocate ((this barons-ship-lores) (arg0 int)) +(defmethod relocate ((this barons-ship-lores) (offset int)) (if (nonzero? (-> this paths 0)) - (&+! (-> this paths 0) arg0) + (&+! (-> this paths 0) offset) ) (if (nonzero? (-> this paths 1)) - (&+! (-> this paths 1) arg0) + (&+! (-> this paths 1) offset) ) (if (nonzero? (-> this paths 2)) - (&+! (-> this paths 2) arg0) + (&+! (-> this paths 2) offset) ) - (call-parent-method this arg0) + (call-parent-method this offset) ) (defstate idle (barons-ship-lores) @@ -4093,11 +4083,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this lurker-pipe-lid) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (lurker-pipe-lid-method-28 this) (process-drawable-from-entity! this arg0) (ctywide-entity-hack) @@ -4251,11 +4241,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this ctyn-lamp) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (ctyn-lamp-method-29 this) (process-drawable-from-entity! this arg0) (initialize-skeleton diff --git a/goal_src/jak2/levels/city/ctywide-tasks.gc b/goal_src/jak2/levels/city/ctywide-tasks.gc index 9798b84bc5..e54ebf22f1 100644 --- a/goal_src/jak2/levels/city/ctywide-tasks.gc +++ b/goal_src/jak2/levels/city/ctywide-tasks.gc @@ -181,11 +181,7 @@ (talker-spawn-func (-> *talker-speech* 38) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self sound-id 0)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while (or (not *target*) (focus-test? *target* dead teleporting)) (suspend) ) @@ -234,11 +230,7 @@ (talker-spawn-func (-> *talker-speech* 31) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self sound-id 0)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while (or (not *target*) (focus-test? *target* dead teleporting)) (suspend) ) @@ -246,11 +238,7 @@ (talker-spawn-func (-> *talker-speech* 35) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self sound-id 0)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while (or (not *target*) (focus-test? *target* dead teleporting)) (suspend) ) @@ -271,11 +259,7 @@ ) (wait-for-speech-end (-> self sound-id 0)) (set! (-> self sub-state) (the-as uint 2)) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (go-virtual complete) (none) ) @@ -348,11 +332,7 @@ (talker-spawn-func (-> *talker-speech* 35) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self sound-id 0)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (set! (-> self sound-id 0) (talker-spawn-func (-> *talker-speech* 36) *entity-pool* (target-pos 0) (the-as region #f)) ) @@ -366,11 +346,7 @@ (talker-spawn-func (-> *talker-speech* 37) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self sound-id 0)) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) (go-virtual complete) (none) ) diff --git a/goal_src/jak2/levels/city/market/ctymark-obs.gc b/goal_src/jak2/levels/city/market/ctymark-obs.gc index b5cc1a642a..ee500bd237 100644 --- a/goal_src/jak2/levels/city/market/ctymark-obs.gc +++ b/goal_src/jak2/levels/city/market/ctymark-obs.gc @@ -1042,11 +1042,7 @@ :to self ) (process-entity-status! self (entity-perm-status dead) #t) - (let ((frame (current-time))) - (until (time-elapsed? frame (seconds 5)) - (suspend) - ) - ) + (suspend-for (seconds 5)) ) ) @@ -1070,11 +1066,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this market-basket-a) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((cshape (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((prim-mesh (new 'process 'collide-shape-prim-mesh cshape (the-as uint 0) (the-as uint 0)))) (set! (-> prim-mesh prim-core collide-as) (collide-spec crate)) @@ -1146,11 +1142,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this market-basket-b) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((cshape (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((prim-mesh (new 'process 'collide-shape-prim-mesh cshape (the-as uint 0) (the-as uint 0)))) (set! (-> prim-mesh prim-core collide-as) (collide-spec crate)) @@ -1222,11 +1218,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this market-crate) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((cshape (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((prim-mesh (new 'process 'collide-shape-prim-mesh cshape (the-as uint 0) (the-as uint 0)))) (set! (-> prim-mesh prim-core collide-as) (collide-spec crate)) @@ -1298,11 +1294,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this market-sack-a) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((cshape (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((prim-mesh (new 'process 'collide-shape-prim-mesh cshape (the-as uint 0) (the-as uint 0)))) (set! (-> prim-mesh prim-core collide-as) (collide-spec crate)) @@ -1374,11 +1370,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this market-sack-b) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((cshape (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((prim-mesh (new 'process 'collide-shape-prim-mesh cshape (the-as uint 0) (the-as uint 0)))) (set! (-> prim-mesh prim-core collide-as) (collide-spec crate)) diff --git a/goal_src/jak2/levels/city/onintent/onin-game.gc b/goal_src/jak2/levels/city/onintent/onin-game.gc index 7cb4373fd7..81e7e3655d 100644 --- a/goal_src/jak2/levels/city/onintent/onin-game.gc +++ b/goal_src/jak2/levels/city/onintent/onin-game.gc @@ -1836,11 +1836,7 @@ (-> gp-0 ppointer) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (go-virtual fall) ) ) @@ -2536,11 +2532,7 @@ ) :code (behavior ((arg0 symbol)) (ja-channel-set! 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (talker-spawn-func (-> *talker-speech* 145) *entity-pool* (target-pos 0) (the-as region #f)) (sleep-code) ) @@ -2662,11 +2654,7 @@ (while (nonzero? (get-status *gui-control* s5-1)) (suspend) ) - (let ((s5-3 (current-time))) - (until (time-elapsed? s5-3 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (set-blackout-frames (seconds 0.1)) (send-event (handle->process gp-4) 'complete) ) diff --git a/goal_src/jak2/levels/city/port/portrun/portrun.gc b/goal_src/jak2/levels/city/port/portrun/portrun.gc index 8b47a3f200..09a14cd016 100644 --- a/goal_src/jak2/levels/city/port/portrun/portrun.gc +++ b/goal_src/jak2/levels/city/port/portrun/portrun.gc @@ -968,11 +968,7 @@ 0 ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) (cleanup-for-death self) ) :post (behavior () @@ -1476,11 +1472,7 @@ (defstate die (ctyport-cargo) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (cleanup-for-death self) ) ) @@ -1864,11 +1856,7 @@ ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) (none) ) diff --git a/goal_src/jak2/levels/city/traffic/citizen/metalhead-flitter.gc b/goal_src/jak2/levels/city/traffic/citizen/metalhead-flitter.gc index 4a85053059..b2c51bf45e 100644 --- a/goal_src/jak2/levels/city/traffic/citizen/metalhead-flitter.gc +++ b/goal_src/jak2/levels/city/traffic/citizen/metalhead-flitter.gc @@ -382,18 +382,10 @@ ) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.6)) - (suspend) - ) - ) + (suspend-for (seconds 0.6)) (+! (-> self root trans y) -8192.0) (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) (logclear! (-> self draw status) (draw-control-status no-draw)) (go-virtual ambush-jumping) ) diff --git a/goal_src/jak2/levels/city/traffic/vehicle/vehicle.gc b/goal_src/jak2/levels/city/traffic/vehicle/vehicle.gc index ff1c787920..4343f49f1f 100644 --- a/goal_src/jak2/levels/city/traffic/vehicle/vehicle.gc +++ b/goal_src/jak2/levels/city/traffic/vehicle/vehicle.gc @@ -378,8 +378,8 @@ (let ((s5-0 (new 'stack-no-clear 'vector))) (set! (-> s5-0 x) (analog-input (the-as int (-> *cpad-list* cpads 0 leftx)) 128.0 48.0 110.0 -1.0)) (set! (-> s5-0 w) (analog-input (the-as int (-> *cpad-list* cpads 0 lefty)) 128.0 48.0 110.0 -1.0)) - (set! (-> s5-0 y) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton 6))))) - (set! (-> s5-0 z) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton 7))))) + (set! (-> s5-0 y) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton (abutton-idx x)))))) ;; og:preserve-this abutton indexing + (set! (-> s5-0 z) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton (abutton-idx square)))))) ;; og:preserve-this abutton indexing (vehicle-method-95 this (the-as vector (&-> s5-0 x))) ) (if (or (cpad-hold? 0 l1) (and (logtest? (-> this info flags) 512) (cpad-hold? 0 r1))) diff --git a/goal_src/jak2/levels/common/enemy/flitter.gc b/goal_src/jak2/levels/common/enemy/flitter.gc index cddbf21b14..ddd247f907 100644 --- a/goal_src/jak2/levels/common/enemy/flitter.gc +++ b/goal_src/jak2/levels/common/enemy/flitter.gc @@ -672,11 +672,7 @@ (-> gp-0 ppointer) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.6)) - (suspend) - ) - ) + (suspend-for (seconds 0.6)) (+! (-> self root trans y) -8192.0) (enemy-method-129 self) (let ((a0-5 (handle->process (-> self focus handle)))) @@ -694,11 +690,7 @@ ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) (logclear! (-> self draw status) (draw-control-status no-draw)) (go-virtual ambush-jumping) ) diff --git a/goal_src/jak2/levels/common/enemy/grunt.gc b/goal_src/jak2/levels/common/enemy/grunt.gc index 2bbf7170b5..c65731c059 100644 --- a/goal_src/jak2/levels/common/enemy/grunt.gc +++ b/goal_src/jak2/levels/common/enemy/grunt.gc @@ -331,7 +331,7 @@ (defmethod general-event-handler ((this grunt) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (case arg2 (('hit 'hit-knocked) (logclear! (-> this mask) (process-mask actor-pause)) @@ -450,11 +450,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (let ((v1-6 (-> self root root-prim))) (set! (-> v1-6 prim-core collide-as) (-> self root backup-collide-as)) (set! (-> v1-6 prim-core collide-with) (-> self root backup-collide-with)) @@ -1411,11 +1407,11 @@ ) ;; WARN: Return type mismatch nav-enemy vs grunt. -(defmethod relocate ((this grunt) (arg0 int)) +(defmethod relocate ((this grunt) (offset int)) (if (nonzero? (-> this intro-path)) - (&+! (-> this intro-path) arg0) + (&+! (-> this intro-path) offset) ) - (the-as grunt ((method-of-type nav-enemy relocate) this arg0)) + (the-as grunt ((method-of-type nav-enemy relocate) this offset)) ) (defmethod init-enemy-collision! ((this grunt)) diff --git a/goal_src/jak2/levels/common/enemy/guards/crimson-guard-level.gc b/goal_src/jak2/levels/common/enemy/guards/crimson-guard-level.gc index 8300c8a5d9..3e1580ffe5 100644 --- a/goal_src/jak2/levels/common/enemy/guards/crimson-guard-level.gc +++ b/goal_src/jak2/levels/common/enemy/guards/crimson-guard-level.gc @@ -1105,7 +1105,7 @@ (defmethod general-event-handler ((this crimson-guard-level) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (case arg2 (('event-death) (when (<= (-> this hit-points) 0) @@ -1459,9 +1459,9 @@ ;; WARN: Return type mismatch object vs none. (defmethod common-post ((this crimson-guard-level)) "Does a lot of various things relating to interacting with the target -- tracks when the enemy was last drawn -- looks at the target and handles attacking -@TODO Not extremely well understood yet" + - tracks when the enemy was last drawn + - looks at the target and handles attacking + @TODO Not extremely well understood yet" (let ((t9-0 (method-of-type nav-enemy common-post))) (t9-0 this) ) @@ -2131,11 +2131,7 @@ (suspend) ) (when (logtest? (-> self flags) 4) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (until (crimson-guard-level-method-194 self) (suspend) ) @@ -2705,22 +2701,21 @@ (suspend) (ja :num! (seek! (ja-aframe 12.0 0))) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (the int (* 900.0 (you-suck-scale *game-info* #f)))) - (ja-no-eval :group! crimson-guard-grenade-attack-ja - :num! (seek! (ja-aframe 12.0 0)) - :frame-num (ja-aframe 12.0 0) - ) - (until (ja-done? 0) - (seek-toward-heading-vec! (-> self root) (-> self target-self-xz) 65536.0 (seconds 0.02)) - (suspend) - (ja :num! (seek! (ja-aframe 12.0 0))) - ) - (if (and (< (-> self target-self-xz-dist) 81920.0) (= (-> self focus aware) (enemy-aware enemy-aware-3))) - (go-hostile self) - ) + (suspend-for + (the int (* 900.0 (you-suck-scale *game-info* #f))) + (ja-no-eval :group! crimson-guard-grenade-attack-ja + :num! (seek! (ja-aframe 12.0 0)) + :frame-num (ja-aframe 12.0 0) + ) + (until (ja-done? 0) + (seek-toward-heading-vec! (-> self root) (-> self target-self-xz) 65536.0 (seconds 0.02)) (suspend) + (ja :num! (seek! (ja-aframe 12.0 0))) ) + (empty-form) + (if (and (< (-> self target-self-xz-dist) 81920.0) (= (-> self focus aware) (enemy-aware enemy-aware-3))) + (go-hostile self) + ) ) (crimson-guard-level-method-192 self) (ja-no-eval :group! crimson-guard-grenade-attack-ja @@ -4118,14 +4113,14 @@ (none) ) -(defmethod relocate ((this crimson-guard-level) (arg0 int)) +(defmethod relocate ((this crimson-guard-level) (offset int)) (if (nonzero? (-> this joint)) - (&+! (-> this joint) arg0) + (&+! (-> this joint) offset) ) (if (nonzero? (-> this l-control)) - (&+! (-> this l-control) arg0) + (&+! (-> this l-control) offset) ) - (call-parent-method this arg0) + (call-parent-method this offset) ) ;; WARN: Return type mismatch float vs none. diff --git a/goal_src/jak2/levels/common/enemy/hover/crimson-guard-hover.gc b/goal_src/jak2/levels/common/enemy/hover/crimson-guard-hover.gc index 7e21fe1237..a85a4ecfba 100644 --- a/goal_src/jak2/levels/common/enemy/hover/crimson-guard-hover.gc +++ b/goal_src/jak2/levels/common/enemy/hover/crimson-guard-hover.gc @@ -907,11 +907,7 @@ (defstate knocked (crimson-guard-hover) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) ) @@ -967,11 +963,7 @@ 0 (set! (-> self hit-points) 0) (do-effect (-> self skel effect) 'death-default 0.0 -1) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event self 'death-end) (cleanup-for-death self) ) @@ -981,11 +973,7 @@ (defstate flying-death (crimson-guard-hover) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (let ((gp-0 (get-process *default-dead-pool* part-tracker #x4000))) (when gp-0 (let ((t9-3 (method-of-type part-tracker activate))) @@ -1042,11 +1030,7 @@ (defstate flying-death-explode (crimson-guard-hover) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (sound-play "hover-explode") (let ((gp-1 (get-process *default-dead-pool* part-tracker #x4000))) (when gp-1 @@ -1094,7 +1078,7 @@ (defmethod general-event-handler ((this crimson-guard-hover) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (local-vars (v1-15 enemy-flag)) (case arg2 (('attack-invinc) @@ -1317,9 +1301,9 @@ (defmethod common-post ((this crimson-guard-hover)) "Does a lot of various things relating to interacting with the target -- tracks when the enemy was last drawn -- looks at the target and handles attacking -@TODO Not extremely well understood yet" + - tracks when the enemy was last drawn + - looks at the target and handles attacking + @TODO Not extremely well understood yet" (seek! (-> this gun-x-angle) (-> this gun-x-angle-final) (* 21845.334 (seconds-per-frame))) (let* ((s5-0 (hover-nav-control-method-16 (-> this hover) (new 'stack-no-clear 'vector))) (s4-0 @@ -1693,23 +1677,24 @@ ) ;; WARN: Return type mismatch hover-enemy vs crimson-guard-hover. -(defmethod relocate ((this crimson-guard-hover) (arg0 int)) +(defmethod relocate ((this crimson-guard-hover) (offset int)) (if (nonzero? (-> this gun-jmod)) - (&+! (-> this gun-jmod) arg0) + (&+! (-> this gun-jmod) offset) ) (if (nonzero? (-> this hips-jmod)) - (&+! (-> this hips-jmod) arg0) + (&+! (-> this hips-jmod) offset) ) (if (nonzero? (-> this smoke-part)) - (&+! (-> this smoke-part) arg0) + (&+! (-> this smoke-part) offset) ) (if (nonzero? (-> this engine-part)) - (&+! (-> this engine-part) arg0) + (&+! (-> this engine-part) offset) ) - (the-as crimson-guard-hover ((method-of-type hover-enemy relocate) this arg0)) + (the-as crimson-guard-hover ((method-of-type hover-enemy relocate) this offset)) ) (defmethod deactivate ((this crimson-guard-hover)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (if (nonzero? (-> this smoke-part)) (kill-and-free-particles (-> this smoke-part)) ) diff --git a/goal_src/jak2/levels/common/enemy/hover/hover-enemy-battle.gc b/goal_src/jak2/levels/common/enemy/hover/hover-enemy-battle.gc index ebcff71007..f442d600b3 100644 --- a/goal_src/jak2/levels/common/enemy/hover/hover-enemy-battle.gc +++ b/goal_src/jak2/levels/common/enemy/hover/hover-enemy-battle.gc @@ -180,21 +180,13 @@ (('wait) ) ) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 (-> gp-0 s5-0 time)) - (suspend) - ) - ) + (suspend-for (-> gp-0 s5-0 time)) (while (< (-> gp-0 s5-0 alive-count) (-> self alive-count)) (suspend) ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (go-virtual die) ) :post hover-enemy-manager-post @@ -242,16 +234,16 @@ (none) ) -(defmethod relocate ((this hover-enemy-manager) (arg0 int)) +(defmethod relocate ((this hover-enemy-manager) (offset int)) (when (-> this formation) (if (nonzero? (-> this formation)) - (&+! (-> this formation) arg0) + (&+! (-> this formation) offset) ) ) (if (nonzero? (-> this path)) - (&+! (-> this path) arg0) + (&+! (-> this path) offset) ) - (call-parent-method this arg0) + (call-parent-method this offset) ) (defmethod hover-enemy-manager-init! ((this hover-enemy-manager) (arg0 (array hover-enemy-battle-command))) diff --git a/goal_src/jak2/levels/common/enemy/hover/wasp.gc b/goal_src/jak2/levels/common/enemy/hover/wasp.gc index 63502f9977..3202b17b45 100644 --- a/goal_src/jak2/levels/common/enemy/hover/wasp.gc +++ b/goal_src/jak2/levels/common/enemy/hover/wasp.gc @@ -438,7 +438,7 @@ (defmethod general-event-handler ((this wasp) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (case arg2 (('hit 'hit-knocked) (logclear! (-> this mask) (process-mask actor-pause)) @@ -539,9 +539,9 @@ (defmethod common-post ((this wasp)) "Does a lot of various things relating to interacting with the target -- tracks when the enemy was last drawn -- looks at the target and handles attacking -@TODO Not extremely well understood yet" + - tracks when the enemy was last drawn + - looks at the target and handles attacking + @TODO Not extremely well understood yet" (seek! (-> this gun-x-angle) (-> this gun-x-angle-final) (* 21845.334 (seconds-per-frame))) ((method-of-type hover-enemy common-post) this) (none) @@ -1053,11 +1053,7 @@ 0 (set! (-> self hit-points) 0) (do-effect (-> self skel effect) 'death-default 0.0 -1) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event self 'death-end) (cleanup-for-death self) ) @@ -1401,6 +1397,7 @@ ) (defmethod deactivate ((this wasp)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (if (nonzero? (-> this smoke-part)) (kill-and-free-particles (-> this smoke-part)) ) @@ -1413,17 +1410,17 @@ ) ;; WARN: Return type mismatch hover-enemy vs wasp. -(defmethod relocate ((this wasp) (arg0 int)) +(defmethod relocate ((this wasp) (offset int)) (if (nonzero? (-> this gun-jmod)) - (&+! (-> this gun-jmod) arg0) + (&+! (-> this gun-jmod) offset) ) (if (nonzero? (-> this smoke-part)) - (&+! (-> this smoke-part) arg0) + (&+! (-> this smoke-part) offset) ) (if (nonzero? (-> this engine-part)) - (&+! (-> this engine-part) arg0) + (&+! (-> this engine-part) offset) ) - (the-as wasp ((method-of-type hover-enemy relocate) this arg0)) + (the-as wasp ((method-of-type hover-enemy relocate) this offset)) ) (defmethod hover-enemy-method-149 ((this wasp)) diff --git a/goal_src/jak2/levels/common/enemy/spyder.gc b/goal_src/jak2/levels/common/enemy/spyder.gc index 290b978b7b..7c02f83a71 100644 --- a/goal_src/jak2/levels/common/enemy/spyder.gc +++ b/goal_src/jak2/levels/common/enemy/spyder.gc @@ -267,7 +267,7 @@ (defmethod general-event-handler ((this spyder) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (case arg2 (('hit-knocked) (logclear! (-> this mask) (process-mask actor-pause)) @@ -661,9 +661,9 @@ (defmethod common-post ((this spyder)) "Does a lot of various things relating to interacting with the target -- tracks when the enemy was last drawn -- looks at the target and handles attacking -@TODO Not extremely well understood yet" + - tracks when the enemy was last drawn + - looks at the target and handles attacking + @TODO Not extremely well understood yet" (spyder-method-185 this) (spyder-method-184 this (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> this root quat))) (update-trans! (-> this sound) (-> this root trans)) @@ -1067,13 +1067,11 @@ (set! (-> self fire-info 0 quad) (-> s3-0 quad)) (set! (-> self fire-info 1 quad) (-> s2-1 quad)) ) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 0.2)) - (set! f30-0 (seek f30-0 (lerp-scale 0.0 1.0 (the float s4-0) 0.0 8.0) (seconds-per-frame))) - (ja :num! (loop!)) - (ja :chan 1 :num! (chan 0) :frame-interp0 f30-0 :frame-interp1 f30-0) - (suspend) - ) + (suspend-for + (seconds 0.2) + (set! f30-0 (seek f30-0 (lerp-scale 0.0 1.0 (the float s4-0) 0.0 8.0) (seconds-per-frame))) + (ja :num! (loop!)) + (ja :chan 1 :num! (chan 0) :frame-interp0 f30-0 :frame-interp1 f30-0) ) (let ((f28-1 (+ 12288.0 f28-0))) (set! (-> gp-0 quad) (-> s5-0 quad)) diff --git a/goal_src/jak2/levels/common/entities/com-elevator.gc b/goal_src/jak2/levels/common/entities/com-elevator.gc index 36ab2d3771..cd404c42df 100644 --- a/goal_src/jak2/levels/common/entities/com-elevator.gc +++ b/goal_src/jak2/levels/common/entities/com-elevator.gc @@ -30,10 +30,10 @@ (defmethod move-between-points ((this com-elevator) (arg0 vector) (arg1 float) (arg2 float)) "Move between two points on the elevator's path -@param vec TODO not sure -@param point-a The first point fetched from the elevator's path -@param point-b The second point fetched from the path -@see [[path-control]] and [[elevator]]" + @param vec TODO not sure + @param point-a The first point fetched from the elevator's path + @param point-b The second point fetched from the path + @see [[path-control]] and [[elevator]]" (let ((s4-0 (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) arg1 'interp)) (a0-3 (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) arg2 'interp)) (v1-3 (-> this root trans)) @@ -93,11 +93,7 @@ (defstate dormant (com-elevator) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (process-entity-status! self (entity-perm-status subtask-complete) #t) ) ) @@ -127,11 +123,7 @@ (remove-setting! 'allow-look-around) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (sound-play "com-elevator-s") (logior! (-> self elevator-status) (elevator-status waiting-to-ascend)) (until #f @@ -174,6 +166,7 @@ ) (defmethod deactivate ((this com-elevator)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (-> this sound-id)) (call-parent-method this) (none) @@ -182,7 +175,7 @@ ;; WARN: Return type mismatch sound-id vs none. (defmethod init-plat! ((this com-elevator)) "Does any necessary initial platform setup. -For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." + For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." (dotimes (s5-0 (-> this path curve num-cverts)) (let ((a1-1 (res-lump-struct (-> this entity) 'string-startup-vector structure :time (the float s5-0)))) (cond @@ -272,11 +265,7 @@ For example for an elevator pre-compute the distance between the first and last ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (logior! (-> self elevator-status) (elevator-status waiting-to-ascend)) (until #f (sound-play "tmb-elevator-lp" :id (-> self sound-id)) @@ -303,6 +292,7 @@ For example for an elevator pre-compute the distance between the first and last ) (defmethod deactivate ((this tomb-trans-elevator)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (-> this sound-id)) (call-parent-method this) (none) @@ -311,7 +301,7 @@ For example for an elevator pre-compute the distance between the first and last ;; WARN: Return type mismatch sound-id vs none. (defmethod init-plat! ((this tomb-trans-elevator)) "Does any necessary initial platform setup. -For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." + For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." (call-parent-method this) (set! (-> this sound-id) (new-sound-id)) (none) diff --git a/goal_src/jak2/levels/common/entities/gun-buoy.gc b/goal_src/jak2/levels/common/entities/gun-buoy.gc index 763ed906a5..6c91ae73c5 100644 --- a/goal_src/jak2/levels/common/entities/gun-buoy.gc +++ b/goal_src/jak2/levels/common/entities/gun-buoy.gc @@ -826,11 +826,7 @@ (gun-buoy-method-183 self a1-1) ) ) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.75)) - (suspend) - ) - ) + (suspend-for (seconds 0.75)) ) (go-virtual hostile) ) @@ -856,11 +852,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (go-virtual exit-ambush) ) :post gun-buoy-chase-post @@ -875,7 +867,7 @@ (defmethod general-event-handler ((this gun-buoy) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (case arg2 (('jump) #f @@ -888,9 +880,9 @@ (defmethod common-post ((this gun-buoy)) "Does a lot of various things relating to interacting with the target -- tracks when the enemy was last drawn -- looks at the target and handles attacking -@TODO Not extremely well understood yet" + - tracks when the enemy was last drawn + - looks at the target and handles attacking + @TODO Not extremely well understood yet" (-> this root) (let* ((s4-0 *target*) (s5-0 (if (type? s4-0 process-focusable) @@ -973,10 +965,10 @@ ;; WARN: disable def twice: 40. This may happen when a cond (no else) is nested inside of another conditional, but it should be rare. (defmethod in-aggro-range? ((this gun-buoy) (arg0 process-focusable) (arg1 vector)) "Should the enemy activate. -- if `activate-distance` is `0.0`, always true -- otherwise, check if the provided process is close enough -@param proc The process used to distance check -@returns true/false" + - if `activate-distance` is `0.0`, always true + - otherwise, check if the provided process is close enough + @param proc The process used to distance check + @returns true/false" (local-vars (v1-19 process-focusable) (f30-1 meters)) (if (and arg0 (not arg1)) (set! arg1 (get-trans arg0 0)) @@ -1142,11 +1134,11 @@ ) ;; WARN: Return type mismatch nav-enemy vs gun-buoy. -(defmethod relocate ((this gun-buoy) (arg0 int)) +(defmethod relocate ((this gun-buoy) (offset int)) (if (nonzero? (-> this gun-elev-jmod)) - (&+! (-> this gun-elev-jmod) arg0) + (&+! (-> this gun-elev-jmod) offset) ) - (the-as gun-buoy ((method-of-type nav-enemy relocate) this arg0)) + (the-as gun-buoy ((method-of-type nav-enemy relocate) this offset)) ) ;; WARN: Return type mismatch collide-shape-moving vs none. diff --git a/goal_src/jak2/levels/common/entities/spydroid.gc b/goal_src/jak2/levels/common/entities/spydroid.gc index 7798355517..9dc7012212 100644 --- a/goal_src/jak2/levels/common/entities/spydroid.gc +++ b/goal_src/jak2/levels/common/entities/spydroid.gc @@ -622,9 +622,9 @@ (defmethod common-post ((this spydroid)) "Does a lot of various things relating to interacting with the target -- tracks when the enemy was last drawn -- looks at the target and handles attacking -@TODO Not extremely well understood yet" + - tracks when the enemy was last drawn + - looks at the target and handles attacking + @TODO Not extremely well understood yet" (let ((t9-0 (method-of-type nav-enemy common-post))) (t9-0 this) ) @@ -720,7 +720,7 @@ (defmethod general-event-handler ((this spydroid) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (local-vars (v1-6 vector) (sv-144 vector)) (rlet ((vf0 :class vf) (vf4 :class vf) @@ -868,11 +868,7 @@ ) (suspend) (ja-channel-set! 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event self 'death-end) (while (-> self child) (suspend) @@ -1299,6 +1295,7 @@ ) (defmethod deactivate ((this spydroid)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (if (nonzero? (-> this explode-part)) (kill-and-free-particles (-> this explode-part)) ) @@ -1307,18 +1304,18 @@ ) ;; WARN: Return type mismatch nav-enemy vs spydroid. -(defmethod relocate ((this spydroid) (arg0 int)) +(defmethod relocate ((this spydroid) (offset int)) (dotimes (v1-0 4) (if (nonzero? (-> this lightning v1-0)) - (&+! (-> this lightning v1-0) arg0) + (&+! (-> this lightning v1-0) offset) ) ) (when (nonzero? (-> this explode-part)) (if (nonzero? (-> this explode-part)) - (&+! (-> this explode-part) arg0) + (&+! (-> this explode-part) offset) ) ) - (the-as spydroid ((method-of-type nav-enemy relocate) this arg0)) + (the-as spydroid ((method-of-type nav-enemy relocate) this offset)) ) (defmethod init-enemy! ((this spydroid)) diff --git a/goal_src/jak2/levels/common/race/race-obs.gc b/goal_src/jak2/levels/common/race/race-obs.gc index b3554fc68f..e030ed99dd 100644 --- a/goal_src/jak2/levels/common/race/race-obs.gc +++ b/goal_src/jak2/levels/common/race/race-obs.gc @@ -283,50 +283,30 @@ :code (behavior () (until #f (ja :num-func num-func-identity :frame-num (ja-aframe 0.0 0)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (ja-no-eval :group! (ja-group) :num! (seek! (ja-aframe 2.0 0)) :frame-num (ja-aframe 0.0 0)) (until (ja-done? 0) (suspend) (ja :num! (seek! (ja-aframe 2.0 0))) ) (process-spawn part-tracker :init part-tracker-init (-> *part-group-id-table* 196) 600 #f #f self 5 :to self) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (ja-no-eval :group! (ja-group) :num! (seek! (ja-aframe 4.0 0)) :frame-num (ja-aframe 2.0 0)) (until (ja-done? 0) (suspend) (ja :num! (seek! (ja-aframe 4.0 0))) ) (process-spawn part-tracker :init part-tracker-init (-> *part-group-id-table* 195) 300 #f #f self 7 :to self) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (ja-no-eval :group! (ja-group) :num! (seek! (ja-aframe 6.0 0)) :frame-num (ja-aframe 4.0 0)) (until (ja-done? 0) (suspend) (ja :num! (seek! (ja-aframe 6.0 0))) ) (process-spawn part-tracker :init part-tracker-init (-> *part-group-id-table* 194) 300 #f #f self 9 :to self) - (let ((gp-13 (current-time))) - (until (time-elapsed? gp-13 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (process-spawn part-tracker :init part-tracker-init (-> *part-group-id-table* 197) 300 #f #f self 10 :to self) - (let ((gp-15 (current-time))) - (until (time-elapsed? gp-15 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) ) #f ) diff --git a/goal_src/jak2/levels/common/warp-gate.gc b/goal_src/jak2/levels/common/warp-gate.gc index 0731f8386e..d924ad25ec 100644 --- a/goal_src/jak2/levels/common/warp-gate.gc +++ b/goal_src/jak2/levels/common/warp-gate.gc @@ -696,11 +696,7 @@ (set-blackout-frames (seconds 0.05)) ) (start 'play arg0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while (and *target* (and (>= 81920.0 (vector-vector-distance (-> self root trans) (-> *target* control trans))) (not (logtest? (focus-status teleporting) (-> *target* focus-status))) ) @@ -789,11 +785,11 @@ (defmethod init-from-entity! ((this warp-gate) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (warp-gate-init arg0 (the-as vector #f)) (none) ) @@ -1104,20 +1100,21 @@ This commonly includes things such as: ;; WARN: Return type mismatch warp-gate vs air-train. -(defmethod relocate ((this air-train) (arg0 int)) +(defmethod relocate ((this air-train) (offset int)) (if (nonzero? (-> this part-exhaust-left)) - (&+! (-> this part-exhaust-left) arg0) + (&+! (-> this part-exhaust-left) offset) ) (if (nonzero? (-> this part-exhaust-right)) - (&+! (-> this part-exhaust-right) arg0) + (&+! (-> this part-exhaust-right) offset) ) (if (nonzero? (-> this part-dust)) - (&+! (-> this part-dust) arg0) + (&+! (-> this part-dust) offset) ) - (the-as air-train ((method-of-type warp-gate relocate) this arg0)) + (the-as air-train ((method-of-type warp-gate relocate) this offset)) ) (defmethod deactivate ((this air-train)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (-> this hover-sound)) (if (nonzero? (-> this part-exhaust-left)) (kill-and-free-particles (-> this part-exhaust-left)) diff --git a/goal_src/jak2/levels/demo/demo-obs.gc b/goal_src/jak2/levels/demo/demo-obs.gc index 9038f72802..5a4aa77f44 100644 --- a/goal_src/jak2/levels/demo/demo-obs.gc +++ b/goal_src/jak2/levels/demo/demo-obs.gc @@ -30,16 +30,17 @@ ;; WARN: Return type mismatch process vs demo-control. -(defmethod relocate ((this demo-control) (arg0 int)) +(defmethod relocate ((this demo-control) (offset int)) (dotimes (v1-0 2) (if (nonzero? (-> this buffer v1-0)) - (&+! (-> this buffer v1-0) arg0) + (&+! (-> this buffer v1-0) offset) ) ) - (the-as demo-control ((method-of-type process relocate) this arg0)) + (the-as demo-control ((method-of-type process relocate) this offset)) ) (defmethod deactivate ((this demo-control)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (dotimes (s5-0 2) (set-pending-file (-> this buffer s5-0) (the-as string #f) -1 (the-as handle #f) 100000000.0) ) @@ -634,59 +635,41 @@ ) (set! (-> self sprite-draw) (the-as uint 3)) (set-vector! (-> self sprite-pos) -512.0 40.0 0.0 1.0) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.25)) - (set! (-> self sprite-pos x) - (lerp-scale -512.0 0.0 (sin (* 218.45334 (the float (- (current-time) gp-4)))) 0.0 1.0) - ) - (suspend) - ) - ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 2)) - (suspend) - ) + (suspend-for + (seconds 0.25) + (set! (-> self sprite-pos x) + (lerp-scale -512.0 0.0 (sin (* 218.45334 (the float (- (current-time) time)))) 0.0 1.0) + ) ) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 0.25)) - (set! (-> self sprite-pos x) - (lerp-scale 0.0 512.0 (sin (* 218.45334 (the float (- (current-time) gp-6)))) 0.0 1.0) - ) - (suspend) - ) + (suspend-for (seconds 2)) + (suspend-for + (seconds 0.25) + (set! (-> self sprite-pos x) + (lerp-scale 0.0 512.0 (sin (* 218.45334 (the float (- (current-time) time)))) 0.0 1.0) + ) ) (set! (-> self sprite-draw) (the-as uint 1)) (set-vector! (-> self sprite-pos) 30.0 -240.0 0.0 1.0) - (let ((gp-7 (current-time))) - (until (time-elapsed? gp-7 (seconds 0.25)) - (set! (-> self sprite-pos y) - (lerp-scale -240.0 270.0 (sin (* 218.45334 (the float (- (current-time) gp-7)))) 0.0 1.0) - ) - (suspend) - ) - ) - (let ((gp-8 (current-time))) - (until (time-elapsed? gp-8 (seconds 2)) - (suspend) - ) + (suspend-for + (seconds 0.25) + (set! (-> self sprite-pos y) + (lerp-scale -240.0 270.0 (sin (* 218.45334 (the float (- (current-time) time)))) 0.0 1.0) + ) ) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 0.25)) - (set! (-> self sprite-pos y) - (lerp-scale 270.0 720.0 (sin (* 218.45334 (the float (- (current-time) gp-9)))) 0.0 1.0) - ) - (suspend) - ) + (suspend-for (seconds 2)) + (suspend-for + (seconds 0.25) + (set! (-> self sprite-pos y) + (lerp-scale 270.0 720.0 (sin (* 218.45334 (the float (- (current-time) time)))) 0.0 1.0) + ) ) (set! (-> self sprite-draw) (the-as uint 2)) (set-vector! (-> self sprite-pos) 20.0 40.0 0.0 1.0) - (let ((gp-10 (current-time))) - (until (time-elapsed? gp-10 (seconds 0.25)) - (set! (-> self sprite-pos y) - (lerp-scale 720.0 20.0 (sin (* 218.45334 (the float (- (current-time) gp-10)))) 0.0 1.0) - ) - (suspend) - ) + (suspend-for + (seconds 0.25) + (set! (-> self sprite-pos y) + (lerp-scale 720.0 20.0 (sin (* 218.45334 (the float (- (current-time) time)))) 0.0 1.0) + ) ) (let ((a1-21 (new 'stack-no-clear 'array 'symbol 6))) (set! (-> a1-21 5) #f) @@ -697,73 +680,27 @@ (set! (-> a1-21 0) 'demo) (want-levels *load-state* a1-21) ) - (let ((gp-11 (current-time))) - (until (time-elapsed? gp-11 (seconds 2)) - (suspend) - ) - ) - (let ((gp-12 (current-time))) - (until (time-elapsed? gp-12 (seconds 0.25)) - (set! (-> self sprite-pos y) - (lerp-scale 20.0 -720.0 (sin (* 218.45334 (the float (- (current-time) gp-12)))) 0.0 1.0) - ) - (suspend) - ) + (suspend-for (seconds 2)) + (suspend-for + (seconds 0.25) + (set! (-> self sprite-pos y) + (lerp-scale 20.0 -720.0 (sin (* 218.45334 (the float (- (current-time) time)))) 0.0 1.0) + ) ) ) (else - (let ((gp-13 (current-time))) - (until (time-elapsed? gp-13 (seconds 0.38)) - (suspend) - ) - ) - (let ((gp-14 (current-time))) - (until (time-elapsed? gp-14 (seconds 2)) - (suspend) - ) - ) - (let ((gp-15 (current-time))) - (until (time-elapsed? gp-15 (seconds 0.25)) - (suspend) - ) - ) - (let ((gp-16 (current-time))) - (until (time-elapsed? gp-16 (seconds 0.25)) - (suspend) - ) - ) - (let ((gp-17 (current-time))) - (until (time-elapsed? gp-17 (seconds 2)) - (suspend) - ) - ) - (let ((gp-18 (current-time))) - (until (time-elapsed? gp-18 (seconds 0.25)) - (suspend) - ) - ) - (let ((gp-19 (current-time))) - (until (time-elapsed? gp-19 (seconds 0.25)) - (suspend) - ) - ) - (let ((gp-20 (current-time))) - (until (time-elapsed? gp-20 (seconds 2)) - (suspend) - ) - ) - (let ((gp-21 (current-time))) - (until (time-elapsed? gp-21 (seconds 0.25)) - (suspend) - ) - ) - ) - ) - (let ((gp-22 (current-time))) - (until (time-elapsed? gp-22 (seconds 3)) - (suspend) + (suspend-for (seconds 0.38)) + (suspend-for (seconds 2)) + (suspend-for (seconds 0.25)) + (suspend-for (seconds 0.25)) + (suspend-for (seconds 2)) + (suspend-for (seconds 0.25)) + (suspend-for (seconds 0.25)) + (suspend-for (seconds 2)) + (suspend-for (seconds 0.25)) ) ) + (suspend-for (seconds 3)) (demo-screen-change -1 -1 #f #t) (set! (-> *game-info* demo-state) (the-as uint 1)) (start 'play (get-continue-by-name *game-info* "demo-start")) diff --git a/goal_src/jak2/levels/dig/dig-digger.gc b/goal_src/jak2/levels/dig/dig-digger.gc index 645a0af5e3..6c6edb9f25 100644 --- a/goal_src/jak2/levels/dig/dig-digger.gc +++ b/goal_src/jak2/levels/dig/dig-digger.gc @@ -656,10 +656,12 @@ ) (('attack) (let ((v1-2 (the-as attack-info (-> block param 1)))) - - - - (when (and (logtest? (-> v1-2 mask) (attack-mask mode)) #t) + (when (and (logtest? (-> v1-2 mask) (attack-mask mode)) + ;; og:preserve-this fix bug where spinning into grind doesnt break + (#if PC_PORT + (or (= (-> v1-2 mode) 'board) + (and (= (-> v1-2 mode) 'board-spin) (focus-test? *target* rail))) + (= (-> v1-2 mode) 'board))) (cpad-set-buzz! (-> *cpad-list* cpads 0) 0 85 (seconds 0.1)) (go-virtual break-it) ) diff --git a/goal_src/jak2/levels/dig/dig1-obs.gc b/goal_src/jak2/levels/dig/dig1-obs.gc index fc9ea23ce7..4f95188e4c 100644 --- a/goal_src/jak2/levels/dig/dig1-obs.gc +++ b/goal_src/jak2/levels/dig/dig1-obs.gc @@ -440,22 +440,14 @@ (ja :num! (seek! max f30-0)) ) (ja-no-eval :group! dig-bomb-crate-cylinder-idle-ja :num! (seek!) :frame-num 0.0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (ja-no-eval :group! dig-bomb-crate-cylinder-pulse-ja :num! (seek! max f30-0) :frame-num 0.0) (until (ja-done? 0) (suspend) (ja :num! (seek! max f30-0)) ) (ja-no-eval :group! dig-bomb-crate-cylinder-idle-ja :num! (seek!) :frame-num 0.0) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (ja-no-eval :group! dig-bomb-crate-cylinder-pulse-ja :num! (seek! max f30-0) :frame-num 0.0) (until (ja-done? 0) (suspend) @@ -463,33 +455,21 @@ ) ) (ja-no-eval :group! dig-bomb-crate-cylinder-idle-ja :num! (seek!) :frame-num 0.0) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (ja-no-eval :group! dig-bomb-crate-cylinder-pulse-ja :num! (seek! max 0.375) :frame-num 0.0) (until (ja-done? 0) (suspend) (ja :num! (seek! max 0.375)) ) (ja-no-eval :group! dig-bomb-crate-cylinder-idle-ja :num! (seek!) :frame-num 0.0) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (ja-no-eval :group! dig-bomb-crate-cylinder-pulse-ja :num! (seek! max 0.4375) :frame-num 0.0) (until (ja-done? 0) (suspend) (ja :num! (seek! max 0.4375)) ) (ja-no-eval :group! dig-bomb-crate-cylinder-idle-ja :num! (seek!) :frame-num 0.0) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 0.125)) - (suspend) - ) - ) + (suspend-for (seconds 0.125)) (dotimes (gp-6 12) (ja-no-eval :group! dig-bomb-crate-cylinder-pulse-ja :num! (seek! max 0.437) :frame-num 0.0) (until (ja-done? 0) @@ -497,11 +477,7 @@ (ja :num! (seek! max 0.437)) ) (ja-no-eval :group! dig-bomb-crate-cylinder-idle-ja :num! (seek!) :frame-num 0.0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.05)) - (suspend) - ) - ) + (suspend-for (seconds 0.05)) ) (go-virtual die) ) @@ -876,11 +852,7 @@ ) ) (suspend) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 4)) - (suspend) - ) - ) + (suspend-for (seconds 4)) (cleanup-for-death self) ) ) @@ -888,11 +860,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this dig-bomb-crate) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (set! (-> s4-0 penetrated-by) (penetrate diff --git a/goal_src/jak2/levels/dig/dig3-obs.gc b/goal_src/jak2/levels/dig/dig3-obs.gc index 717e656d1f..e0beb76e56 100644 --- a/goal_src/jak2/levels/dig/dig3-obs.gc +++ b/goal_src/jak2/levels/dig/dig3-obs.gc @@ -261,42 +261,24 @@ :virtual #t :trans rider-trans :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (the int (-> self cycle-offset))) - (suspend) - ) - ) + (suspend-for (the int (-> self cycle-offset))) (until #f - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (the int (-> self cycle-time))) - (suspend) - ) - ) + (suspend-for (the int (-> self cycle-time))) (activate! (-> self smush) -1.0 60 225 1.0 1.0 (-> self clock)) (sound-play "spikey-shake" :position (-> self root trans)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.75)) - (set! (-> self shudder-angle) (* 364.0889 (update! (-> self smush)))) - (suspend) - ) - ) + (suspend-for (seconds 0.75) (set! (-> self shudder-angle) (* 364.0889 (update! (-> self smush))))) (set! (-> self shudder-angle) 0.0) (set-zero! (-> self smush)) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (sound-play "spikey-turn" :position (-> self root trans)) (let* ((f0-7 1.0) (f30-1 (* 65536.0 f0-7)) - (gp-6 (current-time)) ) - (until (time-elapsed? gp-6 (seconds 1)) + (suspend-for + (seconds 1) (set! (-> self rot-angle) (the float (sar (shl (the int (+ (-> self rot-angle) (* f30-1 (seconds-per-frame)))) 48) 48)) ) - (suspend) ) ) (let ((v1-42 #x10000)) @@ -329,11 +311,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this dig-spikey-step) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 int)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) @@ -438,11 +420,7 @@ This commonly includes things such as: ) (sound-play "spikey-break") (suspend) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 4)) - (suspend) - ) - ) + (suspend-for (seconds 4)) (let ((t9-7 (-> (method-of-type projectile-bounce die) code))) (if t9-7 ((the-as (function none) t9-7)) @@ -672,11 +650,7 @@ This commonly includes things such as: :virtual #t :code (behavior () (sound-play "spikey-door") - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) (let ((gp-2 (new 'stack-no-clear 'vector)) (s5-1 (new 'static 'vector :x -16384.0 :y -16384.0)) ) @@ -718,11 +692,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this dig-spikey-sphere-door) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -942,11 +916,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this dig-balloon-lurker) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 3) 0))) (set! (-> s4-0 total-prims) (the-as uint 4)) @@ -1046,6 +1020,7 @@ This commonly includes things such as: ) (defmethod deactivate ((this dig-balloon-lurker)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (-> this pedal-sound-id)) ((method-of-type process-drawable deactivate) this) (none) @@ -1198,6 +1173,7 @@ This commonly includes things such as: ) (defmethod deactivate ((this dig-wheel-step)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (-> this wheel-sound-id)) ((method-of-type process-drawable deactivate) this) (none) @@ -1206,11 +1182,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this dig-wheel-step) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 3) 0))) (set! (-> s4-0 total-prims) (the-as uint 4)) @@ -1895,11 +1871,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this dig-stomp-block-controller) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this played-fall?) #f) (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) @@ -1921,6 +1897,7 @@ This commonly includes things such as: ) (defmethod run-logic? ((this dig-totem)) + "Should this process be run? Checked by execute-process-tree." #t ) @@ -1932,11 +1909,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this dig-totem) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((v1-2 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) (set! (-> v1-2 prim-core collide-as) (collide-spec obstacle)) diff --git a/goal_src/jak2/levels/drill/drill-obs2.gc b/goal_src/jak2/levels/drill/drill-obs2.gc index 3da90594bc..5299953484 100644 --- a/goal_src/jak2/levels/drill/drill-obs2.gc +++ b/goal_src/jak2/levels/drill/drill-obs2.gc @@ -192,11 +192,11 @@ (defmethod init-from-entity! ((this drill-flip-step) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (init-plat-collision! this) (process-drawable-from-entity! this arg0) (initialize-skeleton this (the-as skeleton-group (get-skel this)) (the-as pair 0)) @@ -345,11 +345,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this drill-falling-door) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 2) 0))) (set! (-> s4-0 total-prims) (the-as uint 3)) @@ -449,11 +449,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this drill-sliding-door) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 2) 0))) (set! (-> s4-0 total-prims) (the-as uint 3)) @@ -604,11 +604,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this drill-breakable-barrel) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((v1-2 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) (set! (-> v1-2 prim-core collide-as) (collide-spec obstacle)) @@ -788,11 +788,7 @@ This commonly includes things such as: ) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (cleanup-for-death self) ) ) @@ -818,11 +814,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this drill-metalhead-eggs) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) (init-collision! this) (process-drawable-from-entity! this arg0) @@ -1145,11 +1141,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this drill-bridge-shot) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 3) 0))) (set! (-> s4-0 total-prims) (the-as uint 4)) @@ -1233,11 +1229,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this drill-drill) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton diff --git a/goal_src/jak2/levels/forest/forest-obs.gc b/goal_src/jak2/levels/forest/forest-obs.gc index e3521ea059..18a9cadfd7 100644 --- a/goal_src/jak2/levels/forest/forest-obs.gc +++ b/goal_src/jak2/levels/forest/forest-obs.gc @@ -26,11 +26,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this forest-hover-manager) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this entity) arg0) (hover-enemy-manager-init! this *forest-protect-battle*) (set! (-> this transport-actor 0) (entity-actor-lookup arg0 'alt-actor 0)) @@ -343,11 +343,7 @@ This commonly includes things such as: ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (send-event *camera* 'change-target #f) (cleanup-for-death self) ) @@ -381,6 +377,7 @@ This commonly includes things such as: ) (defmethod deactivate ((this forest-youngsamos)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (if (valid? (-> this hud) (the-as type #f) "" #t 0) (send-event (handle->process (-> this hud)) 'hide-and-die) ) @@ -392,12 +389,13 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this forest-youngsamos) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" - (stack-size-set! (-> this main-thread) 384) ;; og:preserve-this + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" + ;; og:preserve-this + (stack-size-set! (-> this main-thread) 384) (let ((s4-0 (new 'process 'collide-shape-moving this (collide-list-enum hit-by-others)))) (set! (-> s4-0 dynam) (copy *standard-dynamics* 'process)) (set! (-> s4-0 reaction) forest-youngsamos-bounce-reaction) @@ -596,11 +594,7 @@ This commonly includes things such as: (lambda :behavior task-manager () (set-time! (-> self start-time)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (let ((s5-0 (entity-by-name "transport-level-1")) (gp-1 (entity-by-name "transport-level-2")) ) @@ -669,11 +663,7 @@ This commonly includes things such as: ) ) ) - (let ((s3-0 (current-time))) - (until (time-elapsed? s3-0 (seconds 15)) - (suspend) - ) - ) + (suspend-for (seconds 15)) (let ((a1-4 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-4 from) (process->ppointer self)) (set! (-> a1-4 num-params) 1) @@ -707,11 +697,7 @@ This commonly includes things such as: ) ) (dotimes (s3-1 3) - (let ((s2-0 (current-time))) - (until (time-elapsed? s2-0 (seconds 10)) - (suspend) - ) - ) + (suspend-for (seconds 10)) (let ((a1-6 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-6 from) (process->ppointer self)) (set! (-> a1-6 num-params) 1) @@ -744,11 +730,7 @@ This commonly includes things such as: ) ) ) - (let ((s2-1 (current-time))) - (until (time-elapsed? s2-1 (seconds 10)) - (suspend) - ) - ) + (suspend-for (seconds 10)) (let ((a1-8 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-8 from) (process->ppointer self)) (set! (-> a1-8 num-params) 1) @@ -782,11 +764,7 @@ This commonly includes things such as: ) ) ) - (let ((s3-2 (current-time))) - (until (time-elapsed? s3-2 (seconds 10)) - (suspend) - ) - ) + (suspend-for (seconds 10)) (let ((a1-10 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-10 from) (process->ppointer self)) (set! (-> a1-10 num-params) 1) @@ -819,11 +797,7 @@ This commonly includes things such as: ) ) ) - (let ((s3-3 (current-time))) - (until (time-elapsed? s3-3 (seconds 10)) - (suspend) - ) - ) + (suspend-for (seconds 10)) (dotimes (s3-4 10) (let ((v1-114 s4-0)) (if (not (if v1-114 @@ -833,11 +807,7 @@ This commonly includes things such as: (goto cfg-74) ) ) - (let ((s2-2 (current-time))) - (until (time-elapsed? s2-2 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) ) (label cfg-74) (let ((a1-12 (new 'stack-no-clear 'event-message-block))) @@ -912,37 +882,21 @@ This commonly includes things such as: ) ) ) - (let ((s3-5 (current-time))) - (until (time-elapsed? s3-5 (seconds 1)) - (suspend) - ) - ) - ) - ) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.5)) - (suspend) + (suspend-for (seconds 1)) ) ) + (suspend-for (seconds 0.5)) (set-setting! 'entity-name "camera-260" 0.0 0) (set-setting! 'process-mask 'set 0.0 (process-mask movie enemy)) (process-grab? *target* #f) - (let ((s4-2 (current-time))) - (until (time-elapsed? s4-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (send-event (if s5-0 (-> s5-0 extra process) ) 'leave ) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (send-event (if gp-1 (-> gp-1 extra process) @@ -950,19 +904,11 @@ This commonly includes things such as: 'leave ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) (remove-setting! 'entity-name) (remove-setting! 'process-mask) (process-release? *target*) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) (go-virtual complete) (while *target* (suspend) diff --git a/goal_src/jak2/levels/fortress/dump/fordumpa-obs.gc b/goal_src/jak2/levels/fortress/dump/fordumpa-obs.gc index 731baf8c6a..0f9a9ee3b0 100644 --- a/goal_src/jak2/levels/fortress/dump/fordumpa-obs.gc +++ b/goal_src/jak2/levels/fortress/dump/fordumpa-obs.gc @@ -48,19 +48,11 @@ :virtual #t :event (-> (method-of-type fort-elec-switch idle) event) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 16)) - (suspend) - ) - ) + (suspend-for (seconds 16)) (until (logtest? (-> self draw status) (draw-control-status on-screen)) (suspend) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.4)) - (suspend) - ) - ) + (suspend-for (seconds 0.4)) (talker-spawn-func (-> *talker-speech* 86) *entity-pool* (target-pos 0) (the-as region #f)) (sleep-code) ) @@ -137,11 +129,7 @@ ) ) (sound-play "elec-switch") - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (let ((v1-22 #t)) (when (-> self switch-group) (dotimes (a0-11 (-> self switch-group-count)) @@ -173,11 +161,7 @@ ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.75)) - (suspend) - ) - ) + (suspend-for (seconds 0.75)) (let ((a1-14 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-14 from) (process->ppointer self)) (set! (-> a1-14 num-params) 0) @@ -193,11 +177,7 @@ ) ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 1.5)) - (suspend) - ) - ) + (suspend-for (seconds 1.5)) (remove-setting! 'entity-name) (remove-setting! 'process-mask) (process-release? *target*) @@ -223,21 +203,21 @@ ) ;; WARN: Return type mismatch process-drawable vs fort-elec-switch. -(defmethod relocate ((this fort-elec-switch) (arg0 int)) +(defmethod relocate ((this fort-elec-switch) (offset int)) (if (nonzero? (-> this l-bolt)) - (&+! (-> this l-bolt) arg0) + (&+! (-> this l-bolt) offset) ) - (the-as fort-elec-switch ((method-of-type process-drawable relocate) this arg0)) + (the-as fort-elec-switch ((method-of-type process-drawable relocate) this offset)) ) ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this fort-elec-switch) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) ;; og:preserve-this added (stack-size-set! (-> this top-thread) 512) @@ -447,11 +427,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this fort-fence) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (stack-size-set! (-> this main-thread) 512) (fort-fence-method-23 this) (process-drawable-from-entity! this arg0) diff --git a/goal_src/jak2/levels/fortress/dump/fordumpc-obs.gc b/goal_src/jak2/levels/fortress/dump/fordumpc-obs.gc index d16272ad63..25d3b42d36 100644 --- a/goal_src/jak2/levels/fortress/dump/fordumpc-obs.gc +++ b/goal_src/jak2/levels/fortress/dump/fordumpc-obs.gc @@ -134,11 +134,7 @@ ) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (cleanup-for-death self) ) ) @@ -146,11 +142,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this fort-dump-bomb-a) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((v1-2 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) (set! (-> v1-2 prim-core collide-as) (collide-spec bot)) @@ -355,11 +351,7 @@ This commonly includes things such as: (-> gp-2 ppointer) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event (ppointer->process (-> self parent)) 'died) (sleep-code) ) @@ -371,6 +363,7 @@ This commonly includes things such as: ) (defmethod deactivate ((this fort-missile-target)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (the-as sound-id (-> this sound-id))) (call-parent-method this) (none) @@ -521,42 +514,22 @@ This commonly includes things such as: ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 8)) - (suspend) - ) - ) + (suspend-for (seconds 8)) (until (logtest? (-> self draw status) (draw-control-status on-screen)) (suspend) ) (when (= (-> self bomb-count) 4) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.4)) - (suspend) - ) - ) + (suspend-for (seconds 0.4)) (add-process *gui-control* self (gui-channel daxter) (gui-action play) "ds017" -99.0 0) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 20)) - (suspend) - ) - ) + (suspend-for (seconds 20)) (if (= (-> self bomb-count) 4) (add-process *gui-control* self (gui-channel daxter) (gui-action play) "ds018" -99.0 0) ) (while (> (-> self bomb-count) 0) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.2)) - (suspend) - ) - ) - ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.8)) - (suspend) - ) + (suspend-for (seconds 0.2)) ) + (suspend-for (seconds 0.8)) (go-virtual missile-countdown) ) :post (behavior () @@ -599,22 +572,14 @@ This commonly includes things such as: ) ) (set-fordumpc-light-flag! #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (while (not (process-grab? *target* #f)) (suspend) ) (set-setting! 'entity-name "camera-182" 0.0 0) (set-setting! 'process-mask 'set 0.0 (process-mask movie enemy)) (task-node-close! (game-task-node fortress-dump-missile)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.75)) - (suspend) - ) - ) + (suspend-for (seconds 0.75)) (let ((a1-5 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-5 from) (process->ppointer self)) (set! (-> a1-5 num-params) 0) @@ -645,11 +610,7 @@ This commonly includes things such as: ) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1.5)) - (suspend) - ) - ) + (suspend-for (seconds 1.5)) (remove-setting! 'entity-name) (remove-setting! 'process-mask) (process-release? *target*) @@ -672,21 +633,13 @@ This commonly includes things such as: (set! (-> *game-info* timer) 0) (set! (-> self hud) (ppointer->handle (process-spawn hud-timer :init hud-init-by-other :to *target*))) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.4)) - (suspend) - ) - ) + (suspend-for (seconds 0.4)) (set! (-> self explosion-sound-id) (add-process *gui-control* self (gui-channel background) (gui-action queue) "big-xplo" -99.0 0) ) (dotimes (gp-5 10) (set! (-> *game-info* timer) (the-as time-frame (- 3000 (the int (* 300.0 (the float gp-5)))))) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) ) (go-virtual die) ) @@ -722,11 +675,7 @@ This commonly includes things such as: (remove-setting! 'allow-progress) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.4)) - (suspend) - ) - ) + (suspend-for (seconds 0.4)) (logior! (-> self draw status) (draw-control-status no-draw)) (when *scene-player* (cleanup-for-death self) @@ -884,11 +833,7 @@ This commonly includes things such as: (suspend) ) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 10)) - (suspend) - ) - ) + (suspend-for (seconds 10)) (cleanup-for-death self) ) ) @@ -899,6 +844,7 @@ This commonly includes things such as: ) (defmethod deactivate ((this fort-missile)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (set-fordumpc-light-flag! #f) (send-event (handle->process (-> this hud)) 'hide-and-die) (if (nonzero? (-> this part-doom)) @@ -909,21 +855,21 @@ This commonly includes things such as: (none) ) -(defmethod relocate ((this fort-missile) (arg0 int)) +(defmethod relocate ((this fort-missile) (offset int)) (if (nonzero? (-> this part-doom)) - (&+! (-> this part-doom) arg0) + (&+! (-> this part-doom) offset) ) - (call-parent-method this arg0) + (call-parent-method this offset) ) ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this fort-missile) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (stack-size-set! (-> this main-thread) 512) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 2) 0))) diff --git a/goal_src/jak2/levels/fortress/dump/fort-robotank-turret.gc b/goal_src/jak2/levels/fortress/dump/fort-robotank-turret.gc index df38111f81..7ec3ad10f9 100644 --- a/goal_src/jak2/levels/fortress/dump/fort-robotank-turret.gc +++ b/goal_src/jak2/levels/fortress/dump/fort-robotank-turret.gc @@ -240,12 +240,10 @@ (defstate die (fort-roboscreen) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (seek! (-> self transition) 0.0 (seconds-per-frame)) - (set-roboscreen-alpha! (-> self transition)) - (suspend) - ) + (suspend-for + (seconds 1) + (seek! (-> self transition) 0.0 (seconds-per-frame)) + (set-roboscreen-alpha! (-> self transition)) ) ) ) @@ -316,6 +314,7 @@ ) (defmethod deactivate ((this fort-roboscreen)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (disable *screen-filter*) (set-roboscreen-alpha! 0.0) (call-parent-method this) @@ -537,19 +536,19 @@ ) ;; WARN: Return type mismatch process-drawable vs fort-robotank-reticle. -(defmethod relocate ((this fort-robotank-reticle) (arg0 int)) +(defmethod relocate ((this fort-robotank-reticle) (offset int)) (if (nonzero? (-> this shadow-jmod)) - (&+! (-> this shadow-jmod) arg0) + (&+! (-> this shadow-jmod) offset) ) (if (nonzero? (-> this sight-jmod)) - (&+! (-> this sight-jmod) arg0) + (&+! (-> this sight-jmod) offset) ) (dotimes (v1-8 3) (if (nonzero? (-> this ring-jmod v1-8)) - (&+! (-> this ring-jmod v1-8) arg0) + (&+! (-> this ring-jmod v1-8) offset) ) ) - (the-as fort-robotank-reticle ((method-of-type process-drawable relocate) this arg0)) + (the-as fort-robotank-reticle ((method-of-type process-drawable relocate) this offset)) ) ;; WARN: Return type mismatch object vs none. @@ -1185,11 +1184,7 @@ (logior! (-> self flags) (robotank-turret-flags rotflags-3)) (set! (-> self firing-sight-pos quad) (-> self sight-pos quad)) (send-event (handle->process (-> self reticle)) 'lock) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (let ((gp-2 (max 2 (min 3 (rand-vu-int-range 0 3))))) 0 (dotimes (s5-2 gp-2) @@ -1215,12 +1210,8 @@ ) ) ) - (let ((f30-0 (rand-vu-float-range 0.05 0.43)) - (s4-2 (current-time)) - ) - (until (time-elapsed? s4-2 (the int (* 300.0 f30-0))) - (suspend) - ) + (let ((f30-0 (rand-vu-float-range 0.05 0.43))) + (suspend-for (the int (* 300.0 f30-0))) ) ) ) @@ -1238,11 +1229,8 @@ 2.11 ) ) - (gp-3 (current-time)) ) - (until (time-elapsed? gp-3 (the int (* 300.0 f30-1))) - (suspend) - ) + (suspend-for (the int (* 300.0 f30-1))) ) ) #f @@ -1255,11 +1243,7 @@ :code (behavior () (send-event (handle->process (-> self reticle)) 'die) (send-event (handle->process (-> self screen)) 'die) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while (-> self child) (suspend) ) @@ -1267,6 +1251,7 @@ ) (defmethod deactivate ((this fort-robotank-turret)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (logclear! (-> this flags) (robotank-turret-flags rotflags-6)) (sound-stop (-> this turn-sound-id)) (let ((a0-4 (handle->process (-> this screen)))) @@ -1279,11 +1264,11 @@ ) ;; WARN: Return type mismatch process-focusable vs fort-robotank-turret. -(defmethod relocate ((this fort-robotank-turret) (arg0 int)) +(defmethod relocate ((this fort-robotank-turret) (offset int)) (if (nonzero? (-> this gun-elev-jmod)) - (&+! (-> this gun-elev-jmod) arg0) + (&+! (-> this gun-elev-jmod) offset) ) - (the-as fort-robotank-turret ((method-of-type process-focusable relocate) this arg0)) + (the-as fort-robotank-turret ((method-of-type process-focusable relocate) this offset)) ) ;; WARN: Return type mismatch object vs none. diff --git a/goal_src/jak2/levels/fortress/dump/fort-robotank.gc b/goal_src/jak2/levels/fortress/dump/fort-robotank.gc index bd0f136b89..4730f4e446 100644 --- a/goal_src/jak2/levels/fortress/dump/fort-robotank.gc +++ b/goal_src/jak2/levels/fortress/dump/fort-robotank.gc @@ -769,11 +769,7 @@ ) :code (behavior () (logclear! (-> self flags) (robotank-flags roflags-2)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) (logior! (-> self flags) (robotank-flags roflags-2)) (sleep-code) ) @@ -901,11 +897,7 @@ (remove-setting! 'process-mask) (remove-setting! 'target-height) (send-event (handle->process (-> self turret)) 'die) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (while (-> self child) (suspend) ) @@ -914,36 +906,37 @@ ) (defmethod deactivate ((this fort-robotank)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (stop! (-> this idle-sound)) (stop! (-> this barrel-sound)) ((method-of-type process-drawable deactivate) this) (none) ) -(defmethod relocate ((this fort-robotank) (arg0 int)) +(defmethod relocate ((this fort-robotank) (offset int)) (if (nonzero? (-> this barrel-part)) - (&+! (-> this barrel-part) arg0) + (&+! (-> this barrel-part) offset) ) (if (nonzero? (-> this roller-jmod)) - (&+! (-> this roller-jmod) arg0) + (&+! (-> this roller-jmod) offset) ) (if (nonzero? (-> this vibe-jmod)) - (&+! (-> this vibe-jmod) arg0) + (&+! (-> this vibe-jmod) offset) ) (if (nonzero? (-> this idle-sound)) - (&+! (-> this idle-sound) arg0) + (&+! (-> this idle-sound) offset) ) (if (nonzero? (-> this barrel-sound)) - (&+! (-> this barrel-sound) arg0) + (&+! (-> this barrel-sound) offset) ) (let ((v1-20 (-> this path-info))) (when (nonzero? v1-20) (dotimes (a0-2 (-> this path-count)) (if (nonzero? (-> v1-20 data a0-2 path)) - (&+! (-> v1-20 data a0-2 path) arg0) + (&+! (-> v1-20 data a0-2 path) offset) ) ) - (&+! (-> this path-info) arg0) + (&+! (-> this path-info) offset) ) ) (dotimes (v1-24 2) @@ -961,24 +954,24 @@ joint-mod (-> (the-as (pointer uint32) (&+ (&+ (the-as (pointer uint32) this) (* 144 v1-24)) (* a0-4 16))) 55) ) - arg0 + offset ) ) ) ) ) ) - (call-parent-method this arg0) + (call-parent-method this offset) ) ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this fort-robotank) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player)))) (set! (-> s4-0 dynam) (copy *standard-dynamics* 'process)) (set! (-> s4-0 reaction) cshape-reaction-default) diff --git a/goal_src/jak2/levels/fortress/exit/forexita-obs.gc b/goal_src/jak2/levels/fortress/exit/forexita-obs.gc index 41e7082f35..1172ec62e3 100644 --- a/goal_src/jak2/levels/fortress/exit/forexita-obs.gc +++ b/goal_src/jak2/levels/fortress/exit/forexita-obs.gc @@ -191,13 +191,14 @@ ;; WARN: Return type mismatch sound-id vs none. (defmethod init-plat! ((this fort-lift-plat)) "Does any necessary initial platform setup. -For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." + For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." (set! (-> this root pause-adjust-distance) 327680.0) (set! (-> this sound-id) (new-sound-id)) (none) ) (defmethod deactivate ((this fort-lift-plat)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (-> this sound-id)) ((method-of-type plat deactivate) this) (none) @@ -205,9 +206,9 @@ For example for an elevator pre-compute the distance between the first and last (defmethod plat-path-sync ((this fort-lift-plat)) "If the `sync` period is greater than `0` then transition the state to [[plat::35]] -otherwise, [[plat::34]] + otherwise, [[plat::34]] -@see [[sync-eased]]" + @see [[sync-eased]]" (cond ((logtest? (-> this path flags) (path-control-flag not-found)) (go (method-of-object this plat-idle)) @@ -281,11 +282,11 @@ otherwise, [[plat::34]] ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this fort-claw) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -316,11 +317,7 @@ This commonly includes things such as: () (until #f (sound-play "fortress-alarm") - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) ) #f ) diff --git a/goal_src/jak2/levels/fortress/fort-turret.gc b/goal_src/jak2/levels/fortress/fort-turret.gc index f38ed07eae..f05c45b5e1 100644 --- a/goal_src/jak2/levels/fortress/fort-turret.gc +++ b/goal_src/jak2/levels/fortress/fort-turret.gc @@ -505,9 +505,9 @@ (defmethod common-post ((this fort-turret)) "Does a lot of various things relating to interacting with the target -- tracks when the enemy was last drawn -- looks at the target and handles attacking -@TODO Not extremely well understood yet" + - tracks when the enemy was last drawn + - looks at the target and handles attacking + @TODO Not extremely well understood yet" (let ((t9-0 (method-of-type enemy common-post))) (t9-0 this) ) @@ -732,11 +732,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (until #f (let ((gp-2 7)) (sound-play "gturret") @@ -753,11 +749,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.33)) - (suspend) - ) - ) + (suspend-for (seconds 0.33)) (if (= gp-2 7) (set! gp-2 8) (set! gp-2 9) @@ -765,11 +757,7 @@ ) ) (set! (-> self flash-state) #f) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 1.5)) - (suspend) - ) - ) + (suspend-for (seconds 1.5)) ) #f ) @@ -855,7 +843,7 @@ (defmethod general-event-handler ((this fort-turret) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (if (and (= arg2 'notify) (< 1 arg1) (= (-> arg3 param 0) 'attack) (= (-> arg3 param 1) *target*)) (set-time! (-> this last-hit-time)) ) @@ -916,19 +904,10 @@ (sound-play "turret-explode") (suspend) (ja-channel-set! 0) - (let ((gp-2 (vector<-cspace! (new 'stack-no-clear 'vector) (joint-node fort-turret-lod0-jg headrotate))) - (s5-2 (current-time)) - ) - (until (time-elapsed? s5-2 (seconds 2)) - (spawn (-> self part) gp-2) - (suspend) - ) - ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 1)) - (suspend) - ) + (let ((gp-2 (vector<-cspace! (new 'stack-no-clear 'vector) (joint-node fort-turret-lod0-jg headrotate)))) + (suspend-for (seconds 2) (spawn (-> self part) gp-2)) ) + (suspend-for (seconds 1)) (send-event self 'death-end) (while (-> self child) (suspend) @@ -948,7 +927,7 @@ ;; WARN: Return type mismatch int vs penetrate. (defmethod get-penetrate-info ((this fort-turret)) "@returns the allowed way(s) this enemy can take damage -@see [[penetrate]] and [[penetrated-by-all&hit-points->penetrated-by]]" + @see [[penetrate]] and [[penetrated-by-all&hit-points->penetrated-by]]" (the-as penetrate 0) ) @@ -1011,14 +990,14 @@ ;; ) ;; WARN: Return type mismatch enemy vs fort-turret. -(defmethod relocate ((this fort-turret) (arg0 int)) +(defmethod relocate ((this fort-turret) (offset int)) (if (nonzero? (-> this gun-tilt-jm)) - (&+! (-> this gun-tilt-jm) arg0) + (&+! (-> this gun-tilt-jm) offset) ) (if (nonzero? (-> this gun-shadow-jm)) - (&+! (-> this gun-shadow-jm) arg0) + (&+! (-> this gun-shadow-jm) offset) ) - (the-as fort-turret ((method-of-type enemy relocate) this arg0)) + (the-as fort-turret ((method-of-type enemy relocate) this offset)) ) (defmethod init-enemy! ((this fort-turret)) diff --git a/goal_src/jak2/levels/fortress/fortress-obs.gc b/goal_src/jak2/levels/fortress/fortress-obs.gc index ae1d3ab44e..252483649c 100644 --- a/goal_src/jak2/levels/fortress/fortress-obs.gc +++ b/goal_src/jak2/levels/fortress/fortress-obs.gc @@ -127,11 +127,7 @@ ) (suspend) (ja-channel-set! 0) - (let ((frame-counter (current-time))) - (until (time-elapsed? frame-counter (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event self 'death-end) (while (-> self child) (suspend) @@ -144,11 +140,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this fort-trap-door) (entity entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((cshape (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((prim-mesh (new 'process 'collide-shape-prim-mesh cshape (the-as uint 0) (the-as uint 0)))) (set! (-> prim-mesh prim-core collide-as) (collide-spec obstacle)) diff --git a/goal_src/jak2/levels/fortress/rescue/forresca-obs.gc b/goal_src/jak2/levels/fortress/rescue/forresca-obs.gc index 61ae287dcc..c077453825 100644 --- a/goal_src/jak2/levels/fortress/rescue/forresca-obs.gc +++ b/goal_src/jak2/levels/fortress/rescue/forresca-obs.gc @@ -161,11 +161,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this fort-led) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -220,20 +220,12 @@ This commonly includes things such as: (let ((a0-0 *target*)) (when (and a0-0 (< 81920.0 (vector-vector-distance (get-trans a0-0 0) (-> self root trans)))) (set! (-> self quality-enabled?) #f) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (hide-hud-quick #f) (set-setting! 'entity-name "camera-243" 0.0 0) (set-setting! 'process-mask 'set 0.0 (process-mask movie enemy)) (process-grab? *target* #f) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) ) (go-virtual shutdown) @@ -326,11 +318,7 @@ This commonly includes things such as: ) :code (behavior () (until (-> self all-gone?) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) ) (set-setting! 'interp-time 'abs 0.0 0) (remove-setting! 'entity-name) @@ -368,9 +356,9 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod set-state! ((this elec-lock-gate)) "If either [[actor-option::17]] is set on the [[elec-gate]] or the related subtask is completed -make the gate `idle`. + make the gate `idle`. -Otherwise, the gate will be `active`." + Otherwise, the gate will be `active`." (if (elec-lock-gate-method-31 this #f) (go (method-of-object this shutdown)) ((method-of-type fort-elec-gate set-state!) this) diff --git a/goal_src/jak2/levels/gungame/gungame-obs.gc b/goal_src/jak2/levels/gungame/gungame-obs.gc index 4596f924c4..5afc0708d8 100644 --- a/goal_src/jak2/levels/gungame/gungame-obs.gc +++ b/goal_src/jak2/levels/gungame/gungame-obs.gc @@ -138,6 +138,7 @@ ) (defmethod deactivate ((this training-manager)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (if (handle->process (-> this voicebox)) (send-event (handle->process (-> this voicebox)) 'die) ) @@ -150,11 +151,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this training-path) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s5-0 (length "training-path-")) (a0-3 (length (-> this name))) (v1-2 0) @@ -2142,11 +2143,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this training-manager) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) (set-setting! 'darkjak #f 0.0 0) (set! sv-16 (new 'static 'res-tag)) @@ -2265,12 +2266,7 @@ This commonly includes things such as: ) :code (behavior () (sound-play "gungame-door") - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.2)) - (suspend) - (suspend) - ) - ) + (suspend-for (seconds 0.2) (suspend)) (ja-no-eval :group! fort-entry-gate-idle-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) (suspend) @@ -2412,11 +2408,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this gungame-door) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player)))) (set! (-> s4-0 dynam) (copy *standard-dynamics* 'process)) (set! (-> s4-0 reaction) cshape-reaction-default) diff --git a/goal_src/jak2/levels/intro/intro-obs.gc b/goal_src/jak2/levels/intro/intro-obs.gc index ef53a2f8e9..4d829fcded 100644 --- a/goal_src/jak2/levels/intro/intro-obs.gc +++ b/goal_src/jak2/levels/intro/intro-obs.gc @@ -201,11 +201,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this intro-flamer) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -307,12 +307,8 @@ This commonly includes things such as: (-> s5-0 ppointer) ) ) - (let ((s5-1 (the int (* 300.0 (rand-vu-float-range 0.03 0.08)))) - (s4-0 (current-time)) - ) - (until (time-elapsed? s4-0 s5-1) - (suspend) - ) + (let ((s5-1 (the int (* 300.0 (rand-vu-float-range 0.03 0.08))))) + (suspend-for s5-1) ) ) ) @@ -341,23 +337,23 @@ This commonly includes things such as: ) ) -(defmethod relocate ((this metalhead-spawner) (arg0 int)) +(defmethod relocate ((this metalhead-spawner) (offset int)) (dotimes (v1-0 19) (if (nonzero? (-> this path-tbl v1-0)) - (&+! (-> this path-tbl v1-0) arg0) + (&+! (-> this path-tbl v1-0) offset) ) ) - (call-parent-method this arg0) + (call-parent-method this offset) ) ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this metalhead-spawner) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this init-pos quad) (-> arg0 extra trans quad)) (vector-reset! (-> this average-dir)) (dotimes (s5-0 19) @@ -409,11 +405,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this vil-windmill-sail) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton diff --git a/goal_src/jak2/levels/intro/intro-scenes.gc b/goal_src/jak2/levels/intro/intro-scenes.gc index 08b8fd0c1f..b6b904d95e 100644 --- a/goal_src/jak2/levels/intro/intro-scenes.gc +++ b/goal_src/jak2/levels/intro/intro-scenes.gc @@ -2171,14 +2171,10 @@ (lambda :behavior scene-player () (talker-spawn-func (-> *talker-speech* 123) self (target-pos 0) (the-as region #f)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 5)) - (if (cpad-pressed? 0 square) - (return #f) - ) - (suspend) - ) - ) + (suspend-for (seconds 5) (if (cpad-pressed? 0 square) + (return #f) + ) + ) #f ) :to self @@ -2236,43 +2232,41 @@ (set! (-> gp-0 scale-x) 1.0) (set! (-> gp-0 scale-y) 1.0) (when (and s5-0 (-> gp-0 tex)) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 (seconds 5)) - (let ((f0-2 1.0)) - (cond - ((< f30-0 2.0) - (set! f0-2 (* 0.5 f30-0)) - ) - ((< 3.0 f30-0) - (set! f0-2 (* 0.5 (- 5.0 f30-0))) + (suspend-for + (seconds 5) + (let ((f0-2 1.0)) + (cond + ((< f30-0 2.0) + (set! f0-2 (* 0.5 f30-0)) + ) + ((< 3.0 f30-0) + (set! f0-2 (* 0.5 (- 5.0 f30-0))) + ) + ) + (set! (-> gp-0 color w) (the int (* 128.0 f0-2))) + ) + (let* ((s2-0 (-> *display* frames (-> *display* on-screen) global-buf)) + (s3-0 (-> s2-0 base)) ) + (draw gp-0 s2-0 s5-0) + (let ((a3-0 (-> s2-0 base))) + (let ((v1-31 (the-as object (-> s2-0 base)))) + (set! (-> (the-as dma-packet v1-31) dma) (new 'static 'dma-tag :id (dma-tag-id next))) + (set! (-> (the-as dma-packet v1-31) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet v1-31) vif1) (new 'static 'vif-tag)) + (set! (-> s2-0 base) (&+ (the-as pointer v1-31) 16)) ) - (set! (-> gp-0 color w) (the int (* 128.0 f0-2))) - ) - (let* ((s2-0 (-> *display* frames (-> *display* on-screen) global-buf)) - (s3-0 (-> s2-0 base)) - ) - (draw gp-0 s2-0 s5-0) - (let ((a3-0 (-> s2-0 base))) - (let ((v1-31 (the-as object (-> s2-0 base)))) - (set! (-> (the-as dma-packet v1-31) dma) (new 'static 'dma-tag :id (dma-tag-id next))) - (set! (-> (the-as dma-packet v1-31) vif0) (new 'static 'vif-tag)) - (set! (-> (the-as dma-packet v1-31) vif1) (new 'static 'vif-tag)) - (set! (-> s2-0 base) (&+ (the-as pointer v1-31) 16)) - ) - (dma-bucket-insert-tag - (-> *display* frames (-> *display* on-screen) bucket-group) - (bucket-id subtitle) - s3-0 - (the-as (pointer dma-tag) a3-0) - ) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) bucket-group) + (bucket-id subtitle) + s3-0 + (the-as (pointer dma-tag) a3-0) ) ) - (if (not (paused?)) - (+! f30-0 (seconds-per-frame)) - ) - (suspend) ) + (if (not (paused?)) + (+! f30-0 (seconds-per-frame)) + ) ) #f ) @@ -2361,47 +2355,45 @@ ) ) (when (and s4-0 (-> gp-0 tex)) - (let ((s3-0 (current-time))) - (until (time-elapsed? s3-0 (seconds 8)) - (let ((f0-6 1.0)) - (cond - ((< f30-0 2.0) - (set! f0-6 (* 0.5 f30-0)) - ) - ((< 6.0 f30-0) - (set! f0-6 (* 0.5 (- 8.0 f30-0))) + (suspend-for + (seconds 8) + (let ((f0-6 1.0)) + (cond + ((< f30-0 2.0) + (set! f0-6 (* 0.5 f30-0)) + ) + ((< 6.0 f30-0) + (set! f0-6 (* 0.5 (- 8.0 f30-0))) + ) + ) + (set! (-> gp-0 color w) (the int (* 128.0 f0-6))) + (set! (-> s5-0 color w) (the int (* 128.0 f0-6))) + ) + (let* ((s1-0 (-> *display* frames (-> *display* on-screen) global-buf)) + (s2-0 (-> s1-0 base)) ) + (draw gp-0 s1-0 s4-0) + (if (-> s5-0 tex) + (draw s5-0 s1-0 s4-0) ) - (set! (-> gp-0 color w) (the int (* 128.0 f0-6))) - (set! (-> s5-0 color w) (the int (* 128.0 f0-6))) - ) - (let* ((s1-0 (-> *display* frames (-> *display* on-screen) global-buf)) - (s2-0 (-> s1-0 base)) - ) - (draw gp-0 s1-0 s4-0) - (if (-> s5-0 tex) - (draw s5-0 s1-0 s4-0) - ) - (let ((a3-0 (-> s1-0 base))) - (let ((v1-59 (the-as object (-> s1-0 base)))) - (set! (-> (the-as dma-packet v1-59) dma) (new 'static 'dma-tag :id (dma-tag-id next))) - (set! (-> (the-as dma-packet v1-59) vif0) (new 'static 'vif-tag)) - (set! (-> (the-as dma-packet v1-59) vif1) (new 'static 'vif-tag)) - (set! (-> s1-0 base) (&+ (the-as pointer v1-59) 16)) - ) - (dma-bucket-insert-tag - (-> *display* frames (-> *display* on-screen) bucket-group) - (bucket-id subtitle) - s2-0 - (the-as (pointer dma-tag) a3-0) - ) + (let ((a3-0 (-> s1-0 base))) + (let ((v1-59 (the-as object (-> s1-0 base)))) + (set! (-> (the-as dma-packet v1-59) dma) (new 'static 'dma-tag :id (dma-tag-id next))) + (set! (-> (the-as dma-packet v1-59) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet v1-59) vif1) (new 'static 'vif-tag)) + (set! (-> s1-0 base) (&+ (the-as pointer v1-59) 16)) ) - ) - (if (not (paused?)) - (+! f30-0 (seconds-per-frame)) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) bucket-group) + (bucket-id subtitle) + s2-0 + (the-as (pointer dma-tag) a3-0) ) - (suspend) + ) ) + (if (not (paused?)) + (+! f30-0 (seconds-per-frame)) + ) ) #f ) diff --git a/goal_src/jak2/levels/mountain/mountain-obs.gc b/goal_src/jak2/levels/mountain/mountain-obs.gc index 11e8a25633..037cd8921f 100644 --- a/goal_src/jak2/levels/mountain/mountain-obs.gc +++ b/goal_src/jak2/levels/mountain/mountain-obs.gc @@ -1287,11 +1287,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this mtn-dice) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 6) 0))) (set! (-> s4-0 total-prims) (the-as uint 7)) @@ -1457,10 +1457,10 @@ This commonly includes things such as: (defmethod move-between-points ((this mtn-plat-elevator) (arg0 vector) (arg1 float) (arg2 float)) "Move between two points on the elevator's path -@param vec TODO not sure -@param point-a The first point fetched from the elevator's path -@param point-b The second point fetched from the path -@see [[path-control]] and [[elevator]]" + @param vec TODO not sure + @param point-a The first point fetched from the elevator's path + @param point-b The second point fetched from the path + @see [[path-control]] and [[elevator]]" (let ((s4-0 (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) arg1 'interp)) (a0-3 (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) arg2 'interp)) ) @@ -1565,11 +1565,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this mtn-plat-updown) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (init-plat-collision! this) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -1701,11 +1701,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this mtn-plat-eject) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (mtn-plat-eject-method-22 this) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -1793,11 +1793,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this mtn-plat-long) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (init-plat-collision! this) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -1861,21 +1861,13 @@ This commonly includes things such as: (suspend) ) (set-setting! 'entity-name "camera-259" 0.0 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (ja-no-eval :group! (ja-group) :num! (seek!) :frame-num 0.0) (until (ja-done? 0) (suspend) (ja :num! (seek!)) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (until (process-release? *target*) (suspend) ) @@ -1887,11 +1879,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this mtn-gate) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 2) 0))) (set! (-> s4-0 total-prims) (the-as uint 3)) @@ -1956,11 +1948,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch process-drawable vs mtn-aval-rocks. -(defmethod relocate ((this mtn-aval-rocks) (arg0 int)) +(defmethod relocate ((this mtn-aval-rocks) (offset int)) (if (nonzero? (-> this rock-data)) - (&+! (-> this rock-data) arg0) + (&+! (-> this rock-data) offset) ) - (the-as mtn-aval-rocks ((method-of-type process-drawable relocate) this arg0)) + (the-as mtn-aval-rocks ((method-of-type process-drawable relocate) this offset)) ) (deftype mtn-aval-rocks-shadow (process-drawable) @@ -2339,11 +2331,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this mtn-aval-rocks) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 collide-shape-prim-sphere) (sv-48 collide-shape-prim-sphere) (sv-64 vector)) (stack-size-set! (-> this main-thread) 512) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) @@ -2644,11 +2636,11 @@ This commonly includes things such as: (defmethod init-from-entity! ((this mtn-plat-return) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (init-plat-collision! this) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -2811,11 +2803,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this mtn-button) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 2) 0))) (set! (-> s4-0 total-prims) (the-as uint 3)) @@ -2914,11 +2906,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this mtn-gear-device) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (cond ((task-complete? *game-info* (game-task mountain-gear)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) @@ -3210,7 +3202,7 @@ This commonly includes things such as: ;; WARN: Return type mismatch float vs none. (defmethod init-plat! ((this trans-plat)) "Does any necessary initial platform setup. -For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." + For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." (logior! (-> this flags) (mtn-plat-flags mtpflags-1)) (let* ((s5-0 *target*) (a0-2 (if (type? s5-0 process-focusable) diff --git a/goal_src/jak2/levels/nest/boss/nestb-scenes.gc b/goal_src/jak2/levels/nest/boss/nestb-scenes.gc index e29ad32473..fd3e34bb3e 100644 --- a/goal_src/jak2/levels/nest/boss/nestb-scenes.gc +++ b/goal_src/jak2/levels/nest/boss/nestb-scenes.gc @@ -20,17 +20,9 @@ (set! (-> a1-0 message) 'test-pickup) (set! (-> a1-0 param 0) (the-as uint 7)) (let ((f30-0 (send-event-function *target* a1-0))) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) (send-event *target* 'change-mode 'darkjak #f (darkjak-stage no-anim)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) (send-event *target* 'get-pickup (pickup-type eco-pill-dark) f30-0) ) ) @@ -1638,11 +1630,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this nest-gun-parts) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -1687,11 +1679,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this nest-unbroken-rocks) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton diff --git a/goal_src/jak2/levels/nest/mantis.gc b/goal_src/jak2/levels/nest/mantis.gc index 135935ce91..a826283f8a 100644 --- a/goal_src/jak2/levels/nest/mantis.gc +++ b/goal_src/jak2/levels/nest/mantis.gc @@ -523,17 +523,9 @@ ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.6)) - (suspend) - ) - ) + (suspend-for (seconds 0.6)) (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) (logclear! (-> self draw status) (draw-control-status no-draw)) (if (rnd-percent? self 0.5) (go-virtual ambush-jumping) @@ -637,14 +629,10 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (if (logtest? (-> self root status) (collide-status on-ground)) - (goto cfg-32) - ) - (suspend) - ) - ) + (suspend-for (seconds 1) (if (logtest? (-> self root status) (collide-status on-ground)) + (goto cfg-32) + ) + ) (label cfg-32) (go-virtual hostile) ) @@ -1188,7 +1176,7 @@ (defmethod general-event-handler ((this mantis) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (case arg2 (('track) (if (and (-> arg3 param 0) (time-elapsed? (-> this track-timer) (seconds 0.5))) @@ -1437,9 +1425,9 @@ ;; WARN: Return type mismatch vector vs none. (defmethod common-post ((this mantis)) "Does a lot of various things relating to interacting with the target -- tracks when the enemy was last drawn -- looks at the target and handles attacking -@TODO Not extremely well understood yet" + - tracks when the enemy was last drawn + - looks at the target and handles attacking + @TODO Not extremely well understood yet" (local-vars (s5-0 vector)) (let ((t9-0 (method-of-type nav-enemy common-post))) (t9-0 this) diff --git a/goal_src/jak2/levels/nest/nest-obs.gc b/goal_src/jak2/levels/nest/nest-obs.gc index 6c904eecdc..da8a0c51d9 100644 --- a/goal_src/jak2/levels/nest/nest-obs.gc +++ b/goal_src/jak2/levels/nest/nest-obs.gc @@ -90,22 +90,16 @@ (set! (-> self root trans y) (+ (-> self y-start) (-> self y-delta))) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (seek! (-> self y-rot-rate) 0.0 (* 4000.0 (seconds-per-frame))) - (quaternion-rotate-y! - (-> self root quat) - (-> self root quat) - (* 182.04445 (seconds-per-frame) (-> self y-rot-rate)) - ) - (suspend) - ) - ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) + (suspend-for + (seconds 1) + (seek! (-> self y-rot-rate) 0.0 (* 4000.0 (seconds-per-frame))) + (quaternion-rotate-y! + (-> self root quat) + (-> self root quat) + (* 182.04445 (seconds-per-frame) (-> self y-rot-rate)) ) ) + (suspend-for (seconds 1)) (remove-setting! 'entity-name) (remove-setting! 'process-mask) (process-release? *target*) @@ -118,11 +112,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this nest-switch) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 3) 0))) (set! (-> s4-0 total-prims) (the-as uint 4)) @@ -204,11 +198,7 @@ This commonly includes things such as: :virtual #t :trans rider-trans :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while (< (-> self y-offset) 16384.0) (seek! (-> self y-offset) 16384.0 (* 8192.0 (seconds-per-frame))) (set! (-> self root trans y) (+ (-> self y-level) (-> self y-offset))) @@ -223,11 +213,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this nest-piston) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) (set! (-> s3-0 prim-core collide-as) (collide-spec obstacle pusher)) diff --git a/goal_src/jak2/levels/sewer/sew-gunturret.gc b/goal_src/jak2/levels/sewer/sew-gunturret.gc index eb4431966e..dc2355a9b2 100644 --- a/goal_src/jak2/levels/sewer/sew-gunturret.gc +++ b/goal_src/jak2/levels/sewer/sew-gunturret.gc @@ -520,7 +520,7 @@ (defmethod aim-turret! ((this sew-gunturret) (aim-at-target? symbol)) "Calculates the angle and tilt for the turret to either aim at the target, or it's default direction -@param aim-at-target? Whether or not the turret should aim at the target, will ignore the target if #f" + @param aim-at-target? Whether or not the turret should aim at the target, will ignore the target if #f" (cond ((and aim-at-target? (-> this los-clear)) (let ((target-proc (handle->process (-> this focus handle)))) @@ -642,7 +642,7 @@ (defmethod fire-turret! ((this sew-gunturret) (fire-sound? symbol)) "Actually fires the turret, sets `flash-state` to [[#t]] -@param fire-sound? Whether to play the fire sound effect or not" + @param fire-sound? Whether to play the fire sound effect or not" (let ((v1-4 (vector<-cspace! (new 'stack-no-clear 'vector) (-> this node-list data (-> this params gun-joint)))) (proj-params (new 'stack-no-clear 'projectile-init-by-other-params)) ) @@ -722,51 +722,42 @@ ) (update-collision! self) (sound-play "sew-gun-lock") - (let ((frame-counter (current-time))) - (until (time-elapsed? frame-counter (seconds 0.75)) - (aim-turret! self #t) - (suspend) - ) - ) + (suspend-for (seconds 0.75) (aim-turret! self #t)) (ja :group! (-> self draw art-group data (-> self params shoot-anim))) (let ((frames 0) (fire-sound? #t) ) (sound-play "gturret") - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.125)) - (cond - ((not (-> self can-shoot)) - ) - ((time-elapsed? (the-as time-frame frames) (seconds 0.05)) - (fire-turret! self fire-sound?) - (set! frames (the-as int (current-time))) - (set! fire-sound? (not fire-sound?)) - ) - (else - (set! (-> self flash-state) #f) - ) + (suspend-for + (seconds 0.125) + (cond + ((not (-> self can-shoot)) + ) + ((time-elapsed? (the-as time-frame frames) (seconds 0.05)) + (fire-turret! self fire-sound?) + (set! frames (the-as int (current-time))) + (set! fire-sound? (not fire-sound?)) + ) + (else + (set! (-> self flash-state) #f) ) - (ja :num! (loop!)) - (suspend) ) + (ja :num! (loop!)) ) ) (set! (-> self flash-state) #f) (ja-channel-push! 1 (seconds 0.2)) (ja :group! (-> self draw art-group data (-> self params idle-anim))) - (let ((_frame-counter (current-time))) - (until (time-elapsed? _frame-counter (seconds 0.5)) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 0))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 1))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 2))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 3))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 4))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 5))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 6))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 7))) - (suspend) - ) + (suspend-for + (seconds 0.5) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 0))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 1))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 2))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 3))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 4))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 5))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 6))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 7))) ) ) #f @@ -789,7 +780,7 @@ (defmethod general-event-handler ((this sew-gunturret) (proc process) (arg2 int) (event-type symbol) (event event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (if (and (= event-type 'notify) (< 1 arg2) (= (-> event param 0) 'attack) (= (-> event param 1) *target*)) (set-time! (-> this last-hit-time)) ) @@ -854,18 +845,9 @@ (let ((vec (new 'stack-no-clear 'vector))) (set! (-> vec quad) (-> self root trans quad)) (+! (-> vec y) 10240.0) - (let ((frame-counter (current-time))) - (until (time-elapsed? frame-counter (seconds 2)) - (spawn (-> self part) vec) - (suspend) - ) - ) - ) - (let ((_frame-counter (current-time))) - (until (time-elapsed? _frame-counter (seconds 1)) - (suspend) - ) + (suspend-for (seconds 2) (spawn (-> self part) vec)) ) + (suspend-for (seconds 1)) (send-event self 'death-end) (while (-> self child) (suspend) @@ -938,10 +920,10 @@ (defmethod in-aggro-range? ((this sew-gunturret) (proc process-focusable) (arg1 vector)) "Should the enemy activate. -- if `activate-distance` is `0.0`, always true -- otherwise, check if the provided process is close enough -@param proc The process used to distance check -@returns true/false" + - if `activate-distance` is `0.0`, always true + - otherwise, check if the provided process is close enough + @param proc The process used to distance check + @returns true/false" (cond ((= (-> this activate-distance) 0.0) (return #t) @@ -961,6 +943,7 @@ ) (defmethod deactivate ((this sew-gunturret)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (if (nonzero? (-> this smoke-part)) (kill-and-free-particles (-> this smoke-part)) ) @@ -977,17 +960,17 @@ ) ;; WARN: Return type mismatch enemy vs sew-gunturret. -(defmethod relocate ((this sew-gunturret) (arg0 int)) +(defmethod relocate ((this sew-gunturret) (offset int)) (if (nonzero? (-> this gun-tilt-jm)) - (&+! (-> this gun-tilt-jm) arg0) + (&+! (-> this gun-tilt-jm) offset) ) (if (nonzero? (-> this smoke-part)) - (&+! (-> this smoke-part) arg0) + (&+! (-> this smoke-part) offset) ) (if (nonzero? (-> this casing-part)) - (&+! (-> this casing-part) arg0) + (&+! (-> this casing-part) offset) ) - (the-as sew-gunturret ((method-of-type enemy relocate) this arg0)) + (the-as sew-gunturret ((method-of-type enemy relocate) this offset)) ) (defmethod init-turret-params! ((this sew-gunturret)) diff --git a/goal_src/jak2/levels/sewer/sewer-obs2.gc b/goal_src/jak2/levels/sewer/sewer-obs2.gc index 1add5309a2..03c16aed46 100644 --- a/goal_src/jak2/levels/sewer/sewer-obs2.gc +++ b/goal_src/jak2/levels/sewer/sewer-obs2.gc @@ -28,10 +28,10 @@ (defmethod move-between-points ((this sew-elevator) (arg1 vector) (point-a float) (point-b float)) "Move between two points on the elevator's path -@param vec TODO not sure -@param point-a The first point fetched from the elevator's path -@param point-b The second point fetched from the path -@see [[path-control]] and [[elevator]]" + @param vec TODO not sure + @param point-a The first point fetched from the elevator's path + @param point-b The second point fetched from the path + @see [[path-control]] and [[elevator]]" (let ((path-point-a (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) point-a 'interp)) (path-point-b (get-point-in-path! (-> this path) (new 'stack-no-clear 'vector) point-b 'interp)) (elevator-pos (-> this root trans)) @@ -69,7 +69,7 @@ (defmethod configure-collision ((this sew-elevator) (collide-with-jak? symbol)) "Appropriately sets the collision on the elevator -@param collide-with-jak? If set, the elevator will collide with Jak" + @param collide-with-jak? If set, the elevator will collide with Jak" (let ((prim-group (-> (the-as collide-shape-prim-group (-> this root root-prim)) child 1))) (cond (collide-with-jak? @@ -131,6 +131,7 @@ ) (defmethod deactivate ((this sew-elevator)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (sound-stop (-> this sound-id)) (call-parent-method this) (none) @@ -138,7 +139,7 @@ (defmethod init-plat! ((this sew-elevator)) "Does any necessary initial platform setup. -For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." + For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." (set! (-> this sound-id) (new-sound-id)) 0 (none) @@ -146,11 +147,11 @@ For example for an elevator pre-compute the distance between the first and last (defmethod init-defaults! ((this sew-elevator)) "Initializes default settings related to the [[elevator]]: -- `elevator-xz-threshold` -- `elevator-y-threshold` -- `elevator-start-pos` -- `elevator-move-rate` -- `elevator-flags`" + - `elevator-xz-threshold` + - `elevator-y-threshold` + - `elevator-start-pos` + - `elevator-move-rate` + - `elevator-flags`" (let ((func (method-of-type elevator init-defaults!))) (func this) ) @@ -305,21 +306,21 @@ For example for an elevator pre-compute the distance between the first and last ) ) -(defmethod relocate ((this sew-valve) (arg0 int)) +(defmethod relocate ((this sew-valve) (offset int)) (if (nonzero? (-> this joint)) - (&+! (-> this joint) arg0) + (&+! (-> this joint) offset) ) - (call-parent-method this arg0) + (call-parent-method this offset) ) ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this sew-valve) (entity entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (tag-1 res-tag) (tag-2 res-tag)) (let ((cshape (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player)))) (set! (-> cshape dynam) (copy *standard-dynamics* 'process)) @@ -526,6 +527,7 @@ This commonly includes things such as: ) (defmethod run-logic? ((this sew-mar-statue)) + "Should this process be run? Checked by execute-process-tree." #t ) @@ -558,11 +560,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this sew-mar-statue) (entity entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this spawned-debris?) #f) (let ((cshape (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((prim-mesh (new 'process 'collide-shape-prim-mesh cshape (the-as uint 0) (the-as uint 0)))) @@ -616,8 +618,8 @@ This commonly includes things such as: (defmethod start-bouncing! ((this sew-catwalk)) "Sets `bouncing` to [[#t]] and sets up the clock to periodically bounce -and translate the platform via the `smush` -@see [[smush-control]]" + and translate the platform via the `smush` + @see [[smush-control]]" (logclear! (-> this mask) (process-mask sleep)) (logclear! (-> this mask) (process-mask sleep-code)) 0 @@ -660,11 +662,11 @@ and translate the platform via the `smush` ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this sew-catwalk) (entity entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 collide-shape-prim-mesh) (sv-32 symbol) (sv-48 type) (sv-64 collide-shape-moving)) (stack-size-set! (-> this main-thread) 512) (let ((cshape (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player)))) @@ -859,11 +861,7 @@ This commonly includes things such as: ) ) (cleanup-for-death self) - (let ((frame-counter (current-time))) - (until (time-elapsed? frame-counter (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) ) @@ -888,11 +886,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this sew-mine-a) (entity entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((cshape (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((prim-mesh (new 'process 'collide-shape-prim-mesh cshape (the-as uint 0) (the-as uint 0)))) (set! (-> prim-mesh prim-core collide-as) (collide-spec pusher)) @@ -968,11 +966,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this sew-mine-b) (entity entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((cshape (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((prim-mesh (new 'process 'collide-shape-prim-mesh cshape (the-as uint 0) (the-as uint 0)))) (set! (-> prim-mesh prim-core collide-as) (collide-spec pusher)) @@ -1192,11 +1190,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this sew-wall) (entity entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (stack-size-set! (-> this main-thread) 512) (logior! (-> this mask) (process-mask collectable)) (let ((data ((method-of-type res-lump get-property-struct) @@ -1336,11 +1334,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this sew-grill) (entity entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this entity) (initialize-skeleton diff --git a/goal_src/jak2/levels/stadium/skate/skatea-obs.gc b/goal_src/jak2/levels/stadium/skate/skatea-obs.gc index 7f43097cff..51b9d596aa 100644 --- a/goal_src/jak2/levels/stadium/skate/skatea-obs.gc +++ b/goal_src/jak2/levels/stadium/skate/skatea-obs.gc @@ -339,11 +339,7 @@ (suspend) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event (handle->process (-> self voicebox)) 'speak-effect #t) (set! (-> self last-sound-id) (add-process *gui-control* self (gui-channel sig) (gui-action play) "kei006" -99.0 0) @@ -379,11 +375,7 @@ (suspend) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event (handle->process (-> self voicebox)) 'speak-effect #t) (set! (-> self last-sound-id) (add-process *gui-control* self (gui-channel sig) (gui-action play) "kei008" -99.0 0) @@ -452,11 +444,7 @@ (while (nonzero? (get-status *gui-control* (-> self last-sound-id))) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (set! (-> self last-sound-id) (add-process *gui-control* self (gui-channel sig) (gui-action play) "kei013" -99.0 0) ) @@ -517,11 +505,7 @@ (suspend) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event (handle->process (-> self voicebox)) 'speak-effect #t) (set! (-> self last-sound-id) (add-process *gui-control* self (gui-channel sig) (gui-action play) "kei010" -99.0 0) @@ -557,11 +541,7 @@ (suspend) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event (handle->process (-> self voicebox)) 'speak-effect #t) (set! (-> self last-sound-id) (add-process *gui-control* self (gui-channel sig) (gui-action play) "kei016" -99.0 0) @@ -594,11 +574,7 @@ (suspend) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event (handle->process (-> self voicebox)) 'speak-effect #t) (set! (-> self last-sound-id) (add-process *gui-control* self (gui-channel sig) (gui-action play) "kei017" -99.0 0) @@ -1081,11 +1057,7 @@ ) ) ) - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event (handle->process gp-3) 'die) ) ) @@ -1289,11 +1261,7 @@ ) ) ) - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event (handle->process gp-2) 'die) ) ) @@ -1310,6 +1278,7 @@ ) (defmethod deactivate ((this hoverboard-training-manager)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (send-event *traffic-manager* 'restore-default-settings) (call-parent-method this) (none) @@ -1318,11 +1287,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this hoverboard-training-manager) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" ;; og:preserve-this added (stack-size-set! (-> this main-thread) 1024) (local-vars (sv-16 res-tag)) @@ -1490,11 +1459,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this skate-training-ramp) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (skate-training-ramp-method-28 this) (process-drawable-from-entity! this arg0) (logclear! (-> this mask) (process-mask actor-pause)) @@ -1611,11 +1580,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this skate-gate) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (skate-gate-method-29 this) (process-drawable-from-entity! this arg0) (logclear! (-> this mask) (process-mask actor-pause)) @@ -1853,11 +1822,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this skatea-floating-ring) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (skatea-floating-ring-method-28 this) (process-drawable-from-entity! this arg0) (initialize-skeleton diff --git a/goal_src/jak2/levels/stadium/stadium-obs.gc b/goal_src/jak2/levels/stadium/stadium-obs.gc index cb706754c3..f26ca34e10 100644 --- a/goal_src/jak2/levels/stadium/stadium-obs.gc +++ b/goal_src/jak2/levels/stadium/stadium-obs.gc @@ -66,11 +66,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this dummy-vehicle) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player)))) (set! (-> s4-0 dynam) (copy *standard-dynamics* 'process)) (set! (-> s4-0 reaction) cshape-reaction-default) @@ -174,11 +174,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this gar-curtain) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 collide-shape-prim-mesh) (sv-32 symbol) (sv-48 type) (sv-64 collide-shape)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 8) 0))) @@ -857,11 +857,7 @@ This commonly includes things such as: ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.2)) - (suspend) - ) - ) + (suspend-for (seconds 1.2)) (rigid-body-object-method-39 self) (sleep-code) ) @@ -1062,11 +1058,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this spotlight) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -1092,11 +1088,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this gar-door) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" ;; og:preserve-this added (stack-size-set! (-> this main-thread) 560) (let ((s5-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) @@ -1454,11 +1450,7 @@ This commonly includes things such as: ) ) (set! (-> self rift-rider-actor) (entity-actor-lookup (-> self entity) 'alt-actor 0)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.31)) - (suspend) - ) - ) + (suspend-for (seconds 0.31)) ) (ja-no-eval :group! (-> self draw art-group data (-> self stand-anim)) :num! (seek!) :frame-num 0.0) (until (ja-done? 0) @@ -1878,11 +1870,7 @@ This commonly includes things such as: ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (send-event *camera* 'change-target #f) (cleanup-for-death self) ) @@ -1948,11 +1936,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this stad-samos) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" ;; og:preserve-this added (stack-size-set! (-> this main-thread) #x180) (let ((s4-0 (new 'process 'collide-shape-moving this (collide-list-enum hit-by-others)))) @@ -2232,11 +2220,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch entity-perm-status vs none. (defmethod init-from-entity! ((this stadium-barrier) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (process-entity-status! this (entity-perm-status dead) #t) (none) ) @@ -2568,11 +2556,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this stad-force-field) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (stad-force-field-method-28 this) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -2601,11 +2589,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this stad-c-force-field) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (stad-force-field-method-28 this) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -2634,11 +2622,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this stad-d-force-field) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (stad-force-field-method-28 this) (process-drawable-from-entity! this arg0) (initialize-skeleton @@ -2858,11 +2846,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this brutter-balloon) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 3) 0))) (set! (-> s4-0 total-prims) (the-as uint 4)) diff --git a/goal_src/jak2/levels/title/title-obs.gc b/goal_src/jak2/levels/title/title-obs.gc index 3a4ce493a7..fcf28b96bf 100644 --- a/goal_src/jak2/levels/title/title-obs.gc +++ b/goal_src/jak2/levels/title/title-obs.gc @@ -35,16 +35,17 @@ ;; WARN: Return type mismatch process vs title-control. -(defmethod relocate ((this title-control) (arg0 int)) +(defmethod relocate ((this title-control) (offset int)) (dotimes (v1-0 2) (if (nonzero? (-> this buffer v1-0)) - (&+! (-> this buffer v1-0) arg0) + (&+! (-> this buffer v1-0) offset) ) ) - (the-as title-control ((method-of-type process relocate) this arg0)) + (the-as title-control ((method-of-type process relocate) this offset)) ) (defmethod deactivate ((this title-control)) + "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (dotimes (s5-0 2) (set-pending-file (-> this buffer s5-0) (the-as string #f) -1 (the-as handle #f) 100000000.0) ) @@ -555,11 +556,7 @@ (defun title-fade-out ((arg0 float)) (setup *screen-filter* (new 'static 'vector) (new 'static 'vector :w 128.0) arg0 (bucket-id screen-filter)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.4)) - (suspend) - ) - ) + (suspend-for (seconds 0.4)) (send-event (ppointer->process (-> *setting-control* user-current movie)) 'abort) (set! (-> *setting-control* user-current bg-a) 0.0) (while (or (-> *setting-control* user-current movie) diff --git a/goal_src/jak2/levels/tomb/target-indax.gc b/goal_src/jak2/levels/tomb/target-indax.gc index 8abca68adc..b28a0ab668 100644 --- a/goal_src/jak2/levels/tomb/target-indax.gc +++ b/goal_src/jak2/levels/tomb/target-indax.gc @@ -699,7 +699,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (if (logtest? (-> self control status) (collide-status on-surface)) @@ -1234,11 +1234,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (move-to-point! (-> self control) s4-1) ) (set! (-> self control camera-pos quad) (-> self control trans quad)) diff --git a/goal_src/jak2/levels/tomb/tomb-beetle.gc b/goal_src/jak2/levels/tomb/tomb-beetle.gc index 53e0cdd4a1..f083dce4cb 100644 --- a/goal_src/jak2/levels/tomb/tomb-beetle.gc +++ b/goal_src/jak2/levels/tomb/tomb-beetle.gc @@ -187,7 +187,7 @@ (defmethod general-event-handler ((this tomb-beetle) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) "Handles various events for the enemy -@TODO - unsure if there is a pattern for the events and this should have a more specific name" + @TODO - unsure if there is a pattern for the events and this should have a more specific name" (let ((v1-0 (new 'static 'array int64 2 -1 0))) (case arg2 (('cue-chase) @@ -730,11 +730,7 @@ (-> gp-1 ppointer) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) :post nav-enemy-simple-post ) diff --git a/goal_src/jak2/levels/tomb/tomb-water.gc b/goal_src/jak2/levels/tomb/tomb-water.gc index 49325adb8a..c283b902e1 100644 --- a/goal_src/jak2/levels/tomb/tomb-water.gc +++ b/goal_src/jak2/levels/tomb/tomb-water.gc @@ -123,11 +123,7 @@ ) ) :code (behavior ((arg0 time-frame)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 arg0) - (suspend) - ) - ) + (suspend-for arg0) (ja-no-eval :group! tomb-door-open-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) (-> self root quat) @@ -142,11 +138,11 @@ ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this tomb-door) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 2) 0))) (set! (-> s4-0 total-prims) (the-as uint 3)) @@ -311,11 +307,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this tomb-beetle-door) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 2) 0))) @@ -642,9 +638,9 @@ This commonly includes things such as: ;; WARN: Return type mismatch symbol vs none. (defmethod send-event! ((this tomb-beetle-button) (arg0 symbol)) "Prepares an [[event-message-block]] using the provided type to send an event to: -- the `notify-actor` -- every [[entity-actor]] in the `actor-group` array -@see [[entity-actor]]" + - the `notify-actor` + - every [[entity-actor]] in the `actor-group` array + @see [[entity-actor]]" (when arg0 (let ((a1-1 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-1 from) (process->ppointer self)) @@ -942,11 +938,7 @@ This commonly includes things such as: ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (go-virtual show-sequence) ) ) @@ -1012,21 +1004,21 @@ This commonly includes things such as: ) ;; WARN: Return type mismatch process-drawable vs tomb-plat-simon. -(defmethod relocate ((this tomb-plat-simon) (arg0 int)) +(defmethod relocate ((this tomb-plat-simon) (offset int)) (if (nonzero? (-> this plat)) - (&+! (-> this plat) arg0) + (&+! (-> this plat) offset) ) - (the-as tomb-plat-simon ((method-of-type process-drawable relocate) this arg0)) + (the-as tomb-plat-simon ((method-of-type process-drawable relocate) this offset)) ) ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this tomb-plat-simon) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) @@ -1403,17 +1395,9 @@ This commonly includes things such as: :virtual #t :code (behavior () (set! (-> self move-rate) (* 4096.0 (rand-vu-float-range 0.5 1.5))) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (logclear! (-> self root root-prim prim-core action) (collide-action rideable)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (cleanup-for-death self) ) :post (behavior () @@ -1644,11 +1628,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this tomb-simon-button) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 5) 0))) (set! (-> s4-0 total-prims) (the-as uint 6)) @@ -1805,11 +1789,7 @@ This commonly includes things such as: ) ) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.45)) - (suspend) - ) - ) + (suspend-for (seconds 0.45)) ) #f ) @@ -1947,11 +1927,7 @@ This commonly includes things such as: 0 ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (persist-with-delay *setting-control* (the-as symbol (process->ppointer self)) @@ -1961,11 +1937,7 @@ This commonly includes things such as: 0.0 (+ (-> self pat-tbl (-> self pat-index)) 18) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (process-grab? *target* #f) (let ((gp-2 (current-time)) (s5-0 540) @@ -2052,11 +2024,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this tomb-vibe) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag) (sv-32 res-tag)) (with-pp (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum hit-by-player)))) @@ -2254,10 +2226,9 @@ This commonly includes things such as: :code (behavior () (until #f (set! (-> self can-exit-running?) #f) - (let ((gp-0 0) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 (-> self on-duration)) + (let ((gp-0 0)) + (suspend-for + (-> self on-duration) (when (< (-> self harmless-time) (current-time)) (tomb-water-trap-method-22 self) (dotimes (s4-0 (+ (-> self path curve num-cverts) -1)) @@ -2295,29 +2266,19 @@ This commonly includes things such as: (+! gp-0 1) ) ) - (suspend) ) ) (set! (-> self can-exit-running?) #t) (let ((gp-1 90)) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 gp-1) - (suspend) - ) - ) - (let ((s5-2 #f) - (s4-2 (current-time)) - ) - (until (time-elapsed? - s4-2 - (the-as time-frame (- (- (-> self sync period) (the-as uint (-> self on-duration))) (the-as uint gp-1))) - ) - (when (and (not s5-2) (time-elapsed? s4-2 (seconds 0.3))) + (suspend-for gp-1) + (let ((s5-2 #f)) + (suspend-for + (the-as time-frame (- (- (-> self sync period) (the-as uint (-> self on-duration))) (the-as uint gp-1))) + (when (and (not s5-2) (time-elapsed? time (seconds 0.3))) (set! s5-2 #t) (set-tombc-electricity-scale! 0.0) ) (seek! (-> self volume) 0.0 (* 2.0 (seconds-per-frame))) - (suspend) ) ) ) @@ -2424,21 +2385,21 @@ This commonly includes things such as: ) ;; WARN: Return type mismatch process-drawable vs tomb-water-trap. -(defmethod relocate ((this tomb-water-trap) (arg0 int)) +(defmethod relocate ((this tomb-water-trap) (offset int)) (if (nonzero? (-> this l-index)) - (&+! (-> this l-index) arg0) + (&+! (-> this l-index) offset) ) - (the-as tomb-water-trap ((method-of-type process-drawable relocate) this arg0)) + (the-as tomb-water-trap ((method-of-type process-drawable relocate) this offset)) ) ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this tomb-water-trap) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this root) (new 'process 'trsqv)) (process-drawable-from-entity! this arg0) (let ((a1-3 (new 'stack-no-clear 'sync-info-params))) @@ -2617,11 +2578,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this tomb-smash-door) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 2) 0))) (set! (-> s4-0 total-prims) (the-as uint 3)) diff --git a/goal_src/jak2/levels/under/under-sig-obs.gc b/goal_src/jak2/levels/under/under-sig-obs.gc index 7b050b7057..9170f834b2 100644 --- a/goal_src/jak2/levels/under/under-sig-obs.gc +++ b/goal_src/jak2/levels/under/under-sig-obs.gc @@ -107,7 +107,7 @@ (defmethod init-plat! ((this under-plat-shoot)) "Does any necessary initial platform setup. -For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." + For example for an elevator pre-compute the distance between the first and last points (both ways) and clear the sound." (logclear! (-> this mask) (process-mask actor-pause)) (logior! (-> this mask) (process-mask enemy)) (set-vector! (-> this axe-flip) 1.0 0.0 0.0 1.0) @@ -403,9 +403,9 @@ For example for an elevator pre-compute the distance between the first and last (defmethod plat-path-sync ((this under-plat-shoot)) "If the `sync` period is greater than `0` then transition the state to [[plat::35]] -otherwise, [[plat::34]] + otherwise, [[plat::34]] -@see [[sync-eased]]" + @see [[sync-eased]]" (cond ((and (script-eval (the-as pair (-> this draw-test-script))) (= *bot-record-path* -1)) (go (method-of-object this dormant)) @@ -505,11 +505,7 @@ otherwise, [[plat::34]] ) (suspend) (ja-channel-set! 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event self 'death-end) (while (-> self child) (suspend) @@ -529,11 +525,11 @@ otherwise, [[plat::34]] ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this under-break-floor) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 2) 0))) (set! (-> s4-0 total-prims) (the-as uint 3)) @@ -620,11 +616,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this under-break-wall) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((v1-2 (new 'process 'collide-shape-prim-mesh s4-0 (the-as uint 0) (the-as uint 0)))) @@ -738,11 +734,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this under-break-bridge) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) (set! (-> this bridge-id) (res-lump-value (-> this entity) 'extra-id int :time -1000000000.0)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) @@ -867,11 +863,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this under-int-door) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) (let ((s4-0 (new 'process 'collide-shape this (collide-list-enum usually-hit-by-player)))) (let ((s3-0 (new 'process 'collide-shape-prim-group s4-0 (the-as uint 2) 0))) @@ -1014,11 +1010,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this under-plat-long) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (local-vars (sv-16 res-tag)) (init-plat-collision! this) (process-drawable-from-entity! this arg0) @@ -1150,11 +1146,11 @@ This commonly includes things such as: ;; WARN: Return type mismatch object vs none. (defmethod init-from-entity! ((this under-plat-wall) (arg0 entity-actor)) "Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that. -This commonly includes things such as: -- stack size -- collision information -- loading the skeleton group / bones -- sounds" + This commonly includes things such as: + - stack size + - collision information + - loading the skeleton group / bones + - sounds" (set! (-> this extended-amount) 0.0) (logior! (-> this mask) (process-mask platform)) (set! (-> this clock) (-> *display* user0-clock)) diff --git a/goal_src/jak2/pc/features/autosplit-h.gc b/goal_src/jak2/pc/features/autosplit-h.gc index 4bf86a56dd..2e5bdefe75 100644 --- a/goal_src/jak2/pc/features/autosplit-h.gc +++ b/goal_src/jak2/pc/features/autosplit-h.gc @@ -127,6 +127,13 @@ (res-stadium-burning-bush-race-class3-r uint8) (res-stadium-burning-bush-race-class2-r uint8) (res-stadium-burning-bush-race-class1-r uint8) + ;; misc other task-nodes + (tomb-poles-poles uint8) ;; left tomb/daxter boulder start + (fortress-save-friends-introduction uint8) ;; talk to torn (before rescue friends) + (sewer-escort-get-gun uint8) ;; get peacemaker + (forest-protect-introduction uint8) ;; talk to onin (protect samos) + (forest-protect-meeting uint8) ;; talk to samos (protect samos) + ;; TODO - orbs in level X ;; end marker just to make things look nice in a memory view (end-marker uint8 4)) diff --git a/goal_src/jak2/pc/features/autosplit.gc b/goal_src/jak2/pc/features/autosplit.gc index 430549bfd4..355c56cc3d 100644 --- a/goal_src/jak2/pc/features/autosplit.gc +++ b/goal_src/jak2/pc/features/autosplit.gc @@ -14,7 +14,17 @@ (defmacro autosplit-flag-task-complete! (field-name task-name) "Given a field name in the autosplitter struct, and a [[game-task]] name to check, sets either a 0 or a 1" - `(set! (-> this ,field-name) (if (task-complete? *game-info* (game-task ,task-name)) 1 0))) + `(begin + (if (!= (-> this ,field-name) (if (task-complete? *game-info* (game-task ,task-name)) 1 0)) + (format 0 "AUTOSPLIT for ~A~%" (quote ,task-name))) + (set! (-> this ,field-name) (if (task-complete? *game-info* (game-task ,task-name)) 1 0)))) + +(defmacro autosplit-flag-task-node-closed! (field-name task-node-name) + "Given a field name in the autosplitter struct, and a [[game-task-node]] name to check, sets either a 0 or a 1" + `(begin + (if (!= (-> this ,field-name) (if (task-node-closed? (game-task-node ,task-node-name)) 1 0)) + (format 0 "AUTOSPLIT for ~A~%" (quote ,task-node-name))) + (set! (-> this ,field-name) (if (task-node-closed? (game-task-node ,task-node-name)) 1 0)))) (defmethod update! ((this autosplit-info)) ;; general statistics @@ -139,6 +149,12 @@ (autosplit-flag-task-complete! res-stadium-burning-bush-race-class3-r stadium-burning-bush-race-class3-r) (autosplit-flag-task-complete! res-stadium-burning-bush-race-class2-r stadium-burning-bush-race-class2-r) (autosplit-flag-task-complete! res-stadium-burning-bush-race-class1-r stadium-burning-bush-race-class1-r) + ;; misc other tasks + (autosplit-flag-task-node-closed! tomb-poles-poles tomb-poles-poles) ;; left tomb/daxter boulder start + (autosplit-flag-task-node-closed! fortress-save-friends-introduction fortress-save-friends-introduction) ;; talk to torn (before rescue friends) + (autosplit-flag-task-node-closed! sewer-escort-get-gun sewer-escort-get-gun) ;; get peacemaker + (autosplit-flag-task-node-closed! forest-protect-introduction forest-protect-introduction) ;; talk to onin (protect samos) + (autosplit-flag-task-node-closed! forest-protect-meeting forest-protect-meeting) ;; talk to samos (protect samos) ;; debug only, draw stuff to the screen so i don't have to stare at a memory editor ;; (debug-draw this) diff --git a/goal_src/jak2/pc/pckernel-impl.gc b/goal_src/jak2/pc/pckernel-impl.gc index 4977b161c6..ded9aac848 100644 --- a/goal_src/jak2/pc/pckernel-impl.gc +++ b/goal_src/jak2/pc/pckernel-impl.gc @@ -101,6 +101,7 @@ (controller-led-status? symbol) (speedrunner-mode-custom-bind uint32) (memcard-subtitles? symbol) + (hint-subtitles? symbol) (text-language pc-language) ;; language for game text ) @@ -167,6 +168,7 @@ (set! (-> obj memcard-volume-dialog) 0.75) (set! (-> obj memcard-vibration?) #t) (set! (-> obj memcard-subtitles?) #f) + (set! (-> obj hinttitles?) #t) 0) (defmethod reset-extra ((obj pc-settings-jak2) (call-handlers symbol)) diff --git a/goal_src/jak2/pc/pckernel.gc b/goal_src/jak2/pc/pckernel.gc index e8a6fb928f..71b07c117a 100644 --- a/goal_src/jak2/pc/pckernel.gc +++ b/goal_src/jak2/pc/pckernel.gc @@ -322,6 +322,7 @@ (set! (-> *setting-control* user-default music-volume) (-> obj memcard-volume-music)) (set! (-> *setting-control* user-default dialog-volume) (-> obj memcard-volume-dialog)) (set! (-> *setting-control* user-default vibration) (-> obj memcard-vibration?)) + (set! (-> *setting-control* user-default subtitle) (-> obj memcard-subtitles?)) obj) (defmethod set-game-setting! ((obj pc-settings-jak2) (setting symbol) (value symbol)) @@ -767,6 +768,7 @@ (("cheats-unlocked") (set! (-> obj cheats-unlocked) (the-as pc-cheats (file-stream-read-int file)))) (("cheats-backup") (file-stream-read-int file)) ;; TODO - Don't remove this, parsing code can't handle unexpected keys (("memcard-subtitles?") (set! (-> obj memcard-subtitles?) (file-stream-read-symbol file))) + (("hint-subtitles?") (file-stream-read-symbol file)) (("music-unlocked") (dotimes (i (/ (align64 (-> obj music-unlocked length)) 64)) (bit-array<-int64 (-> obj music-unlocked) (* i 64) (file-stream-read-int file)) @@ -819,6 +821,7 @@ (format file " (cheats-purchased #x~x)~%" (-> obj cheats-purchased)) (format file " (cheats-unlocked #x~x)~%" (-> obj cheats-unlocked)) (format file " (memcard-subtitles? ~A)~%" (-> obj memcard-subtitles?)) + (format file " (hint-subtitles? ~A)~%" (-> obj hint-subtitles?)) (format file " (music-unlocked") (dotimes (i (/ (align64 (-> obj music-unlocked length)) 64)) diff --git a/goal_src/jak2/pc/progress/progress-draw-pc.gc b/goal_src/jak2/pc/progress/progress-draw-pc.gc index 3d634f1a95..bdfdf8e017 100644 --- a/goal_src/jak2/pc/progress/progress-draw-pc.gc +++ b/goal_src/jak2/pc/progress/progress-draw-pc.gc @@ -3198,7 +3198,7 @@ ;; count "valid" resolutions (let ((this-w 0) (this-h 0) (this-aspect 0.0)) - (pc-get-resolution i (& this-w) (& this-h)) + (pc-get-resolution i (= (pc-get-display-mode) 'windowed) (& this-w) (& this-h)) (set! this-aspect (/ (the float this-w) (the float this-h))) (when (or (= (pc-get-display-mode) 'windowed) diff --git a/goal_src/jak2/pc/progress/progress-pc.gc b/goal_src/jak2/pc/progress/progress-pc.gc index 34485484a1..9485a9867b 100644 --- a/goal_src/jak2/pc/progress/progress-pc.gc +++ b/goal_src/jak2/pc/progress/progress-pc.gc @@ -679,8 +679,8 @@ (res-h 0) (res-aspect 0.0) (res-valid 0)) - (dotimes (i (pc-get-num-resolutions)) - (pc-get-resolution i (& res-w) (& res-h)) + (dotimes (i (pc-get-num-resolutions (= (pc-get-display-mode) 'windowed))) + (pc-get-resolution i (= (pc-get-display-mode) 'windowed) (& res-w) (& res-h)) (set! res-aspect (/ (the float res-w) (the float res-h))) (when (or (= (pc-get-display-mode) 'windowed) (< (fabs (- want-aspect res-aspect)) 0.05)) @@ -716,7 +716,7 @@ (select-h -1) ) - (set! (-> this num-resolutions) (pc-get-num-resolutions)) + (set! (-> this num-resolutions) (pc-get-num-resolutions (= (pc-get-display-mode) 'windowed))) (cond ;; valid state ((> (-> this num-resolutions) 0) @@ -770,7 +770,7 @@ ;; count "valid" resolutions (let ((this-w 0) (this-h 0) (this-aspect 0.0)) - (pc-get-resolution i (& this-w) (& this-h)) + (pc-get-resolution i (= (pc-get-display-mode) 'windowed) (& this-w) (& this-h)) (set! this-aspect (/ (the float this-w) (the float this-h))) (when (or (= (pc-get-display-mode) 'windowed) diff --git a/goal_src/jak2/pc/progress/progress-static-pc.gc b/goal_src/jak2/pc/progress/progress-static-pc.gc index efbe71ecc6..f8f9ee5cbe 100644 --- a/goal_src/jak2/pc/progress/progress-static-pc.gc +++ b/goal_src/jak2/pc/progress/progress-static-pc.gc @@ -336,6 +336,16 @@ This gives us more freedom to write code how we want. (pc-settings-save) (set! (-> *setting-control* user-default subtitle) val)))) +(defmacro game-options-pc-hint-subtitle-toggle () + `(new 'static 'menu-generic-boolean-option + :name (text-id progress-hint-subtitles) + :truthy-text (text-id progress-on) + :falsey-text (text-id progress-off) + :get-value-fn (lambda () (-> *pc-settings* hinttitles?)) + :on-confirm (lambda ((val symbol)) + (set! (-> *pc-settings* hinttitles?) val) + (pc-settings-save)))) + (defmacro game-options-pc-subtitle-language () `(new 'static 'menu-generic-carousel-option :name (text-id progress-sound-subtitle-language) @@ -454,6 +464,7 @@ This gives us more freedom to write code how we want. (progress-new-generic-scrolling-page (text-id progress-root-game-options) (game-options-pc-input-options) (game-options-pc-subtitle-toggle) + (game-options-pc-hint-subtitle-toggle) (game-options-pc-subtitle-language) (game-options-pc-sound-language) (game-options-pc-text-language) @@ -466,6 +477,7 @@ This gives us more freedom to write code how we want. (progress-new-generic-scrolling-page (text-id progress-root-game-options) (game-options-pc-input-options) (game-options-pc-subtitle-toggle) + (game-options-pc-hint-subtitle-toggle) (game-options-pc-subtitle-language) (game-options-pc-sound-language) (game-options-pc-text-language) diff --git a/goal_src/jak2/pc/subtitle2.gc b/goal_src/jak2/pc/subtitle2.gc index 5cd84a154f..0f13aef3ab 100644 --- a/goal_src/jak2/pc/subtitle2.gc +++ b/goal_src/jak2/pc/subtitle2.gc @@ -471,7 +471,9 @@ (set! (-> self font origin y) cur-y) ;; check if we should actually draw subtitles and do it - (when (and (-> *setting-control* user-current subtitle) (or *gui-kick-str* (= *master-mode* 'game))) + (when (and (if (-> self movie-mode?) (-> *setting-control* user-current subtitle) + (-> *pc-settings* hinttitles?)) + (or *gui-kick-str* (= *master-mode* 'game))) (set-action! *gui-control* (gui-action play) (-> self gui-id) (gui-channel none) (gui-action none) (the-as string #f) (the-as (function gui-connection symbol) #f) (the-as process #f)) diff --git a/goal_src/jak3/dgos/game.gd b/goal_src/jak3/dgos/game.gd index 5807ef53de..fcf0fa0233 100644 --- a/goal_src/jak3/dgos/game.gd +++ b/goal_src/jak3/dgos/game.gd @@ -240,6 +240,10 @@ "game-task.o" "game-save.o" "settings.o" + "autosplit-h.o" ;; added + "autosplit.o" ;; added + "popup-menu-h.o" ;; added + "speedruns-h.o" ;; added "mood-tables.o" "mood-tables2.o" "mood.o" @@ -342,6 +346,8 @@ "board-states.o" "mech-h.o" "menu.o" + "popup-menu.o" ;; added + "speedruns.o" ;; added "drawable.o" "drawable-group.o" "drawable-inline-array.o" @@ -352,6 +358,8 @@ "capture-pc.o" ;; added "pckernel-common.o" ;; added "pckernel.o" ;; added + "subtitle3-h.o" ;; added + "subtitle3.o" ;; added "main.o" "collide-cache.o" "collide-debug.o" @@ -410,6 +418,7 @@ "visvol-edit.o" "collision-editor.o" "speech-manager.o" + "vag-player.o" ;; added "default-menu-pc.o" ;; added "dir-tpages.go" "tpage-1.go" diff --git a/goal_src/jak3/engine/ambient/ambient.gc b/goal_src/jak3/engine/ambient/ambient.gc index 51d96ffd91..c38ebe4c9a 100644 --- a/goal_src/jak3/engine/ambient/ambient.gc +++ b/goal_src/jak3/engine/ambient/ambient.gc @@ -382,11 +382,7 @@ (defstate idle (talker) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (the-as time-frame (-> self message delay))) - (suspend) - ) - ) + (suspend-for (the-as time-frame (-> self message delay))) (while (or (not (time-elapsed? (-> self start-time) (the-as time-frame (+ (-> self message delay) 300)))) (and (logtest? (-> self message flags) (talker-flags tf8)) (not (time-elapsed? (-> self start-time) (seconds 180))) @@ -567,11 +563,7 @@ ) ) (when (and (logtest? (-> self message flags) (talker-flags tf3)) (not (-> self save?))) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (set! (-> self save?) #t) (auto-save-user) ) diff --git a/goal_src/jak3/engine/camera/cam-layout.gc b/goal_src/jak3/engine/camera/cam-layout.gc index ea3c6235ae..fc7746d817 100644 --- a/goal_src/jak3/engine/camera/cam-layout.gc +++ b/goal_src/jak3/engine/camera/cam-layout.gc @@ -802,14 +802,14 @@ (when (logtest? (-> *camera* settings master-options) (cam-master-options READ_BUTTONS)) (if (cpad-hold? arg2 r1) (set! (-> arg1 y) - (+ 0.5 (analog-input (the-as int (-> *cpad-list* cpads arg2 abutton 9)) 0.0 32.0 230.0 0.5) (-> arg1 y)) + (+ 0.5 (analog-input (the-as int (-> *cpad-list* cpads arg2 abutton (abutton-idx r1))) 0.0 32.0 230.0 0.5) (-> arg1 y)) ;; og:preserve-this abutton indexing ) ) ) (when (logtest? (-> *camera* settings master-options) (cam-master-options READ_BUTTONS)) (if (cpad-hold? arg2 l1) (set! (-> arg1 y) - (- (-> arg1 y) (+ 0.5 (analog-input (the-as int (-> *cpad-list* cpads arg2 abutton 8)) 0.0 32.0 230.0 0.5))) + (- (-> arg1 y) (+ 0.5 (analog-input (the-as int (-> *cpad-list* cpads arg2 abutton (abutton-idx l1))) 0.0 32.0 230.0 0.5))) ;; og:preserve-this abutton indexing ) ) ) diff --git a/goal_src/jak3/engine/camera/cam-states-dbg.gc b/goal_src/jak3/engine/camera/cam-states-dbg.gc index c7f1464b70..f36e06d6d4 100644 --- a/goal_src/jak3/engine/camera/cam-states-dbg.gc +++ b/goal_src/jak3/engine/camera/cam-states-dbg.gc @@ -213,7 +213,7 @@ (if (cpad-hold? arg4 r1) (+! (-> arg2 y) (+ (* 0.2 f30-0) - (analog-input (the-as int (-> *cpad-list* cpads arg4 abutton 9)) 0.0 32.0 230.0 (* 0.2 f30-0)) + (analog-input (the-as int (-> *cpad-list* cpads arg4 abutton (abutton-idx r1))) 0.0 32.0 230.0 (* 0.2 f30-0)) ;; og:preserve-this abutton indexing ) ) ) @@ -223,7 +223,7 @@ (set! (-> arg2 y) (- (-> arg2 y) (+ (* 0.2 f30-0) - (analog-input (the-as int (-> *cpad-list* cpads arg4 abutton 8)) 0.0 32.0 230.0 (* 0.2 f30-0)) + (analog-input (the-as int (-> *cpad-list* cpads arg4 abutton (abutton-idx l1))) 0.0 32.0 230.0 (* 0.2 f30-0)) ;; og:preserve-this abutton indexing ) ) ) @@ -234,7 +234,7 @@ (when (logtest? (-> *camera* settings master-options) (cam-master-options READ_BUTTONS)) (if (cpad-hold? arg4 r1) (+! (-> arg2 y) - (+ f30-0 (analog-input (the-as int (-> *cpad-list* cpads arg4 abutton 9)) 0.0 32.0 230.0 f30-0)) + (+ f30-0 (analog-input (the-as int (-> *cpad-list* cpads arg4 abutton (abutton-idx r1))) 0.0 32.0 230.0 f30-0)) ;; og:preserve-this abutton indexing ) ) ) @@ -242,7 +242,7 @@ (if (cpad-hold? arg4 l1) (set! (-> arg2 y) (- (-> arg2 y) - (+ f30-0 (analog-input (the-as int (-> *cpad-list* cpads arg4 abutton 8)) 0.0 32.0 230.0 f30-0)) + (+ f30-0 (analog-input (the-as int (-> *cpad-list* cpads arg4 abutton (abutton-idx l1))) 0.0 32.0 230.0 f30-0)) ;; og:preserve-this abutton indexing ) ) ) diff --git a/goal_src/jak3/engine/camera/cam-states.gc b/goal_src/jak3/engine/camera/cam-states.gc index 3bbf82cb09..8bd1dc27e9 100644 --- a/goal_src/jak3/engine/camera/cam-states.gc +++ b/goal_src/jak3/engine/camera/cam-states.gc @@ -2628,7 +2628,7 @@ (if (cpad-hold? (-> *CAMERA-bank* joypad) r1) (+! f30-2 (+ (* 10922.667 (seconds-per-frame)) (analog-input - (the-as int (-> *cpad-list* cpads (-> *CAMERA-bank* joypad) abutton 9)) + (the-as int (-> *cpad-list* cpads (-> *CAMERA-bank* joypad) abutton (abutton-idx r1))) ;; og:preserve-this abutton indexing 0.0 32.0 230.0 @@ -2642,7 +2642,7 @@ (if (cpad-hold? (-> *CAMERA-bank* joypad) l1) (set! f30-2 (- f30-2 (+ (* 10922.667 (seconds-per-frame)) (analog-input - (the-as int (-> *cpad-list* cpads (-> *CAMERA-bank* joypad) abutton 8)) + (the-as int (-> *cpad-list* cpads (-> *CAMERA-bank* joypad) abutton (abutton-idx l1))) ;; og:preserve-this abutton indexing 0.0 32.0 230.0 diff --git a/goal_src/jak3/engine/collide/collide-cache.gc b/goal_src/jak3/engine/collide/collide-cache.gc index 8031a5afe6..f97d175585 100644 --- a/goal_src/jak3/engine/collide/collide-cache.gc +++ b/goal_src/jak3/engine/collide/collide-cache.gc @@ -866,6 +866,109 @@ (defmethod-mips2c "(method 10 collide-cache-prim)" 10 collide-cache-prim) +;; this function is a cleaned up version of the MIPS2C'd (method 10 collide-cache-prim) +;; as far as I know, it works correctly, but I'm too scared to use it as the default +;; in case there's a subtle bug. +#| +(defmethod resolve-moving-sphere-sphere ((this collide-cache-prim) + (result collide-query) + (other sphere) + (move-dist vector) + (best-dist float) + (action collide-action)) + "Update the `result` collide query with the result of moving `other` by `move-dist` + If best-dist is positive, it indicates a fraction of move-dist where we know there is already a collision. + So, collisions after this point should be ignored. + Additionally, the fraction along move-dist to have collision is returned, or a negative number if no collision is possible. + Note that a collision that occurs in move-dist, but after best-dist will return a negative number." + + ;; treat the incoming sphere as the "moving sphere", do collision detection: + (let* ((sphere-collide-pt (new 'stack-no-clear 'vector)) + (u (moving-sphere-sphere-intersect + other ;; the incoming sphere's position/radius + move-dist ;; the delta position of incoming sphere, if no collision happens + (-> this world-sphere) ;; our position/radius + sphere-collide-pt ;; resulting position of sphere collision + )) + ) + + ;; if we are moving away from collision, there is no collision to report + (when (< u 0.0) + (return u) + ) + + ;; if a previous prim has already found a closer collision, ignore this one. + (when (>= best-dist 0.0) ;; only if we've found something. + (when (<= best-dist u) + (return -100000000.0) + ) + ) + + ;; vector pointing from our center to the intersect point + ;; if the incoming sphere moves this way, it will move it out of collision. + (let* ((escape-dir (vector-! (new 'stack-no-clear 'vector) sphere-collide-pt (-> this world-sphere))) + ) + + ;; next, we'll reject collision if we collide with a solid, but our velocity is moving us out of collision + (when (and (logtest? action (collide-action solid)) + (>= (vector-dot escape-dir move-dist) 0.0) + ) + (return -100000000.0) + ) + + ;; we'll now accept this as the real collision! + (set! (-> result best-my-tri intersect quad) (-> sphere-collide-pt quad)) + (let ((p (the collide-shape-prim-sphere (-> this prim)))) + (set! (-> result best-my-tri pat) (-> p pat)) + (set! (-> result best-my-tri collide-ptr) p) + ) + + (vector-normalize! escape-dir 1.0) + (vector-copy! (-> result best-my-tri normal) escape-dir) + + ;; we need to fake a triangle for the collision result. + ;; to do this, we need to find a vector that's perpendicular to our normal + (let ((triangle-rot (new 'stack-no-clear 'matrix))) + (vector-copy! (-> triangle-rot vector 0) escape-dir) + (cond + ((and (= (-> escape-dir x) 0.0) (= (-> escape-dir y) 0.0)) + ;; unlikely case that escape is exactly along z. If this happens, pick unit x. + (set-vector! (-> triangle-rot vector 1) (-> escape-dir z) 0.0 0.0 1.0) + ) + (else + ;; normal case that there's some x/y component + (set-vector! (-> triangle-rot vector 1) (- 0.0 (-> escape-dir y)) (-> escape-dir x) 0.0 1.0) + (vector-normalize! (-> triangle-rot vector 1) 1.0) + ) + ) + + ;; pick final axis + (vector-cross! (-> triangle-rot vector 2) + (-> triangle-rot vector 0) + (-> triangle-rot vector 1)) + ;; position + (set! (-> triangle-rot quad 3) + (-> sphere-collide-pt quad)) + + ;; transform + (vector-matrix*! (-> result best-my-tri vertex 0) + (new 'static 'vector :y 4096.0 :w 1.0) + triangle-rot) + (vector-matrix*! (-> result best-my-tri vertex 1) + (new 'static 'vector :y -4096.0 :z 4096.0 :w 1.0) + triangle-rot) + (vector-matrix*! (-> result best-my-tri vertex 2) + (new 'static 'vector :y -4096.0 :z -4096.0 :w 1.0) + triangle-rot) + + + ) + u + ) + ) + ) +|# + (defmethod fill-and-probe-using-spheres ((this collide-cache) (arg0 collide-query)) (fill-using-spheres this arg0) (probe-using-spheres this arg0) diff --git a/goal_src/jak3/engine/collide/collide-shape.gc b/goal_src/jak3/engine/collide/collide-shape.gc index b0a17b3c53..91279c960c 100644 --- a/goal_src/jak3/engine/collide/collide-shape.gc +++ b/goal_src/jak3/engine/collide/collide-shape.gc @@ -2116,10 +2116,22 @@ (.lvf vf3 (&-> a1-4 uvec quad)) (.add.mul.x.vf acc vf2 vf1 acc) (.lvf vf4 (&-> a1-4 fvec quad)) + + (.add.mul.y.vf acc vf3 vf1 acc) + (.add.mul.z.vf vf1 vf4 vf1 acc :mask #b111) + + ;; this check is added in the PC port. It's added for the same reason as the modification + ;; to vector<-cspace!. On the first frame of a process-drawable being alive, the bones will often be zero + ;; on PS2, this would have a potentially harmless result of setting this bone to 0, putting the collision geometry at 0. + ;; this would usually result in no collision, and no change in velocities + ;; in the next frame, the position would be computed correctly. + ;; on PC, this bone becomes NaN, which propagates to setting the velocity to NaN, which results in the + ;; entire collision system having everything as NaN all the time. + (if (!= (-> a1-4 trans w) 0.0) + (.mul.vf vf1 vf1 Q :mask #b111) ) - (.add.mul.y.vf acc vf3 vf1 acc) - (.add.mul.z.vf vf1 vf4 vf1 acc :mask #b111) - (.mul.vf vf1 vf1 Q :mask #b111) + ) + (.svf (&-> s5-0 prim-core world-sphere quad) vf1) (.mov a1-5 vf1) ) diff --git a/goal_src/jak3/engine/common-obs/collectables.gc b/goal_src/jak3/engine/common-obs/collectables.gc index 119b912b36..5da58d9c62 100644 --- a/goal_src/jak3/engine/common-obs/collectables.gc +++ b/goal_src/jak3/engine/common-obs/collectables.gc @@ -1270,11 +1270,7 @@ (if (not (logtest? (-> self fact options) (actor-option no-reaction))) (send-event (handle->process arg1) 'powerup (-> self fact pickup-type) (-> self fact pickup-amount)) ) - (let ((t9-2 (-> (find-parent-state) code))) - (if t9-2 - ((the-as (function none) t9-2)) - ) - ) + (call-parent-state-handler code) ) ) diff --git a/goal_src/jak3/engine/common-obs/crates.gc b/goal_src/jak3/engine/common-obs/crates.gc index 6350aca3db..baa3b14e7c 100644 --- a/goal_src/jak3/engine/common-obs/crates.gc +++ b/goal_src/jak3/engine/common-obs/crates.gc @@ -920,11 +920,7 @@ ) ) (when (not arg0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.04)) - (suspend) - ) - ) + (suspend-for (seconds 0.04)) (case (-> self look) (('iron) (sound-play "icrate-break") @@ -1016,17 +1012,9 @@ (drop-pickup (-> self fact) #t *entity-pool* (the-as fact-info #f) arg1 #t) (process-entity-status! self (entity-perm-status dead) #t) (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 5)) - (suspend) - ) - ) + (suspend-for (seconds 5)) (when (logtest? (actor-option cond-respawn) (-> self fact options)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 15)) - (suspend) - ) - ) + (suspend-for (seconds 15)) (go-virtual hide) ) ) diff --git a/goal_src/jak3/engine/common-obs/enemy-states.gc b/goal_src/jak3/engine/common-obs/enemy-states.gc index f7045f66c2..9d3d07f1ab 100644 --- a/goal_src/jak3/engine/common-obs/enemy-states.gc +++ b/goal_src/jak3/engine/common-obs/enemy-states.gc @@ -669,11 +669,7 @@ :code (behavior () (cond ((handle->process (-> self ragdoll-proc)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (until (ragdoll-settled? self) (if (or (time-elapsed? (-> self state-time) (seconds 4)) (enemy-method-109 self)) (go-die self) @@ -979,19 +975,11 @@ :code (behavior () (cond ((handle->process (-> self ragdoll-proc)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (if (-> self skel effect) (do-effect (-> self skel effect) "death-default" 0.0 -1) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.8)) - (suspend) - ) - ) + (suspend-for (seconds 0.8)) ) (else (ja-channel-push! 1 (seconds 0.075)) @@ -1073,19 +1061,11 @@ :code (behavior () (cond ((handle->process (-> self ragdoll-proc)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (if (-> self skel effect) (do-effect (-> self skel effect) "death-default" 0.0 -1) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (deactivate-ragdoll! self) ) (else diff --git a/goal_src/jak3/engine/common-obs/generic-obs.gc b/goal_src/jak3/engine/common-obs/generic-obs.gc index bd6da47eec..286a7f3325 100644 --- a/goal_src/jak3/engine/common-obs/generic-obs.gc +++ b/goal_src/jak3/engine/common-obs/generic-obs.gc @@ -290,12 +290,7 @@ (swingpole-method-22 self) (suspend) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (swingpole-method-22 self) - (suspend) - ) - ) + (suspend-for (seconds 0.5) (swingpole-method-22 self)) (go-virtual idle) ) ) @@ -3983,31 +3978,19 @@ (set-setting! 'mode-name 'cam-fixed 0.0 0) (set-setting! 'interp-time 'abs 450.0 0) (set-setting! 'entity-name (res-lump-struct (-> self entity) 'camera-name structure) 0.0 0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (-> self pause-time)) - (suspend) - ) - ) + (suspend-for (-> self pause-time)) (if (-> self blur) (set-setting! 'blur-a 'abs 0.5 0) ) (remove-setting! 'mode-name) (remove-setting! 'entity-name) (remove-setting! 'interp-time) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (while (not (process-release? *target*)) (suspend) ) (remove-setting! 'interp-time) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (remove-setting! 'blur-a) (process-entity-status! self (entity-perm-status no-kill) #f) ) @@ -4059,7 +4042,7 @@ :trans (behavior () (set! (-> self task-counter) (-> *game-info* task-counter)) (if *bigmap* - (bigmap-method-16 *bigmap*) + (set-map-indices! *bigmap*) ) (let ((gp-0 (res-lump-struct (-> self entity) 'on-running structure))) (cond diff --git a/goal_src/jak3/engine/common-obs/powerups.gc b/goal_src/jak3/engine/common-obs/powerups.gc index 9ce4666697..ab925e655e 100644 --- a/goal_src/jak3/engine/common-obs/powerups.gc +++ b/goal_src/jak3/engine/common-obs/powerups.gc @@ -20,25 +20,23 @@ (let ((s1-1 (process->handle arg0)) (s2-1 (process->handle arg1)) ) - (let ((s0-0 (current-time))) - (until (time-elapsed? s0-0 (+ arg3 arg4)) - (let ((v1-8 (or (not (handle->process s1-1)) (not (handle->process s2-1))))) - (if v1-8 - (deactivate self) - ) - ) - (let* ((f0-1 (fmax 0.0 (fmin 1.0 (/ (- (the float (- (current-time) s0-0)) (the float arg3)) (the float arg4))))) - (a0-18 (process-drawable-pair-random-point! - (the-as process-drawable (-> s1-1 process 0)) - (the-as process-drawable (-> s2-1 process 0)) - (new-stack-vector0) - f0-1 - ) + (suspend-for + (+ arg3 arg4) + (let ((v1-8 (or (not (handle->process s1-1)) (not (handle->process s2-1))))) + (if v1-8 + (deactivate self) + ) + ) + (let* ((f0-1 (fmax 0.0 (fmin 1.0 (/ (- (the float (- (current-time) time)) (the float arg3)) (the float arg4))))) + (a0-18 (process-drawable-pair-random-point! + (the-as process-drawable (-> s1-1 process 0)) + (the-as process-drawable (-> s2-1 process 0)) + (new-stack-vector0) + f0-1 ) - ) - (arg2 a0-18) - ) - (suspend) + ) + ) + (arg2 a0-18) ) ) (cond @@ -49,12 +47,10 @@ #f ) (else - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 arg5) - (let ((a0-21 (process-drawable-random-point! (the-as process-drawable (-> s2-1 process 0)) (new-stack-vector0)))) - (arg2 a0-21) - ) - (suspend) + (suspend-for + arg5 + (let ((a0-21 (process-drawable-random-point! (the-as process-drawable (-> s2-1 process 0)) (new-stack-vector0)))) + (arg2 a0-21) ) ) ) diff --git a/goal_src/jak3/engine/common-obs/projectile.gc b/goal_src/jak3/engine/common-obs/projectile.gc index a8130f6a12..2412fb0fa0 100644 --- a/goal_src/jak3/engine/common-obs/projectile.gc +++ b/goal_src/jak3/engine/common-obs/projectile.gc @@ -494,7 +494,7 @@ ;; (usually the vehicle firing the projectile) to set the quat instead. ;; on original hardware, this would not crash because misaligned qw loads silently mask the lower bits ;; of the address, loading a junk value instead. - (quaternion-copy! (-> s5-0 quat) (the-as quaternion (align16 (+ -16 (the-as int (-> self parent 0 root quat)))))) + (quaternion-copy! (-> s5-0 quat) (the quaternion (logand (the int (-> self parent 0 root quat)) #xffffffff0))) (vector-identity! (-> s5-0 scale)) (set! (-> s5-0 transv quad) (-> arg0 vel quad)) (set! (-> self pre-move-transv quad) (-> arg0 vel quad)) diff --git a/goal_src/jak3/engine/common-obs/scene-actor.gc b/goal_src/jak3/engine/common-obs/scene-actor.gc index 266369cd88..e66bc17121 100644 --- a/goal_src/jak3/engine/common-obs/scene-actor.gc +++ b/goal_src/jak3/engine/common-obs/scene-actor.gc @@ -469,7 +469,7 @@ (drag 0.151) (num-iterations 1) (timestep-frequency 7) - (secret-disable (game-secrets scene-player-1 scene-player-3)) + (secret-disable (game-secrets kleever-diaper)) ) ((mesh kleever-highres-kleever-R1-cg) (gravity-constant (meters 24)) @@ -484,7 +484,7 @@ (drag 0.151) (num-iterations 1) (timestep-frequency 7) - (secret-disable (game-secrets scene-player-1 scene-player-3)) + (secret-disable (game-secrets kleever-diaper)) ) ((mesh kleever-highres-kleever-Center-cg) (gravity-constant (meters 24)) @@ -499,7 +499,7 @@ (drag 0.151) (num-iterations 1) (timestep-frequency 7) - (secret-disable (game-secrets scene-player-1 scene-player-3)) + (secret-disable (game-secrets kleever-diaper)) ) ((mesh kleever-highres-kleever-L2-cg) (gravity-constant (meters 12)) @@ -514,7 +514,7 @@ (drag 0.151) (num-iterations 1) (timestep-frequency 7) - (secret-disable (game-secrets scene-player-1 scene-player-3)) + (secret-disable (game-secrets kleever-diaper)) ) ((mesh kleever-highres-kleever-R2-cg) (gravity-constant (meters 12)) @@ -529,7 +529,7 @@ (drag 0.151) (num-iterations 1) (timestep-frequency 7) - (secret-disable (game-secrets scene-player-1 scene-player-3)) + (secret-disable (game-secrets kleever-diaper)) ) ) ) diff --git a/goal_src/jak3/engine/common-obs/warp-gate.gc b/goal_src/jak3/engine/common-obs/warp-gate.gc index f90fa4d8d7..45cfef14ce 100644 --- a/goal_src/jak3/engine/common-obs/warp-gate.gc +++ b/goal_src/jak3/engine/common-obs/warp-gate.gc @@ -688,11 +688,7 @@ (set-blackout-frames (seconds 0.05)) ) (start 'play arg0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while (and *target* (and (>= 81920.0 (vector-vector-distance (-> self root trans) (-> *target* control trans))) (not (logtest? (focus-status teleporting) (-> *target* focus-status))) ) diff --git a/goal_src/jak3/engine/debug/anim-tester.gc b/goal_src/jak3/engine/debug/anim-tester.gc index 32f710d826..49b9a5947c 100644 --- a/goal_src/jak3/engine/debug/anim-tester.gc +++ b/goal_src/jak3/engine/debug/anim-tester.gc @@ -9,6 +9,9 @@ ;; DECOMP BEGINS +;; og:preserve-this +(declare-file (debug)) + (deftype list-control (structure) ((listfunc (function int list-control symbol) :offset-assert 0) ;; guessed by decompiler (list-owner uint32 :offset-assert 4) diff --git a/goal_src/jak3/engine/debug/default-menu.gc b/goal_src/jak3/engine/debug/default-menu.gc index d06e68024a..cfc95a87e0 100644 --- a/goal_src/jak3/engine/debug/default-menu.gc +++ b/goal_src/jak3/engine/debug/default-menu.gc @@ -3679,6 +3679,8 @@ (flag "german" 2 dm-setting-subtitle-language) (flag "spanish" 3 dm-setting-subtitle-language) (flag "italian" 4 dm-setting-subtitle-language) + ;; og:preserve-this added + (flag "commentary" 5 dm-setting-subtitle-language) (flag "korean" 7 dm-setting-subtitle-language) (flag "russian" 8 dm-setting-subtitle-language) (flag "portuguese" 9 dm-setting-subtitle-language) diff --git a/goal_src/jak3/engine/game/game-info.gc b/goal_src/jak3/engine/game/game-info.gc index f806579f0b..664ffc2480 100644 --- a/goal_src/jak3/engine/game/game-info.gc +++ b/goal_src/jak3/engine/game/game-info.gc @@ -587,10 +587,7 @@ (dotimes (v1-96 (-> this game-score length)) (set! (-> this game-score v1-96) 0.0) ) - (when *bigmap* ;; og:preserve-this not-yet-implemented check - (format 0 "skipping bigmap init in game-info~%") - ((method-of-object *bigmap* bigmap-method-9)) - ) + (initialize *bigmap*) ) ) (case mode @@ -1106,25 +1103,19 @@ (set! (-> v1-9 origin z) (the float (/ (-> s3-0 z) 16))) ) (set! (-> s5-0 flags) (font-flags shadow kerning large)) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (+ arg2 -75)) - (+! (-> s5-0 origin y) (* -120.0 (seconds-per-frame))) - (let ((s2-0 print-game-text)) - (format (clear *temp-string*) "~4,,0f" arg1) - (s2-0 *temp-string* s5-0 #f 44 (bucket-id debug-no-zbuf1)) - ) - (suspend) + (suspend-for (+ arg2 -75) + (+! (-> s5-0 origin y) (* -120.0 (seconds-per-frame))) + (let ((s2-0 print-game-text)) + (format (clear *temp-string*) "~4,,0f" arg1) + (s2-0 *temp-string* s5-0 #f 44 (bucket-id debug-no-zbuf1)) ) ) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.25)) - (set! (-> s5-0 alpha) (lerp-scale 1.0 0.0 (the float (- (current-time) s4-1)) 0.0 150.0)) - (+! (-> s5-0 origin y) (* -120.0 (seconds-per-frame))) - (let ((s3-2 print-game-text)) - (format (clear *temp-string*) "~4,,0f" arg1) - (s3-2 *temp-string* s5-0 #f 44 (bucket-id debug-no-zbuf1)) - ) - (suspend) + (suspend-for (seconds 0.25) + (set! (-> s5-0 alpha) (lerp-scale 1.0 0.0 (the float (- (current-time) time)) 0.0 150.0)) + (+! (-> s5-0 origin y) (* -120.0 (seconds-per-frame))) + (let ((s3-2 print-game-text)) + (format (clear *temp-string*) "~4,,0f" arg1) + (s3-2 *temp-string* s5-0 #f 44 (bucket-id debug-no-zbuf1)) ) ) ) @@ -1401,10 +1392,6 @@ (defmethod copy-perms-to-level! ((this game-info) (arg0 level)) (let ((s5-0 (-> arg0 bsp level entity))) - (when (not s5-0) ;; og:preserve-this not-yet-implemented check - (format #t "skipping copy-perms-to-level! since we have no entity links (needs entity.gc)~%") - (return 0) - ) (dotimes (s4-0 (-> s5-0 length)) (let* ((s3-0 (-> s5-0 data s4-0 entity extra perm)) (v1-7 (actor-perm this (-> s3-0 aid))) @@ -1594,11 +1581,8 @@ process (lambda :behavior process ((arg0 string)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 10)) - (format *stdcon* "~S~%" arg0) - (suspend) - ) + (suspend-for (seconds 10) + (format *stdcon* "~S~%" arg0) ) (none) ) diff --git a/goal_src/jak3/engine/game/main.gc b/goal_src/jak3/engine/game/main.gc index ef05182270..4d6aa420b5 100644 --- a/goal_src/jak3/engine/game/main.gc +++ b/goal_src/jak3/engine/game/main.gc @@ -260,7 +260,9 @@ ) ) (('menu) - (set-master-mode (cond + ;; og:preserve-this Let the popup menu code handle inputs instead of the code written for the original debug menu + (when (not *popup-menu-open*) + (set-master-mode (cond ((and *debug-segment* (cpad-hold? 0 l3) (cpad-pressed? 0 select start)) 'menu ) @@ -280,7 +282,7 @@ *master-mode* ) ) - ) + )) (set! *pause-lock* #f) ) (('pause) @@ -1485,7 +1487,7 @@ ) ; ;; Update start-menu map and masking - ; (update *bigmap*) + (update *bigmap*) ;; do some more level loading. (if (-> *level* loading-level) @@ -1508,10 +1510,12 @@ ; (draw-color-bars *blit-displays-work*) ; ) - ;; run debug menu - (*menu-hook*) + ;; draw and update menus + ;; og:preserve-this Let the popup menu code handle inputs instead of the code written for the original debug menu + (when (not *popup-menu-open*) + (*menu-hook*)) + ; load the right language file. - ;; disabled for now: seems to load 255COMMON.TXT. (load-level-text-files -1) ;; draw screen filter @@ -1555,7 +1559,7 @@ ; ;; generate DMA to copy from render buffer to frame buffer. (with-profiler 'blit-displays *profile-blit-color* - (blit-displays-work-method-19 *blit-displays-work*) + (do-blit-displays *blit-displays-work*) ) ;; wrap up this frame (drawing of stdcon, debugging, etc.) @@ -1575,8 +1579,11 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; start stat collection for this frame - (start-frame! (-> arg0 frames (-> arg0 on-screen) profile-array data 0)) - (start-profiling! (-> *perf-stats* data 0)) + ;; og:preserve-this added check + (when *debug-segment* + (start-frame! (-> arg0 frames (-> arg0 on-screen) profile-array data 0)) + (start-profiling! (-> *perf-stats* data 0)) + ) ;; update *teleport* flag, which is set when the game intentionally teleports the camera, ;; and indicates that effects should not be gradually transitioned. diff --git a/goal_src/jak3/engine/game/settings.gc b/goal_src/jak3/engine/game/settings.gc index 4502f73bcf..e8fd3851d7 100644 --- a/goal_src/jak3/engine/game/settings.gc +++ b/goal_src/jak3/engine/game/settings.gc @@ -1838,7 +1838,7 @@ (-> s4-0 blur-a) (* (-> s5-0 blur-a-speed) (-> *display* real-clock seconds-per-frame)) ) - (blit-displays-work-method-17 + (setup-zoom-blur-2d *blit-displays-work* (new 'static 'vector :x 256.0 :y 208.0 :w 1.0) s3-10 diff --git a/goal_src/jak3/engine/game/task/task-control.gc b/goal_src/jak3/engine/game/task/task-control.gc index 8d65547680..33c517d775 100644 --- a/goal_src/jak3/engine/game/task/task-control.gc +++ b/goal_src/jak3/engine/game/task/task-control.gc @@ -2537,18 +2537,14 @@ (process-release? *target*) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (let ((f30-0 (lerp-scale 1.0 0.0 (the float (- (current-time) gp-0)) 0.0 300.0))) - (set-filter-color! - (lerp-scale 1.0 1.25 f30-0 0.0 1.0) - (lerp-scale 1.0 0.875 f30-0 0.0 1.0) - (lerp-scale 1.0 0.25 f30-0 0.0 1.0) - ) - ) - (suspend) - ) - ) + (suspend-for (seconds 1) (let ((f30-0 (lerp-scale 1.0 0.0 (the float (- (current-time) time)) 0.0 300.0))) + (set-filter-color! + (lerp-scale 1.0 1.25 f30-0 0.0 1.0) + (lerp-scale 1.0 0.875 f30-0 0.0 1.0) + (lerp-scale 1.0 0.25 f30-0 0.0 1.0) + ) + ) + ) (let ((gp-1 (if (-> self retry?) (-> self params retry) (-> self params fail) diff --git a/goal_src/jak3/engine/gfx/blit-displays-h.gc b/goal_src/jak3/engine/gfx/blit-displays-h.gc index d41ea279b5..275d8742ea 100644 --- a/goal_src/jak3/engine/gfx/blit-displays-h.gc +++ b/goal_src/jak3/engine/gfx/blit-displays-h.gc @@ -23,7 +23,7 @@ (zoom-blur-texels int32) (zoom-blur-alpha-target float) (zoom-blur-alpha-current float) - (zoom-blur-2d basic) + (zoom-blur-2d symbol) (menu-mode symbol) (screen-copied symbol) (vu1-enable-user-menu vu1-renderer-mask) @@ -38,18 +38,18 @@ (slow-time float) ) (:methods - (blit-displays-work-method-9 () none) - (blit-displays-work-method-10 () none) - (blit-displays-work-method-11 () none) - (blit-displays-work-method-12 () none) - (blit-displays-work-method-13 () none) - (blit-displays-work-method-14 () none) - (blit-displays-work-method-15 () none) - (blit-displays-work-method-16 () none) - (blit-displays-work-method-17 (_type_ vector int float symbol) none) - (blit-displays-work-method-18 () none) - (blit-displays-work-method-19 (_type_) none) - (blit-displays-work-method-20 (_type_) none) + (blit-displays-work-method-9 (_type_ dma-buffer int int int) none) + (blit-displays-work-method-10 (_type_ dma-buffer int int int) none) + (blit-displays-work-method-11 (_type_ dma-buffer int) none) + (draw-letterbox (_type_ dma-buffer float int float) none) + (blit-displays-work-method-13 (_type_ dma-buffer int int int) none) + (blit-displays-work-method-14 (_type_ dma-buffer vector) none) + (blit-displays-work-method-15 (_type_ dma-buffer) none) + (draw-zoom-blur (_type_ dma-buffer int) none) + (setup-zoom-blur-2d (_type_ vector int float symbol) none) + (setup-brightness-and-contrast (_type_ dma-buffer float float) none) + (do-blit-displays (_type_) none) + (draw-sky (_type_ dma-buffer) none) (get-menu-mode (_type_) symbol) (get-screen-copied (_type_) symbol) (get-horizontal-flip-flag (_type_) symbol) diff --git a/goal_src/jak3/engine/gfx/blit-displays.gc b/goal_src/jak3/engine/gfx/blit-displays.gc index 68a8b02174..3878a712d6 100644 --- a/goal_src/jak3/engine/gfx/blit-displays.gc +++ b/goal_src/jak3/engine/gfx/blit-displays.gc @@ -83,20 +83,958 @@ ) ) -;; stub: +(defun pc-upload-raw-texture ((dma-buf dma-buffer) (image-data pointer) (width int) (height int) (tbp int)) + "Added function in the PC port to create a 'raw' texture (no clut)" + (pc-texture-anim-flag start-anim-array dma-buf) + (pc-texture-anim-flag upload-generic-vram dma-buf :qwc 1) + (let ((upload-record (the texture-anim-pc-upload (-> dma-buf base)))) + (set! (-> upload-record data) image-data) + (set! (-> upload-record width) width) + (set! (-> upload-record height) height) + (set! (-> upload-record dest) tbp) + (set! (-> upload-record format) (gs-psm ct32)) + (set! (-> upload-record force-to-gpu) 1) + ) + (&+! (-> dma-buf base) 16) + (pc-texture-anim-flag finish-anim-array dma-buf) + ) -(defmethod blit-displays-work-method-19 ((this blit-displays-work)) - (set! (-> this slow-time) (- 1.0 (-> *setting-control* user-current slow-time))) +;; DECOMP BEGINS + +(define *blit-displays-work* (new 'static 'blit-displays-work + :adgif-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x6 :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x6 :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x1000000000008005 #xe) + ) + :sprite-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x41 :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x41 :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x408b400000008010 #x5353) + ) + :contrast-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x41 :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x41 :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x40ab400000008010 #x5353) + ) + :sprite-slow-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x6 :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x6 :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x50ab400000008001 #x53531) + ) + :draw-slow-time-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x13 :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x13 :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x30aec00000008006 #x531) + ) + :line-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x41 :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x41 :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x2020c00000008020 #x55) + ) + :scan-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x4c :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x4c :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x5020c0000000800f #x55551) + ) + :color (new 'static 'vector4w :x #x80 :y #x80 :z #x80 :w #x80) + :line-color #x3f80000000000000 + :scan-colors (new 'static 'inline-array vector4w 15 + (new 'static 'vector4w :y 1 :z 1) + (new 'static 'vector4w :y 1 :z 1) + (new 'static 'vector4w :y 1 :z 1) + (new 'static 'vector4w :y 1 :z 1) + (new 'static 'vector4w :x 1 :y 3 :z 2) + (new 'static 'vector4w :x 1 :y 4 :z 3) + (new 'static 'vector4w :x 2 :y 6 :z 5) + (new 'static 'vector4w :x 3 :y 8 :z 7) + (new 'static 'vector4w :x 5 :y 11 :z 10) + (new 'static 'vector4w :x 6 :y 14 :z 13) + (new 'static 'vector4w :x 9 :y 20 :z 17) + (new 'static 'vector4w :x 13 :y 27 :z 21) + (new 'static 'vector4w :x 17 :y 36 :z 24) + (new 'static 'vector4w :x 22 :y 45 :z 28) + (new 'static 'vector4w :x 32 :y 63 :z 32) + ) + :menu-mode #f + :screen-copied #f + :horizontal-flip-flag #f + ) + ) + +(defmethod blit-displays-work-method-9 ((this blit-displays-work) (arg0 dma-buffer) (arg1 int) (arg2 int) (arg3 int)) + (let ((v1-0 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-0) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-0) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 2) 128 128 128 arg3) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 3) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 4) 0 0 #xffffff 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 5) 8184 (+ (* (+ arg1 -1) 16) 8) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 6) #x2800 (* arg2 16) #xffffff #x10000) + ) + (&+! (-> arg0 base) 112) + 0 (none) ) -(defmethod blit-displays-work-method-17 ((this blit-displays-work) (arg0 vector) (arg1 int) (arg2 float) (arg3 symbol)) +(defmethod blit-displays-work-method-10 ((this blit-displays-work) (arg0 dma-buffer) (arg1 int) (arg2 int) (arg3 int)) + (let ((v1-0 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-0) 0 quad) (-> this draw-slow-time-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-0) 1 quad) (-> this draw-slow-time-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 2) 96 96 96 192) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 3) 4088 3320 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 4) 5120 (* arg2 8) #xffffff #x10000) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 5) 128 128 128 arg3) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 6) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 7) 0 0 #xffffff 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 8) 128 128 128 arg3) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 9) 8184 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 10) #x2800 0 #xffffff #x10000) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 11) 128 128 128 arg3) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 12) 8184 (+ (* (+ arg1 -1) 16) 8) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 13) #x2800 (* arg2 16) #xffffff #x10000) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 14) 128 128 128 arg3) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 15) 8 (+ (* (+ arg1 -1) 16) 8) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 16) 0 (* arg2 16) #xffffff #x10000) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 17) 128 128 128 arg3) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 18) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 19) 0 0 #xffffff 0) + ) + (&+! (-> arg0 base) 320) + 0 (none) ) -(defun draw-raw-image ((arg0 bucket-id) (arg1 art-group) (arg2 int) (arg3 vector) (arg4 vector) (arg5 level) (arg6 int)) +(defmethod blit-displays-work-method-11 ((this blit-displays-work) (arg0 dma-buffer) (arg1 int)) + (let ((v1-0 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-0) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-0) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) v1-0) 2 quad) (-> this color quad)) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 3) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 4) 0 0 #xffffff 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 5) #x27f8 (+ (* (+ arg1 -1) 16) 8) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 6) 8192 6656 #xffffff #x10000) + ) + (&+! (-> arg0 base) 112) + 0 (none) ) -;; DECOMP BEGINS +(defmethod draw-letterbox ((this blit-displays-work) (arg0 dma-buffer) (arg1 float) (arg2 int) (arg3 float)) + (let ((v1-0 (the-as object (-> arg0 base)))) + (set! (-> (the-as (pointer uint128) v1-0)) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-0) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 2) 128 128 128 128) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 3) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 4) 0 0 #xffffff 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 5) 8184 (+ (the int (* 736.0 arg1)) 8) 0 0) + (set-vector! + (-> (the-as (inline-array vector4w) v1-0) 6) + #x2800 + (the int (* 736.0 arg3 arg1)) + #xffffff + #x10000 + ) + ) + (&+! (-> arg0 base) 112) + (let ((v1-4 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-4) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-4) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) v1-4) 2) 128 128 128 128) + (set-vector! (-> (the-as (inline-array vector4w) v1-4) 3) 8 (+ (* (- 416 (the int (* 46.0 arg1))) 16) 8) 0 0) + (set-vector! + (-> (the-as (inline-array vector4w) v1-4) 4) + 0 + (* (- arg2 (the int (* 46.0 arg3 arg1))) 16) + #xffffff + 0 + ) + (set-vector! (-> (the-as (inline-array vector4w) v1-4) 5) 8184 6648 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-4) 6) #x2800 (* arg2 16) #xffffff #x10000) + ) + (&+! (-> arg0 base) 112) + 0 + (none) + ) + +(defmethod blit-displays-work-method-13 ((this blit-displays-work) (arg0 dma-buffer) (arg1 int) (arg2 int) (arg3 int)) + (set-display-gs-state arg0 408 512 416 0 0) + (dma-buffer-add-gs-set arg0 (rgbaq (new 'static 'gs-rgbaq :r #x80 :g #x80 :b #x80 :a #x80 :q 1.0))) + (let ((v1-3 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-3) 0 quad) (-> this sprite-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-3) 1 quad) (-> this sprite-tmpl quad 1)) + ) + (&+! (-> arg0 base) 32) + (dotimes (v1-6 16) + (let ((a0-10 (the-as object (-> arg0 base))) + (a2-2 (* v1-6 512)) + (a1-10 (* (+ v1-6 1) 512)) + ) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 0) (+ a2-2 arg3) arg1 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 1) a2-2 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 2) (+ a1-10 arg3) arg2 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 3) a1-10 6656 0 #x10000) + ) + (&+! (-> arg0 base) 64) + ) + 0 + (none) + ) + +(defmethod blit-displays-work-method-14 ((this blit-displays-work) (arg0 dma-buffer) (arg1 vector)) + (set-display-gs-state arg0 408 512 416 0 0) + (dma-buffer-add-gs-set arg0 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x3300 :tbw #x8 :tw #x9 :th #x9 :tcc #x1)) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (rgbaq (new 'static 'gs-rgbaq + :a #x80 + :q 1.0 + :b (the int (* 128.0 (-> arg1 z))) + :g (the int (* 128.0 (-> arg1 y))) + :r (the int (* 128.0 (-> arg1 x))) + ) + ) + (texflush 0) + ) + (let ((v1-3 (the-as object (-> arg0 base)))) + (set! (-> (the-as dma-gif-packet v1-3) dma-vif quad) (-> this sprite-tmpl dma-vif quad)) + (set! (-> (the-as dma-gif-packet v1-3) quad 1) (-> this sprite-tmpl quad 1)) + ) + (&+! (-> arg0 base) 32) + (dotimes (v1-6 16) + (let ((a0-10 (the-as object (-> arg0 base))) + (a2-14 (* v1-6 512)) + (a1-23 (* (+ v1-6 1) 512)) + ) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 0) (+ a2-14 8) 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 1) a2-14 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 2) (+ a1-23 8) 6664 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 3) a1-23 6656 0 0) + ) + (&+! (-> arg0 base) 64) + ) + 0 + (none) + ) + +(defmethod blit-displays-work-method-15 ((this blit-displays-work) (arg0 dma-buffer)) + (set-display-gs-state arg0 408 512 416 0 0) + (dma-buffer-add-gs-set arg0 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x4c0 :tbw #x8 :tw #x9 :th #x9 :tcc #x1)) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (rgbaq (new 'static 'gs-rgbaq :r #x80 :g #x80 :b #x80 :a #x80 :q 1.0)) + (texflush 0) + ) + (let ((v1-3 (the-as object (-> arg0 base)))) + (set! (-> (the-as dma-gif-packet v1-3) dma-vif quad) (-> this sprite-tmpl dma-vif quad)) + (set! (-> (the-as dma-gif-packet v1-3) quad 1) (-> this sprite-tmpl quad 1)) + ) + (&+! (-> arg0 base) 32) + (dotimes (v1-6 16) + (let ((a0-10 (the-as object (-> arg0 base))) + (a2-1 (+ (* v1-6 512) 8)) + (a1-22 (+ (* (+ v1-6 1) 512) 8)) + (a3-3 (* (- 16 v1-6) 512)) + (t0-3 (* (- 16 (+ v1-6 1)) 512)) + ) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 0) a2-1 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 1) a3-3 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 2) a1-22 6664 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 3) t0-3 6656 0 #x10000) + ) + (&+! (-> arg0 base) 64) + ) + (set-display-gs-state arg0 304 512 416 (shl #xff00 16) 48) + (dma-buffer-add-gs-set arg0 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x2600 :tbw #x8 :psm #x30 :tw #x9 :th #x9)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (texflush 0) + ) + (let ((a0-21 (the-as object (-> arg0 base))) + (a1-40 2640) + (v1-13 4560) + ) + (set! (-> (the-as (inline-array vector4w) a0-21) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) a0-21) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) a0-21) 2 quad) (-> this color quad)) + (set-vector! (-> (the-as (inline-array vector4w) a0-21) 3) 8192 a1-40 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-21) 4) 8 a1-40 #xffffff 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-21) 5) 6592 v1-13 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-21) 6) 1608 v1-13 #xffffff 0) + ) + (&+! (-> arg0 base) 112) + 0 + (none) + ) + +(defmethod draw-zoom-blur ((this blit-displays-work) (arg0 dma-buffer) (arg1 int)) + (let ((s2-0 (the-as object (-> arg0 base))) + (s5-0 (new 'stack-no-clear 'vector)) + ) + 0.0 + (let ((f26-0 512.0)) + 0.0 + (let ((f30-0 416.0) + (f28-0 (the float (-> this zoom-blur-texels))) + ) + (cond + ((-> this zoom-blur-2d) + (set! (-> s5-0 quad) (-> this zoom-blur-pos quad)) + (let* ((f2-0 (* 0.001953125 f28-0 (-> s5-0 x))) + (f0-6 (- f26-0 (- f28-0 f2-0))) + (f3-1 (* 0.0024038462 f28-0 (-> s5-0 y))) + (f1-4 (- f30-0 (- f28-0 f3-1))) + ) + (set! (-> (the-as (inline-array vector4w) s2-0) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) s2-0) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) s2-0) 2 quad) (-> this color quad)) + (set-vector! (-> (the-as (inline-array vector4w) s2-0) 3) (the int (* 16.0 f2-0)) (the int (* 16.0 f3-1)) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) s2-0) 4) 0 0 #xffffff 0) + (set-vector! + (-> (the-as (inline-array vector4w) s2-0) 5) + (the int (* 16.0 (+ -1.0 f0-6))) + (the int (* 16.0 (+ -1.0 f1-4))) + 0 + 0 + ) + ) + (set-vector! (-> (the-as (inline-array vector4w) s2-0) 6) #x2800 (* arg1 16) #xffffff #x10000) + (&+! (-> arg0 base) 112) + ) + (else + (transform-point-vector! s5-0 (-> this zoom-blur-pos)) + (if (< (-> s5-0 z) 0.0) + (vector-negate! s5-0 s5-0) + ) + (+! (-> s5-0 x) -1792.0) + (+! (-> s5-0 y) -1840.0) + (let* ((f1-10 (* 0.001953125 f28-0 (-> s5-0 x))) + (f2-8 (fmax 0.0 (fmin f1-10 f28-0))) + (f0-22 (- f26-0 (- f28-0 f2-8))) + (f3-4 (* 0.0024038462 f28-0 (-> s5-0 y))) + (f3-6 (fmax 0.0 (fmin f3-4 f28-0))) + (f1-16 (- f30-0 (- f28-0 f3-6))) + ) + (set! (-> (the-as (inline-array vector4w) s2-0) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) s2-0) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) s2-0) 2 quad) (-> this color quad)) + (set-vector! (-> (the-as (inline-array vector4w) s2-0) 3) (the int (* 16.0 f2-8)) (the int (* 16.0 f3-6)) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) s2-0) 4) 0 0 #xffffff 0) + (set-vector! + (-> (the-as (inline-array vector4w) s2-0) 5) + (the int (* 16.0 (+ -1.0 f0-22))) + (the int (* 16.0 (+ -1.0 f1-16))) + 0 + 0 + ) + ) + (set-vector! (-> (the-as (inline-array vector4w) s2-0) 6) #x2800 (* arg1 16) #xffffff #x10000) + (&+! (-> arg0 base) 112) + ) + ) + ) + ) + (let ((f0-29 0.0) + (f1-18 0.0) + ) + (if (< (-> s5-0 x) 0.0) + (set! f0-29 (fmin 1.0 (* 0.001953125 (- (-> s5-0 x))))) + ) + (if (< 512.0 (-> s5-0 x)) + (set! f0-29 (fmin 1.0 (* 0.001953125 (+ -512.0 (-> s5-0 x))))) + ) + (if (< (-> s5-0 y) 0.0) + (set! f1-18 (fmin 1.0 (* 0.001953125 (- (-> s5-0 y))))) + ) + (if (< 416.0 (-> s5-0 y)) + (set! f1-18 (fmin 1.0 (* 0.001953125 (+ -416.0 (-> s5-0 y))))) + ) + (let ((f0-32 (fmax f0-29 f1-18))) + (set! (-> this zoom-blur-alpha-current) (lerp (-> this zoom-blur-alpha-target) 1.0 f0-32)) + ) + ) + ) + (set-dirty-mask! (-> *level* level-default) 9 #xd0000 #x4c000) + 0 + (none) + ) + +(defmethod setup-zoom-blur-2d ((this blit-displays-work) (arg0 vector) (arg1 int) (arg2 float) (arg3 symbol)) + (set! (-> this zoom-blur-2d) arg3) + (set! (-> this zoom-blur-pos quad) (-> arg0 quad)) + (set! (-> this zoom-blur-texels) arg1) + (set! (-> this zoom-blur-alpha-target) arg2) + 0 + (none) + ) +(defmethod setup-brightness-and-contrast ((this blit-displays-work) (arg0 dma-buffer) (arg1 float) (arg2 float)) + (set-display-gs-state arg0 408 512 416 0 0) + (let ((s4-1 (fmax 0.0 (fmin 1.0 arg2))) + (s3-1 (fmax 0.0 (fmin 1.0 arg1))) + ) + (let ((v1-2 (the-as object (-> arg0 base)))) + (set! (-> (the-as dma-gif-packet v1-2) dma-vif quad) (-> this adgif-tmpl dma-vif quad)) + (set! (-> (the-as dma-gif-packet v1-2) quad 1) (-> this adgif-tmpl quad 1)) + (adgif-shader<-texture-simple! + (the-as adgif-shader (&+ (the-as dma-gif-packet v1-2) 32)) + (get-texture common-white common) + ) + ) + (&+! (-> arg0 base) 112) + (let ((v1-9 (the int (* 64.2509 (+ (- 0.5 s4-1) (* 2.0 (fmax 0.0 (+ -0.5 s3-1))))))) + (a0-10 (the int (fmin 255.0 (* 256.0 (fmin 1.0 (* 2.0 s3-1)) s4-1)))) + ) + (cond + ((>= v1-9 0) + (dma-buffer-add-gs-set arg0 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha :a #x1 :b #x2 :c #x2 :fix a0-10)) + (rgbaq (new 'static 'gs-rgbaq :a #x80 :q 1.0 :b v1-9 :g v1-9 :r v1-9)) + ) + ) + (else + (let ((v1-15 (- v1-9))) + (dma-buffer-add-gs-set arg0 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha :a #x1 :c #x2 :d #x2 :fix a0-10)) + (rgbaq (new 'static 'gs-rgbaq :a #x80 :q 1.0 :b v1-15 :g v1-15 :r v1-15)) + ) + ) + ) + ) + ) + ) + (let ((v1-21 (the-as object (-> arg0 base)))) + (set! (-> (the-as dma-gif-packet v1-21) dma-vif quad) (-> this contrast-tmpl dma-vif quad)) + (set! (-> (the-as dma-gif-packet v1-21) quad 1) (-> this contrast-tmpl quad 1)) + ) + (&+! (-> arg0 base) 32) + (dotimes (v1-24 16) + (let ((a0-27 (the-as object (-> arg0 base))) + (a2-12 (* v1-24 512)) + (a1-10 (* (+ v1-24 1) 512)) + ) + (set-vector! (-> (the-as (inline-array vector4w) a0-27) 0) 0 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-27) 1) a2-12 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-27) 2) 0 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-27) 3) a1-10 6656 0 0) + ) + (&+! (-> arg0 base) 64) + ) + 0 + (none) + ) + +;; TODO new jak3 effects +(defmethod do-blit-displays ((this blit-displays-work)) + (set! (-> this slow-time) (- 1.0 (-> *setting-control* user-current slow-time))) + (let ((v1-3 (-> *setting-control* user-current))) + (when (or (!= (-> v1-3 contrast) 0.5) (!= (-> v1-3 brightness) 0.5)) + ; (with-dma-buffer-add-bucket ((s4-0 (-> *display* frames (-> *display* on-screen) global-buf)) + ; (bucket-id debug-menu) + ; ) + ; (setup-brightness-and-contrast this s4-0 (-> v1-3 brightness) (-> v1-3 contrast)) + ; (reset-display-gs-state *display* s4-0) + ; ) + ) + ) + (when (zero? (-> this count-down)) + (cond + ((and (-> this menu-mode) (not (-> this screen-copied))) + (with-dma-buffer-add-bucket ((s4-1 (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id bucket3) + ) + (fx-copy-buf s4-1) + ) + (set! (-> this vu1-enable-user-menu) (-> *display* vu1-enable-user-menu)) + ;; og:preserve-this + (set! (-> *display* vu1-enable-user-menu) (vu1-renderer-mask merc)) + (set! (-> *display* vu1-enable-user) (vu1-renderer-mask merc)) + (set! (-> this texture-enable-user-menu) (the-as uint (-> *texture-pool* texture-enable-user-menu))) + (set! (-> *texture-pool* texture-enable-user-menu) (texture-enable-mask shrub water hud)) + (set! (-> *texture-pool* texture-enable-user) (texture-enable-mask shrub water hud)) + (set! (-> this count-down) (the-as uint 3)) + (set! (-> this screen-copied) #t) + (set! (-> this progress-interp) 0.0) + (set! (-> this progress-interp-dest) 1.0) + (set! (-> this progress-interp-speed) 0.033333335) + (#when PC_PORT + (when (-> *pc-settings* fast-progress?) + (*! (-> this progress-interp-speed) (-> *pc-cheat-state* progress-speed)) + ) + ) + ) + ((and (not (get-menu-mode this)) (get-screen-copied this)) + (set! (-> *display* vu1-enable-user-menu) (-> this vu1-enable-user-menu)) + (set! (-> *texture-pool* texture-enable-user-menu) + (the-as texture-enable-mask (-> this texture-enable-user-menu)) + ) + (set! (-> this count-down) (the-as uint 3)) + (set! (-> this screen-copied) #f) + ) + ) + ) + (when (and (-> *setting-control* user-current render) (>= (the-as uint 1) (-> this count-down))) + (when (and (get-horizontal-flip-flag this) (not (get-menu-mode this))) + ; (with-dma-buffer-add-bucket ((s4-2 (-> *display* frames (-> *display* on-screen) global-buf)) + ; (bucket-id debug-no-zbuf1) + ; ) + ; (fx-copy-buf s4-2) + ; (blit-displays-work-method-15 this s4-2) + ; (reset-display-gs-state *display* s4-2) + ; ) + ) + ; (when (logtest? (vu1-renderer-mask rn36) (-> *display* vu1-enable-user)) + ; (when (not *display-color-bars*) + ; (with-dma-buffer-add-bucket ((s4-3 (-> *display* frames (-> *display* on-screen) global-buf)) + ; (bucket-id bucket567) + ; ) + ; (dma-buffer-add-gs-set s4-3 + ; (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + ; (alpha-1 (new 'static 'gs-alpha)) + ; (tex0-1 (new 'static 'gs-tex0 :tbp0 #x3300 :tbw #x8 :tw #x9 :th #x9 :tcc #x1)) + ; (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + ; (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + ; (texflush 0) + ; ) + ; (if (or (zero? *screen-shot-work*) (= (-> *screen-shot-work* count) -1)) + ; (blit-displays-work-method-13 this s4-3 0 6656 8) + ; ) + ; (reset-display-gs-state *display* s4-3) + ; ) + ; ) + ; ) + ) + (let ((f0-9 (-> this slow-time)) + (a2-6 (-> *time-of-day-context* filter)) + (s5-4 (new 'stack-no-clear 'vector)) + ) + (set-vector! s5-4 1.0 1.0 1.5 1.0) + (vector4-lerp! s5-4 s5-4 a2-6 f0-9) + (when (and (or (!= (-> s5-4 x) 1.0) (!= (-> s5-4 y) 1.0) (!= (-> s5-4 z) 1.0)) (not (get-menu-mode this))) + ; (with-dma-buffer-add-bucket ((s3-0 (-> *display* frames (-> *display* on-screen) global-buf)) + ; (bucket-id tex-hud-hud-alpha) + ; ) + ; (blit-displays-work-method-14 this s3-0 s5-4) + ; (reset-display-gs-state *display* s3-0) + ; ) + ) + ) + (cond + ((and (-> *setting-control* user-current render) (zero? (-> this count-down))) + ; (with-dma-buffer-add-bucket ((s4-5 (-> *display* frames (-> *display* on-screen) global-buf)) + ; (bucket-id bucket3) + ; ) + ; (dma-buffer-add-gs-set s4-5 + ; (dthe (new 'static 'gs-dthe)) + ; (prmodecont (new 'static 'gs-prmode-cont :ac #x1)) + ; (colclamp (new 'static 'gs-color-clamp :clamp #x1)) + ; (pabe 0) + ; (texa (new 'static 'gs-texa :ta1 #x80)) + ; (texclut (new 'static 'gs-texclut :cbw #x4)) + ; (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + ; (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + ; (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + ; (fogcol *fog-color*) + ; (texflush 0) + ; ) + ; (let* ((s0-0 *video-params*) + ; (s1-0 (-> s0-0 display-fbp)) + ; (s3-1 (-> s0-0 display-sy)) + ; ) + ; (let ((s2-0 (* s3-1 2))) + ; (dma-buffer-add-gs-set s4-5 + ; (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + ; (tex0-1 (new 'static 'gs-tex0 :tbp0 #x3300 :tbw #x8 :tw #x9 :th #x9)) + ; ) + ; (cond + ; ((or (zero? (-> this zoom-blur-texels)) (or (= (-> this zoom-blur-alpha-target) 1.0) (paused?))) + ; (let ((f0-14 (-> this slow-time)) + ; (f30-0 1.0) + ; ) + ; (if (!= f0-14 1.0) + ; (set! f30-0 (lerp 0.05 1.0 f0-14)) + ; ) + ; (set-display-gs-state s4-5 (-> s0-0 display-fbp) 640 s2-0 (shl #xff00 16) 0) + ; (if (= f30-0 1.0) + ; (blit-displays-work-method-9 this s4-5 416 s2-0 128) + ; (blit-displays-work-method-10 this s4-5 416 s2-0 (the int (* 128.0 f30-0))) + ; ) + ; ) + ; ) + ; (else + ; (set-display-gs-state s4-5 38 512 416 (shl #xff00 16) 0) + ; (dma-buffer-add-gs-set s4-5 + ; (tex0-1 (new 'static 'gs-tex0 :tbw #xa :tw #xa :th #x9 :tbp0 (* (-> s0-0 display-fbp) 32))) + ; ) + ; (blit-displays-work-method-11 this s4-5 s2-0) + ; (set-display-gs-state s4-5 s1-0 640 s2-0 (shl #xff00 16) 0) + ; (dma-buffer-add-gs-set s4-5 (tex0-1 (new 'static 'gs-tex0 :tbp0 #x4c0 :tbw #x8 :tw #x9 :th #x9))) + ; (draw-zoom-blur this s4-5 s2-0) + ; (dma-buffer-add-gs-set s4-5 (tex0-1 (new 'static 'gs-tex0 :tbp0 #x3300 :tbw #x8 :tw #x9 :th #x9))) + ; (blit-displays-work-method-9 this s4-5 416 s2-0 (the int (* 128.0 (-> this zoom-blur-alpha-current)))) + ; (when (or (!= (-> *setting-control* user-current letterbox) 0.0) + ; (< (-> *display* base-clock frame-counter) (-> *game-info* letterbox-time)) + ; ) + ; (when (and (= (-> *setting-control* user-current aspect-ratio) 'aspect4x3) + ; (or (zero? *screen-shot-work*) (= (-> *screen-shot-work* count) -1)) + ; ) + ; (let ((f0-24 (the-as float (if (< (-> *display* base-clock frame-counter) (-> *game-info* letterbox-time)) + ; 1.0 + ; (-> *setting-control* user-current letterbox) + ; ) + ; ) + ; ) + ; (f1-15 (* 0.0024038462 (the float s2-0))) + ; ) + ; (draw-letterbox this s4-5 f0-24 s2-0 f1-15) + ; ) + ; ) + ; ) + ; ) + ; ) + ; ) + ; (when (!= (-> *setting-control* user-current scanlines) 0.0) + ; (let ((v1-213 (the int (* 128.0 (-> *setting-control* user-current scanlines))))) + ; (set! (-> this line-color) + ; (logior (logand (-> this line-color) (the-as uint #xffffffff00ffffff)) (shr (shl v1-213 56) 32)) + ; ) + ; (dotimes (a0-120 15) + ; (set! (-> this scan-colors a0-120 w) v1-213) + ; ) + ; ) + ; (dma-buffer-add-gs-set s4-5 + ; (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + ; (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + ; (rgbaq (-> this line-color)) + ; ) + ; (dotimes (v1-219 (/ s3-1 32)) + ; (let ((a0-127 (the-as object (-> s4-5 base)))) + ; (set! (-> (the-as dma-gif-packet a0-127) dma-vif quad) (-> this line-tmpl dma-vif quad)) + ; (set! (-> (the-as dma-gif-packet a0-127) quad 1) (-> this line-tmpl quad 1)) + ; ) + ; (&+! (-> s4-5 base) 32) + ; (dotimes (a0-130 16) + ; (let ((a1-115 (the-as object (-> s4-5 base))) + ; (a2-25 (* (+ (* v1-219 64) (* a0-130 4)) 16)) + ; ) + ; (set-vector! (-> (the-as (inline-array vector4w) a1-115) 0) 0 a2-25 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) a1-115) 1) #x2800 a2-25 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) a1-115) 2) 0 (+ a2-25 16) 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) a1-115) 3) #x2800 (+ a2-25 16) 0 0) + ; ) + ; (&+! (-> s4-5 base) 64) + ; ) + ; ) + ; (dma-buffer-add-gs-set s4-5 (alpha-1 (new 'static 'gs-alpha :b #x2 :d #x1))) + ; (let ((v1-225 (the-as object (-> s4-5 base)))) + ; (set! (-> (the-as dma-gif-packet v1-225) dma-vif quad) (-> this scan-tmpl dma-vif quad)) + ; (set! (-> (the-as dma-gif-packet v1-225) quad 1) (-> this scan-tmpl quad 1)) + ; ) + ; (&+! (-> s4-5 base) 32) + ; (let ((a0-142 (* (-> this scanline) 32))) + ; (dotimes (v1-229 15) + ; (let ((a1-126 (the-as object (-> s4-5 base)))) + ; (set! (-> (the-as (inline-array vector4w) a1-126) 0 quad) (-> this scan-colors v1-229 quad)) + ; (set-vector! (-> (the-as (inline-array vector4w) a1-126) 1) 0 (the-as int a0-142) 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) a1-126) 2) #x2800 (the-as int a0-142) 0 0) + ; (let ((a0-143 (+ a0-142 16))) + ; (set-vector! (-> (the-as (inline-array vector4w) a1-126) 3) 0 (the-as int a0-143) 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) a1-126) 4) #x2800 (the-as int a0-143) 0 0) + ; (set! a0-142 (+ a0-143 16)) + ; ) + ; ) + ; (&+! (-> s4-5 base) 80) + ; ) + ; ) + ; (if (not (paused?)) + ; (set! (-> this scanline) (the-as uint (mod (the-as int (+ (-> this scanline) 4)) s3-1))) + ; ) + ; ) + ; ) + ; (reset-display-gs-state *display* s4-5) + ; ) + ) + (else + ; (with-dma-buffer-add-bucket ((s4-6 (-> *display* frames (-> *display* on-screen) global-buf)) + ; (bucket-id bucket3) + ; ) + ; (reset-display-gs-state *display* s4-6) + ; ) + ) + ) + (when (nonzero? (-> this count-down)) + (+! (-> this count-down) -1) + ;; og:preserve-this + (with-dma-buffer-add-bucket ((buf (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id bucket3) + ) + (dma-buffer-add-cnt-vif2 buf 0 (new 'static 'vif-tag :cmd (vif-cmd pc-port) :imm #x11) ;; kind - do nothing + (new 'static 'vif-tag :cmd (vif-cmd pc-port))) + ) + ) + 0 + (none) + ) + +(defmethod draw-sky ((this blit-displays-work) (arg0 dma-buffer)) + (let ((f0-0 (-> this progress-interp)) + (v1-0 *time-of-day-context*) + ) + (dma-buffer-add-gs-set arg0 + (zbuf-1 (new 'static 'gs-zbuf :zbp #x130 :psm (gs-psm ct24))) + (test-1 (new 'static 'gs-test :ate #x1 :atst (gs-atest always) :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x4c0 :tbw #x8 :tw #x9 :th #x9 :tcc #x1)) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (texflush 0) + ) + ;; og:preserve-this + ; (let ((a3-17 (the-as object (-> arg0 base))) + ; (t0-0 #x7000) + ; (t1-0 #x7300) + ; (a0-4 #x7800) + ; (a2-6 #x7980) + ; ) + ; (set! (-> (the-as (inline-array vector4w) a3-17) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + ; (set! (-> (the-as (inline-array vector4w) a3-17) 1 quad) (-> this sprite-slow-tmpl quad 1)) + ; (set-vector! (-> (the-as (inline-array vector4w) a3-17) 2) 128 128 128 128) + ; (set-vector! (-> (the-as (inline-array vector4w) a3-17) 3) 8 8 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) a3-17) 4) t0-0 t1-0 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) a3-17) 5) 8200 6664 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) a3-17) 6) a0-4 a2-6 0 0) + ; ) + ; (&+! (-> arg0 base) 112) + (let ((t1-3 (the-as object (-> arg0 base))) + (a3-19 #x8000) + (t0-2 #x8000) + (a0-7 #x9000) + (a2-7 #x8d00) + ) + (set! (-> (the-as (inline-array vector4w) t1-3) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) t1-3) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) t1-3) 2) 128 128 128 128) + (set-vector! (-> (the-as (inline-array vector4w) t1-3) 3) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t1-3) 4) a3-19 t0-2 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t1-3) 5) 8200 6664 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t1-3) 6) a0-7 a2-7 0 0) + (&+! (-> arg0 base) 112) + (dma-buffer-add-gs-set arg0 + (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x3300 :tbw #x8 :tw #x9 :th #x9 :tcc #x1)) + (texflush 0) + ) + (let ((t1-10 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) t1-10) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) t1-10) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) t1-10) 2) 128 128 128 80) + (set-vector! (-> (the-as (inline-array vector4w) t1-10) 3) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t1-10) 4) a3-19 (+ t0-2 -8) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t1-10) 5) 2056 1672 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t1-10) 6) a0-7 (+ a2-7 -8) 0 0) + ) + ) + (&+! (-> arg0 base) 112) + (dma-buffer-add-gs-set arg0 (alpha-1 (new 'static 'gs-alpha))) + (let ((a0-16 (the int (+ 128.0 (* 32.0 f0-0)))) + (a2-16 (the int (- 128.0 (* 16.0 f0-0)))) + (a3-31 (the int (- 128.0 (* 96.0 f0-0)))) + ) + (when (or (!= (-> v1-0 filter x) 1.0) (!= (-> v1-0 filter y) 1.0) (!= (-> v1-0 filter z) 1.0)) + (set! a0-16 128) + (set! a2-16 128) + (set! a3-31 128) + ) + ;; og:preserve-this + (let ((v1-57 (* (get-current-game-height *pc-settings*) 16)) + (a3-16 0) + ) + (let ((t1-22 (the-as (inline-array qword) (-> arg0 base)))) + (set! (-> t1-22 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> t1-22 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> t1-22 2 vector4w) a0-16 a2-16 a3-31 128) + (set-vector! (-> t1-22 3 vector4w) (* 0 16) v1-57 0 0) + (set-vector! (-> t1-22 4 vector4w) (* 1792 16) #x7300 0 0) + (set-vector! (-> t1-22 5 vector4w) (* (get-current-game-width *pc-settings*) 16) a3-16 0 0) + (set-vector! (-> t1-22 6 vector4w) (* 2304 16) #x8d00 0 0) + (&+! (-> arg0 base) 112) + ) + ) + ; (let ((v1-5 3328) + ; (t0-9 6656) + ; ) + ; (dotimes (t1-11 16) + ; (let ((t2-22 (the-as object (-> arg0 base))) + ; (t4-0 (* (+ (* t1-11 32) 1792) 16)) + ; (t3-35 (* (+ (* (+ t1-11 1) 32) 1792) 16)) + ; ) + ; (let ((t6-0 (* (+ (* t1-11 16) 256) 16)) + ; (t5-5 (* (+ (* (+ t1-11 1) 16) 256) 16)) + ; ) + ; (set! (-> (the-as (inline-array vector4w) t2-22) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + ; (set! (-> (the-as (inline-array vector4w) t2-22) 1 quad) (-> this sprite-slow-tmpl quad 1)) + ; (set-vector! (-> (the-as (inline-array vector4w) t2-22) 2) a0-16 a2-16 a3-31 128) + ; (set-vector! (-> (the-as (inline-array vector4w) t2-22) 3) t6-0 (+ v1-5 8) 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) t2-22) 4) t4-0 #x72f8 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) t2-22) 5) t5-5 (+ t0-9 8) 0 0) + ; ) + ; (set-vector! (-> (the-as (inline-array vector4w) t2-22) 6) t3-35 #x8cf8 0 0) + ; ) + ; (&+! (-> arg0 base) 112) + ; ) + ; ) + ; (dma-buffer-add-gs-set arg0 + ; (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + ; (tex0-1 (new 'static 'gs-tex0 :tbp0 #x4c0 :tbw #x8 :tw #x9 :th #x9 :tcc #x1)) + ; (texflush 0) + ; ) + ; (let ((v1-11 (the-as object (-> arg0 base)))) + ; (set! (-> (the-as (inline-array vector4w) v1-11) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + ; (set! (-> (the-as (inline-array vector4w) v1-11) 1 quad) (-> this sprite-slow-tmpl quad 1)) + ; (set-vector! + ; (-> (the-as (inline-array vector4w) v1-11) 2) + ; a0-16 + ; a2-16 + ; a3-31 + ; (the int (- 128.0 (* 48.0 f0-0))) + ; ) + ; (set-vector! (-> (the-as (inline-array vector4w) v1-11) 3) 8 8 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) v1-11) 4) #x7000 #x72f8 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) v1-11) 5) 8200 6664 0 0) + ; (set-vector! (-> (the-as (inline-array vector4w) v1-11) 6) #x9000 #x8cf8 0 0) + ; ) + ) + ) + ; (&+! (-> arg0 base) 112) + (seek! (-> this progress-interp) (-> this progress-interp-dest) (-> this progress-interp-speed)) + 0 + (none) + ) + +;; WARN: Return type mismatch pointer vs none. +(defun draw-color-bars ((arg0 blit-displays-work)) + (with-dma-buffer-add-bucket ((s5-0 (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id debug-no-zbuf2) + ) + (let ((v1-5 (the-as object (-> s5-0 base)))) + (set! (-> (the-as dma-gif-packet v1-5) dma-vif quad) (-> arg0 adgif-tmpl dma-vif quad)) + (set! (-> (the-as dma-gif-packet v1-5) quad 1) (-> arg0 adgif-tmpl quad 1)) + (adgif-shader<-texture-simple! + (the-as adgif-shader (&+ (the-as dma-gif-packet v1-5) 32)) + (get-texture colorbars13 programmer) + ) + ) + (&+! (-> s5-0 base) 112) + (let ((v1-8 (the-as object (-> s5-0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-8) 0 quad) (-> arg0 sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-8) 1 quad) (-> arg0 sprite-slow-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) v1-8) 2 quad) (-> arg0 color quad)) + (set-vector! (-> (the-as (inline-array vector4w) v1-8) 3) 32 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-8) 4) #x7000 #x7300 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-8) 5) 480 256 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-8) 6) #x9000 #x8d00 0 0) + ) + (&+! (-> s5-0 base) 112) + ) + (none) + ) + +;; WARN: Return type mismatch pointer vs none. +(defun draw-raw-image ((arg0 blit-displays-work) + (arg1 bucket-id) + (arg2 art-group) + (arg3 vector) + (arg4 vector) + (arg5 level) + (arg6 int) + ) + (local-vars (sv-16 blit-displays-work) (sv-32 int)) + (set! sv-16 *blit-displays-work*) + (with-dma-buffer-add-bucket ((s1-0 (-> *display* frames (-> *display* on-screen) global-buf)) + arg1 + ) + ;; og:preserve-this + (#when PC_PORT + ;; draw a black rectangle covering the screen first + (draw-sprite2d-xy s1-0 0 0 512 416 (static-rgba 0 0 0 128) #x3fffff) + ) + ; (upload-vram-data s1-0 0 (the-as pointer arg2) (the int (-> arg3 y)) (the int (-> arg3 x))) + (pc-upload-raw-texture s1-0 (the pointer arg2) (the int (-> arg3 x)) (the int (-> arg3 y)) 0) + (set! sv-32 (+ (log2 (+ (the int (-> arg3 x)) -1)) 1)) + (let ((v1-9 (+ (log2 (+ (the int (-> arg3 y)) -1)) 1))) + (dma-buffer-add-gs-set s1-0 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha)) + (tex0-1 (new 'static 'gs-tex0 :tcc #x1 :th v1-9 :tw sv-32 :tbw (/ (the int (-> arg3 x)) 64))) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (texflush 0) + ) + ) + (let ((v1-20 (the-as object (-> s1-0 base))) + (f0-10 (-> *video-params* relative-x-scale)) + ) + (set! (-> (the-as (inline-array vector4w) v1-20) 0 quad) (-> sv-16 sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-20) 1 quad) (-> sv-16 sprite-slow-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) v1-20) 2 quad) (-> sv-16 color quad)) + (set-vector! (-> (the-as (inline-array vector4w) v1-20) 3) 0 0 0 0) + (set-vector! + (-> (the-as (inline-array vector4w) v1-20) 4) + (* (- 2048 (the int (* 256.0 f0-10 (-> arg4 x)))) 16) + (* (- 2048 (the int (* 208.0 (-> arg4 y)))) 16) + 0 + 0 + ) + (set-vector! + (-> (the-as (inline-array vector4w) v1-20) 5) + (* (the int (-> arg3 x)) 16) + (* (the int (-> arg3 y)) 16) + 0 + 0 + ) + (set-vector! + (-> (the-as (inline-array vector4w) v1-20) 6) + (* (+ (the int (* 256.0 f0-10 (-> arg4 x))) 2048) 16) + (* (+ (the int (* 208.0 (-> arg4 y))) 2048) 16) + 0 + 0 + ) + ;; og:preserve-this + (#when PC_PORT + (when (not (-> *pc-settings* use-vis?)) + (let ((corrected-width (the int (* (-> *pc-settings* aspect-ratio-reciprocal) #x1000)))) + (set-vector! (-> (the-as (inline-array vector4w) v1-20) 4) (- #x8000 corrected-width) #x7300 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-20) 6) (+ #x8000 corrected-width) #x8d00 0 0) + ) + ) + ) + ) + (&+! (-> s1-0 base) 112) + (set-dirty-mask! arg5 arg6 (* (* (the int (-> arg3 y)) (the int (-> arg3 x))) 4) 0) + ) + (none) + ) diff --git a/goal_src/jak3/engine/gfx/font-h.gc b/goal_src/jak3/engine/gfx/font-h.gc index b014473dfe..ce1ceb12d0 100644 --- a/goal_src/jak3/engine/gfx/font-h.gc +++ b/goal_src/jak3/engine/gfx/font-h.gc @@ -725,10 +725,10 @@ (none) ) -(defun set-font-color ((arg0 font-color) (arg1 int) (arg2 rgba) (arg3 rgba) (arg4 rgba)) - (set! (-> *font-work* color-table arg0 color 0) (the-as rgba arg1)) - (set! (-> *font-work* color-table arg0 color 1) arg2) - (set! (-> *font-work* color-table arg0 color 2) arg3) - (set! (-> *font-work* color-table arg0 color 3) arg4) +(defun set-font-color ((idx font-color) (clr0 rgba) (clr1 rgba) (clr2 rgba) (clr3 rgba)) + (set! (-> *font-work* color-table idx color 0) clr0) + (set! (-> *font-work* color-table idx color 1) clr1) + (set! (-> *font-work* color-table idx color 2) clr2) + (set! (-> *font-work* color-table idx color 3) clr3) 0 ) diff --git a/goal_src/jak3/engine/gfx/foreground/foreground.gc b/goal_src/jak3/engine/gfx/foreground/foreground.gc index f3ff9fd955..eeb698479b 100644 --- a/goal_src/jak3/engine/gfx/foreground/foreground.gc +++ b/goal_src/jak3/engine/gfx/foreground/foreground.gc @@ -1633,6 +1633,7 @@ (disable-fog 1) (pc-blerc 2) (disable-envmap 3) + (no-textures 4) ) (deftype pc-merc-flags (structure) @@ -1750,6 +1751,9 @@ (when (logtest? (-> dc global-effect) (draw-control-global-effect disable-envmap)) (logior! (-> flags bit-flags) (pc-merc-bits disable-envmap)) ) + (when (logtest? (-> dc global-effect) (draw-control-global-effect no-textures)) + (logior! (-> flags bit-flags) (pc-merc-bits no-textures)) + ) (set! (-> flags enable-mask) enable-mask) (set! (-> flags ignore-alpha-mask) ignore-alpha-mask) ) @@ -2102,7 +2106,8 @@ ) (cond ((or (nonzero? (-> bucket-info must-use-mercneric-for-clip)) - (or (< 0.0 t-amount) (logtest? (-> geo effect effect-idx effect-bits) (effect-bits cross-fade))) + ;; force envmap mode, even if strength is zero - PC renderer will handle this case. + (or #t #|(< 0.0 t-amount)|# (logtest? (-> geo effect effect-idx effect-bits) (effect-bits cross-fade))) ) (let ((a0-33 (&-> tint-info tint)) (v1-74 (the-as object (-> bucket-info effect effect-idx))) diff --git a/goal_src/jak3/engine/gfx/mood/time-of-day.gc b/goal_src/jak3/engine/gfx/mood/time-of-day.gc index b0d9898703..31bb86a1aa 100644 --- a/goal_src/jak3/engine/gfx/mood/time-of-day.gc +++ b/goal_src/jak3/engine/gfx/mood/time-of-day.gc @@ -549,7 +549,9 @@ ) ) (if (-> arg0 sky) - (set! (-> (&-> *level* level-default texture-anim-array 9) 0) *sky-texture-anim-array*) + ;; og:preserve-this + (set! (-> (&-> *level* level-default texture-anim-array 9) 0) (#if PC_PORT (if *hires-sky* *sky-hires-texture-anim-array* *sky-texture-anim-array*) + *sky-texture-anim-array*)) (set! (-> (&-> *level* level-default texture-anim-array 9) 0) #f) ) (let ((s5-2 (level-get-target-inside *level*))) diff --git a/goal_src/jak3/engine/gfx/sky/sky-tng.gc b/goal_src/jak3/engine/gfx/sky/sky-tng.gc index ca03233c1a..adc477d210 100644 --- a/goal_src/jak3/engine/gfx/sky/sky-tng.gc +++ b/goal_src/jak3/engine/gfx/sky/sky-tng.gc @@ -17,6 +17,7 @@ ;; (def-mips2c clip-polygon-against-negative-hyperplane function) (def-mips2c render-sky-quad (function (inline-array sky-vertex) dma-buffer none)) + (def-mips2c render-sky-tri (function (inline-array sky-vertex) dma-buffer none)) ;; WARN: Return type mismatch pointer vs none. @@ -730,7 +731,7 @@ (with-dma-buffer-add-bucket ((s5-2 (-> *display* frames (-> *display* on-screen) global-buf)) (bucket-id sky) ) - (blit-displays-work-method-20 *blit-displays-work*) + (draw-sky *blit-displays-work* s5-2) ) ) (else diff --git a/goal_src/jak3/engine/gfx/texture/texture-anim-tables.gc b/goal_src/jak3/engine/gfx/texture/texture-anim-tables.gc index d74ed8ded9..af81ef3d26 100644 --- a/goal_src/jak3/engine/gfx/texture/texture-anim-tables.gc +++ b/goal_src/jak3/engine/gfx/texture/texture-anim-tables.gc @@ -419,9 +419,614 @@ ) ) +;; og:preserve-this +(#when PC_PORT +(define *sky-hires-texture-anim-array* + (the (texture-anim-array texture-anim) + (new 'static 'texture-anim-array :type texture-anim + (new 'static 'texture-anim + :func-id 'texture-anim-alpha-ramp-clut-upload + :init-func-id 'texture-anim-alpha-ramp-clut-init + :tex #f + :tex-name #f + :extra (new 'static 'vector :x 24.0) + :color (new 'static 'rgba :a #x80) + :test (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x1 :d #x1) + :data (new 'static 'array texture-anim-layer 0) + ) + (new 'static 'texture-anim + :num-layers #x2 + :func-id 'cloud-texture-anim-func + :init-func-id 'dest-texture-init + :tex #f + :tex-name #f + :extra (new 'static 'vector :x 16.0 :y 4.0) + :color (new 'static 'rgba :a #x80) + :frame-delta 300.0 + :frame-mod 9600.0 + :test (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x1 :d #x1) + :data (new 'static 'array texture-anim-layer 2 + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 16.0 :y 16.0 :z 24.0) + :func-id 'cloud-texture-anim-layer-func + :init-func-id 'noise-texture-init + :tex #f + :end-time 9600.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 16.0 :y 16.0 :z 24.0) + :func-id 'cloud-texture-anim-layer-func + :init-func-id 'noise-texture-init + :tex #f + :end-time 9600.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + ) + ) + (new 'static 'texture-anim + :num-layers #x2 + :func-id 'cloud-texture-anim-func + :init-func-id 'dest-texture-init + :tex #f + :tex-name #f + :extra (new 'static 'vector :x 32.0 :y 5.0) + :color (new 'static 'rgba :a #x80) + :frame-delta 300.0 + :frame-mod 4800.0 + :test (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x1 :d #x1) + :data (new 'static 'array texture-anim-layer 2 + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 32.0 :y 16.0 :z 24.0) + :func-id 'cloud-texture-anim-layer-func + :init-func-id 'noise-texture-init + :tex #f + :end-time 4800.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 32.0 :y 16.0 :z 24.0) + :func-id 'cloud-texture-anim-layer-func + :init-func-id 'noise-texture-init + :tex #f + :end-time 4800.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + ) + ) + (new 'static 'texture-anim + :num-layers #x2 + :func-id 'cloud-texture-anim-func + :init-func-id 'dest-texture-init + :tex #f + :tex-name #f + :extra (new 'static 'vector :x 64.0 :y 6.0) + :color (new 'static 'rgba :a #x80) + :frame-delta 300.0 + :frame-mod 2400.0 + :test (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x1 :d #x1) + :data (new 'static 'array texture-anim-layer 2 + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 64.0 :y 16.0 :z 24.0) + :func-id 'cloud-texture-anim-layer-func + :init-func-id 'noise-texture-init + :tex #f + :end-time 2400.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 64.0 :y 16.0 :z 24.0) + :func-id 'cloud-texture-anim-layer-func + :init-func-id 'noise-texture-init + :tex #f + :end-time 2400.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + ) + ) + (new 'static 'texture-anim + :num-layers #x2 + :func-id 'cloud-texture-anim-func + :init-func-id 'dest-texture-init + :tex #f + :tex-name #f + :extra (new 'static 'vector :x 128.0 :y 8.0) + :color (new 'static 'rgba :a #x80) + :frame-delta 300.0 + :frame-mod 1200.0 + :test (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x1 :d #x1) + :data (new 'static 'array texture-anim-layer 2 + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 128.0 :y 16.0 :z 24.0) + :func-id 'cloud-texture-anim-layer-func + :init-func-id 'noise-texture-init + :tex #f + :end-time 1200.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 128.0 :y 16.0 :z 24.0) + :func-id 'cloud-texture-anim-layer-func + :init-func-id 'noise-texture-init + :tex #f + :end-time 1200.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + ) + ) + (new 'static 'texture-anim + :num-layers #x2 + :func-id 'cloud-texture-anim-func + :init-func-id 'dest-texture-init + :tex #f + :tex-name #f + :extra (new 'static 'vector :x 256.0 :y 8.0) + :color (new 'static 'rgba :a #x80) + :frame-delta 300.0 + :frame-mod 600.0 + :test (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x1 :d #x1) + :data (new 'static 'array texture-anim-layer 2 + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 256.0 :y 16.0 :z 24.0) + :func-id 'cloud-texture-anim-layer-func + :init-func-id 'noise-texture-init + :tex #f + :end-time 600.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 256.0 :y 16.0 :z 24.0) + :func-id 'cloud-texture-anim-layer-func + :init-func-id 'noise-texture-init + :tex #f + :end-time 600.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + ) + ) + (new 'static 'texture-anim + :num-layers #x2 + :func-id 'cloud-texture-anim-func + :init-func-id 'dest-texture-init + :tex #f + :tex-name #f + :extra (new 'static 'vector :x 512.0 :y 8.0) + :color (new 'static 'rgba :a #x80) + :frame-delta 300.0 + :frame-mod 450.0 + :test (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x1 :d #x1) + :data (new 'static 'array texture-anim-layer 2 + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 512.0 :y 16.0 :z 24.0) + :func-id 'cloud-texture-anim-layer-func + :init-func-id 'noise-texture-init + :tex #f + :end-time 450.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 512.0 :y 16.0 :z 24.0) + :func-id 'cloud-texture-anim-layer-func + :init-func-id 'noise-texture-init + :tex #f + :end-time 450.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + ) + ) + (new 'static 'texture-anim + :num-layers 6 + :func #f + :init-func-id 'dest-texture-init + :tex #f + :tex-name #f + :extra (new 'static 'vector :x 512.0 :y 16.0) + :color (new 'static 'rgba :a #x80) + :test (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x1 :d #x1) + :data (new 'static 'array texture-anim-layer 6 + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 16.0 :y 4.0) + :func-id 'default-texture-anim-layer-func + :init-func-id 'src-texture-init + :tex #f + :end-time 300.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 0.49) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 32.0 :y 5.0) + :func-id 'default-texture-anim-layer-func + :init-func-id 'src-texture-init + :tex #f + :end-time 300.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 0.19) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 64.0 :y 6.0) + :func-id 'default-texture-anim-layer-func + :init-func-id 'src-texture-init + :tex #f + :end-time 300.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 0.145) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 128.0 :y 8.0) + :func-id 'default-texture-anim-layer-func + :init-func-id 'src-texture-init + :tex #f + :end-time 300.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 0.015) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 256.0 :y 8.0) + :func-id 'default-texture-anim-layer-func + :init-func-id 'src-texture-init + :tex #f + :end-time 300.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 0.01) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 512.0 :y 8.0) + :func-id 'default-texture-anim-layer-func + :init-func-id 'src-texture-init + :tex #f + :end-time 300.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x2 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 0.0075) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + ) + ) + (new 'static 'texture-anim + :num-layers #x1 + :func #f + :init-func-id 'dest-texture-init + :tex #f + :tex-name #f + :extra (new 'static 'vector :x 512.0 :y 8.0) + :color (new 'static 'rgba :a #x80) + :test (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x1 :d #x1) + :data (new 'static 'array texture-anim-layer 2 + (new 'static 'texture-anim-layer + :extra (new 'static 'vector :x 512.0 :y 16.0) + :func-id 'move-rg-to-ba-texture-anim-layer-func + :init-func-id 'src-texture-init + :tex #f + :end-time 300.0 + :tex-name #f + :test (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x1 :d #x1) + :start-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :start-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :start-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :start-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-color (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + :end-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-st-scale (new 'static 'vector2 :data (new 'static 'array float 2 1.0 1.0)) + :end-st-offset (new 'static 'vector2 :data (new 'static 'array float 2 0.5 0.5)) + :end-qs (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) + ) + ) + ) + (new 'static 'texture-anim + :func-id 'texture-anim-cloud-clut-upload + :init-func-id 'texture-anim-cloud-clut-init + :tex #f + :tex-name #f + :extra (new 'static 'vector :x 24.0 :y 0.5 :z 1.0) + :color (new 'static 'rgba :a #x80) + :test (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x1 :d #x1) + :data (new 'static 'array texture-anim-layer 2) + ) + (new 'static 'texture-anim + :func-id 'fog-texture-anim-func + :init-func-id 'fog-texture-anim-init + :tex #f + :tex-name #f + :extra (new 'static 'vector :x 4.0 :y 6.0 :z 122880.0) + :color (new 'static 'rgba :a #x80) + :test (new 'static 'gs-test :ate #x1 :afail #x1 :zte #x1 :ztst (gs-ztest always)) + :alpha (new 'static 'gs-alpha :b #x1 :d #x1) + :data (new 'static 'array texture-anim-layer 2) + ) + ) + ) + ) + +(defun set-layer-scale! ((n int) (val float)) + "set the scale of noise layer `n` in the hires sky anim" + (set! (-> *sky-hires-texture-anim-array* array-data 7 data n start-color w) val) + ) +(defun set-layer-update-time! ((n int) (val float)) + "set the update time of noise layer `n` in the hires sky anim" + (set! (-> *sky-hires-texture-anim-array* array-data (1+ n) frame-mod) val) + (set! (-> *sky-hires-texture-anim-array* array-data (1+ n) data 0 end-time) val) + (set! (-> *sky-hires-texture-anim-array* array-data (1+ n) data 1 end-time) val) + ) + +(set-layer-scale! 0 0.49) +(set-layer-scale! 1 0.19) +(set-layer-scale! 2 0.145) +(set-layer-scale! 3 0.015) +(set-layer-scale! 4 0.01) +(set-layer-scale! 5 0.0075) +(set-layer-update-time! 0 (fsec 16)) +(set-layer-update-time! 1 (fsec 8)) +(set-layer-update-time! 2 (fsec 6)) +(set-layer-update-time! 3 (fsec 4)) +(set-layer-update-time! 4 (fsec 3)) +(set-layer-update-time! 5 (fsec 2)) + +) + ;; WARN: Return type mismatch float vs none. (defun set-fog-height! ((arg0 float)) (set! (-> *sky-texture-anim-array* array-data 8 extra z) arg0) + ;; og:preserve-this + (#when PC_PORT + (set! (-> (the (array texture-anim) *sky-hires-texture-anim-array*) 10 extra z) arg0)) (none) ) @@ -429,6 +1034,10 @@ (defun set-cloud-minmax! ((arg0 float) (arg1 float)) (set! (-> *sky-texture-anim-array* array-data 7 extra y) arg0) (set! (-> *sky-texture-anim-array* array-data 7 extra z) arg1) + ;; og:preserve-this + (#when PC_PORT + (set! (-> *sky-hires-texture-anim-array* array-data 9 extra y) arg0) + (set! (-> *sky-hires-texture-anim-array* array-data 9 extra z) arg1)) (none) ) diff --git a/goal_src/jak3/engine/gfx/texture/texture-anim.gc b/goal_src/jak3/engine/gfx/texture/texture-anim.gc index 4f98a2b7b7..e5a3f6cad8 100644 --- a/goal_src/jak3/engine/gfx/texture/texture-anim.gc +++ b/goal_src/jak3/engine/gfx/texture/texture-anim.gc @@ -361,6 +361,9 @@ ) (define-extern *sky-texture-anim-array* (texture-anim-array texture-anim)) +;; og:preserve-this +(#when PC_PORT + (define-extern *sky-hires-texture-anim-array* (texture-anim-array texture-anim))) (define-extern *darkjak-texture-anim-array* (texture-anim-array texture-anim)) (define-extern *darkjak-highres-texture-anim-array* (texture-anim-array texture-anim)) (define-extern *skull-gem-texture-anim-array* (texture-anim-array texture-anim)) @@ -430,11 +433,56 @@ ) ) +(defun make-sky-hires-input ((si sky-input)) + (set! (-> si fog-height) (-> (the (array texture-anim) *sky-hires-texture-anim-array*) 10 extra z)) + (set! (-> si cloud-min) (-> *sky-hires-texture-anim-array* array-data 9 extra y)) + (set! (-> si cloud-max) (-> *sky-hires-texture-anim-array* array-data 9 extra z)) + (set! (-> si cloud-dest) (the int (-> *sky-hires-texture-anim-array* array-data 8 tex dest 0))) + (dotimes (i (-> *sky-hires-texture-anim-array* array-data 7 num-layers)) + (set! (-> si scales i) (-> *sky-hires-texture-anim-array* array-data 7 data i start-color w)) + (set! (-> si max-times i) (-> *sky-hires-texture-anim-array* array-data (1+ i) frame-mod)) + ) + (dotimes (i 11) + (set! (-> si times i) + (-> *sky-hires-texture-anim-array* array-data i frame-time) + ) + ) + ) + (defmacro print-anim (&rest args) ;`(format 0 ,@args) 0 ) +(defun pc-clut-blender ((bucket bucket-id) (id texture-anim-pc) (anim-array texture-anim-array)) + (let* ((sz (-> anim-array length)) + (qwc (+ 1 (/ (+ 3 sz) 4)))) + (with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf)) + bucket + ) + (pc-texture-anim-flag start-anim-array dma-buf) + (pc-texture-anim-flag-id id dma-buf :qwc qwc) + (let ((morph (-> anim-array array-data 0 frame-time)) + (vec (the vector (-> dma-buf base))) + ) + (set! (-> vec x) morph) + ) + (&+! (-> dma-buf base) 16) + (dotimes (i sz) + (let ((tex (-> anim-array array-data i tex))) + (set! (-> (the (pointer uint32) (-> dma-buf base)) i) + (if tex (-> tex dest 0) + -1) + ) + ) + ) + (&+! (-> dma-buf base) (- (* 16 qwc) 16)) + (pc-texture-anim-flag finish-anim-array dma-buf) + ) + ) + (none) + ) + ;; WARN: Function update-texture-anim has a return type of none, but the expression builder found a return statement. (defun update-texture-anim ((bucket bucket-id) (anim-array texture-anim-array)) (let ((anim-idx 0)) @@ -470,36 +518,35 @@ (set! anim-idx 8) ;; fog ;; (return #f) ) - ((*darkjak-texture-anim-array*) + ((*sky-hires-texture-anim-array*) + (when (= bucket (bucket-id tex-lcom-sky-post)) + ;; skip. I believe this is only used to generate the envmap texture for the ocean. + ;; it generates the exact same thing, so if we want this on PC one day, we can just + ;; steal if from the beginning of the frame. + (return #f) + ) (with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf)) - bucket - ) + bucket + ) (pc-texture-anim-flag start-anim-array dma-buf) - (pc-texture-anim-flag darkjak dma-buf :qwc 1) - (let ((morph (-> anim-array array-data 0 frame-time)) - (vec (the vector (-> dma-buf base))) - ) - (set! (-> vec x) morph) - ) - (&+! (-> dma-buf base) 16) + (pc-texture-anim-flag clouds-hires dma-buf :qwc (/ (psize-of sky-input) 16)) + (make-sky-hires-input (the sky-input (-> dma-buf base))) + (&+! (-> dma-buf base) (psize-of sky-input)) (pc-texture-anim-flag finish-anim-array dma-buf) + (dotimes (i 10) ;; intentially skipping fog here!! + (pc-update-anim-frame-time (-> *sky-hires-texture-anim-array* array-data i)) + ) ) + ;; falling through on purpose + (set! anim-idx 10) ;; fog + ; (return #f) + ) + ((*darkjak-texture-anim-array*) + (pc-clut-blender bucket (texture-anim-pc darkjak) anim-array) (return #f) ) ((*darkjak-highres-texture-anim-array*) - (with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf)) - bucket - ) - (pc-texture-anim-flag start-anim-array dma-buf) - (pc-texture-anim-flag darkjak-highres dma-buf :qwc 1) - (let ((morph (-> anim-array array-data 0 frame-time)) - (vec (the vector (-> dma-buf base))) - ) - (set! (-> vec x) morph) - ) - (&+! (-> dma-buf base) 16) - (pc-texture-anim-flag finish-anim-array dma-buf) - ) + (pc-clut-blender bucket (texture-anim-pc darkjak-highres) anim-array) (return #f) ) ((*skull-gem-texture-anim-array*) diff --git a/goal_src/jak3/engine/gfx/texture/texture-finish.gc b/goal_src/jak3/engine/gfx/texture/texture-finish.gc index 474a6d12f8..f7f7faa342 100644 --- a/goal_src/jak3/engine/gfx/texture/texture-finish.gc +++ b/goal_src/jak3/engine/gfx/texture/texture-finish.gc @@ -18,6 +18,8 @@ ) (init! *sky-texture-anim-array*) +;; og:preserve-this +(init! *sky-hires-texture-anim-array*) (init! *darkjak-texture-anim-array*) (init! *skull-gem-texture-anim-array*) (init! *default-water-texture-anim-array*) diff --git a/goal_src/jak3/engine/level/level-h.gc b/goal_src/jak3/engine/level/level-h.gc index d7734a7ce8..5ad335925f 100644 --- a/goal_src/jak3/engine/level/level-h.gc +++ b/goal_src/jak3/engine/level/level-h.gc @@ -139,27 +139,27 @@ ;; +++bigmap-id (defenum bigmap-id :type uint32 - (bigmap-id-0 0) - (bigmap-id-1 1) + (city 0) + (comb 1) (desert 2) (factory 3) (forest 4) (mhcity 5) (mine 6) (nest 7) - (bigmap-id-8 8) - (no-map 9) - (precursor 10) - (bigmap-id-11 11) + (nest2 8) + (none 9) + (precursor1 10) + (precursor2 11) (rubble 12) - (sewer0 13) - (sewer1 14) - (sewer2 15) + (sewer-hum-kg 13) + (sewer-kg-met 14) + (sewer-met-hum 15) (stadium 16) - (temple 17) - (bigmap-id-18 18) - (bigmap-id-19 19) - (bigmap-id-20 20) + (temple1 17) + (temple2 18) + (temple3 19) + (temple4 20) (tower 21) (volcano 22) (wascity 23) diff --git a/goal_src/jak3/engine/level/level-info.gc b/goal_src/jak3/engine/level/level-info.gc index c0cb0641be..bc74fb1886 100644 --- a/goal_src/jak3/engine/level/level-info.gc +++ b/goal_src/jak3/engine/level/level-info.gc @@ -47,7 +47,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -81,7 +81,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -113,7 +113,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "title-start" :level 'title @@ -315,7 +315,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "vinroom-start" :level 'vinroom @@ -490,7 +490,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((7 . *ljkdxvin-texture-anim-array*)) :borrow #f @@ -523,7 +523,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((7 . *ljkdxvin-texture-anim-array*)) :borrow #f @@ -557,7 +557,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -590,7 +590,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 9.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((34 . ctywide-logout) (36 . ctywide-deactivate) @@ -634,7 +634,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -669,7 +669,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -704,7 +704,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -739,7 +739,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -774,7 +774,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -809,7 +809,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -843,7 +843,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -877,7 +877,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -910,7 +910,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -943,7 +943,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -976,7 +976,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1009,7 +1009,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1042,7 +1042,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1075,7 +1075,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1109,7 +1109,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -1143,7 +1143,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -1176,7 +1176,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1209,7 +1209,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1242,7 +1242,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1275,7 +1275,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1308,7 +1308,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1341,7 +1341,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1375,7 +1375,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -3355,7 +3355,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -3390,7 +3390,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((34 . lpattack-logout) (36 . rubblea-deactivate) (35 . rubblea-activate) (33 . lpattack-login)) :borrow #f @@ -4135,7 +4135,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4168,7 +4168,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4201,7 +4201,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((34 . lctypatk-logout) (33 . lctypatk-login)) :borrow #f @@ -4234,7 +4234,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -4267,7 +4267,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((34 . lctypalt-logout) (33 . lctypalt-login)) :borrow #f @@ -4300,7 +4300,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4333,7 +4333,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((23 . init-mood-mhcitya)) :borrow #f @@ -4366,7 +4366,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4399,7 +4399,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4432,7 +4432,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4465,7 +4465,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "onintent-start" :level 'onintent @@ -4541,7 +4541,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4575,7 +4575,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "hiphog-start" :level 'hiphog @@ -4670,7 +4670,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4704,7 +4704,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "gungame-start" :level 'gungame @@ -4821,7 +4821,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4855,7 +4855,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4889,7 +4889,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4923,7 +4923,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "freehq-start" :level 'freehq @@ -5058,7 +5058,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -5092,7 +5092,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -5126,7 +5126,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((3 . *darkjak-highres-texture-anim-array*)) :borrow #f @@ -5705,7 +5705,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "comba-start" :level 'comba @@ -5822,7 +5822,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "combb-start" :level 'combb @@ -5873,7 +5873,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "combc" :level 'combc @@ -5926,7 +5926,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "combd" :level 'combd @@ -5979,7 +5979,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "combe" :level 'combe @@ -6032,7 +6032,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((23 . init-mood-comb)) :borrow #f @@ -6065,7 +6065,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "combn-start" :level 'combn @@ -6138,7 +6138,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((23 . init-mood-combx)) :borrow #f @@ -6171,7 +6171,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . comba-deactivate) (35 . comba-activate) (33 . comba-login) (23 . init-mood-comb)) :borrow #f @@ -6204,7 +6204,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "railb-start" :level 'railb @@ -6257,7 +6257,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "railb2-start" :level 'railb2 @@ -6310,7 +6310,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "railc-start" :level 'railc @@ -6363,7 +6363,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "raild-start" :level 'raild @@ -6416,7 +6416,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "raile-start" :level 'raile @@ -6469,7 +6469,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((23 . init-mood-comb)) :borrow #f @@ -6502,7 +6502,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "railx-start" :level 'railx @@ -6557,7 +6557,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -6591,7 +6591,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -6694,7 +6694,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -6978,7 +6978,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "prebot-intro" :level 'mined @@ -7138,7 +7138,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "sewer-start" :level 'sewa @@ -7252,7 +7252,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer0) + :bigmap-id (bigmap-id sewer-hum-kg) :continues '((new 'static 'continue-point :name "sewb" :level 'sewb @@ -7346,7 +7346,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer0) + :bigmap-id (bigmap-id sewer-hum-kg) :continues '((new 'static 'continue-point :name "sewc-start" :level 'sewc @@ -7420,7 +7420,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer0) + :bigmap-id (bigmap-id sewer-hum-kg) :continues '((new 'static 'continue-point :name "sewd-start" :level 'sewd @@ -7494,7 +7494,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer0) + :bigmap-id (bigmap-id sewer-hum-kg) :continues '((new 'static 'continue-point :name "sewe" :level 'sewe @@ -7606,7 +7606,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer0) + :bigmap-id (bigmap-id sewer-hum-kg) :continues '((new 'static 'continue-point :name "sewf-start" :level 'sewf @@ -7680,7 +7680,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer1) + :bigmap-id (bigmap-id sewer-kg-met) :continues '((new 'static 'continue-point :name "sewg-start" :level 'sewg @@ -7754,7 +7754,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer1) + :bigmap-id (bigmap-id sewer-kg-met) :continues '((new 'static 'continue-point :name "sewh-start" :level 'sewh @@ -7828,7 +7828,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer1) + :bigmap-id (bigmap-id sewer-kg-met) :continues '((new 'static 'continue-point :name "sewi-start" :level 'sewi @@ -7882,7 +7882,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer1) + :bigmap-id (bigmap-id sewer-kg-met) :continues '((new 'static 'continue-point :name "sewj-start" :level 'sewj @@ -7956,7 +7956,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer1) + :bigmap-id (bigmap-id sewer-kg-met) :continues '((new 'static 'continue-point :name "sewk" :level 'sewk @@ -8030,7 +8030,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer2) + :bigmap-id (bigmap-id sewer-met-hum) :continues '((new 'static 'continue-point :name "sewl" :level 'sewl @@ -8102,7 +8102,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer2) + :bigmap-id (bigmap-id sewer-met-hum) :continues '((new 'static 'continue-point :name "sewm" :level 'sewm @@ -8194,7 +8194,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer2) + :bigmap-id (bigmap-id sewer-met-hum) :continues '((new 'static 'continue-point :name "sewn" :level 'sewn @@ -8266,7 +8266,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer2) + :bigmap-id (bigmap-id sewer-met-hum) :continues '((new 'static 'continue-point :name "sewo" :level 'sewo @@ -8614,7 +8614,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((3 . *lforplnt-pris-texture-anim-array*)) :borrow #f @@ -8648,7 +8648,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -8682,7 +8682,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((34 . foresta-logout) (35 . foresta-activate) (33 . foresta-login)) :borrow #f @@ -8767,7 +8767,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "pre-intro-start" :level 'wasintro @@ -8902,7 +8902,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info @@ -8940,7 +8940,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -8974,7 +8974,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -9006,7 +9006,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "wasall-start" :level 'wasall @@ -9083,7 +9083,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . waswide-deactivate) (35 . waswide-activate) (33 . waswide-login)) :borrow (new 'static 'level-borrow-info @@ -9414,7 +9414,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -9841,7 +9841,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -9875,7 +9875,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info @@ -9913,7 +9913,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -9947,7 +9947,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -9981,7 +9981,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10015,7 +10015,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . race-level-deactivate) (35 . race-level-activate)) :borrow #f @@ -10366,7 +10366,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info @@ -10404,7 +10404,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10437,7 +10437,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10470,7 +10470,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10503,7 +10503,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10942,7 +10942,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10975,7 +10975,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11008,7 +11008,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11041,7 +11041,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11074,7 +11074,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11107,7 +11107,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11140,7 +11140,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11174,7 +11174,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11207,7 +11207,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11240,7 +11240,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11273,7 +11273,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11306,7 +11306,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11339,7 +11339,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11372,7 +11372,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11405,7 +11405,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11438,7 +11438,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11471,7 +11471,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11504,7 +11504,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11537,7 +11537,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11570,7 +11570,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11603,7 +11603,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11636,7 +11636,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11669,7 +11669,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11702,7 +11702,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11735,7 +11735,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11768,7 +11768,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11801,7 +11801,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11834,7 +11834,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11867,7 +11867,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11900,7 +11900,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11933,7 +11933,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11966,7 +11966,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11999,7 +11999,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12032,7 +12032,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((7 . *ltnfxhip-texture-anim-array*)) :borrow #f @@ -12065,7 +12065,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12098,7 +12098,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12131,7 +12131,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12164,7 +12164,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12197,7 +12197,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12230,7 +12230,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12263,7 +12263,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((6 . *lgunnorm-water-texture-anim-array*)) :borrow #f @@ -12296,7 +12296,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12330,7 +12330,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12519,7 +12519,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12552,7 +12552,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -14058,7 +14058,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -14145,7 +14145,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -14179,7 +14179,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -14915,7 +14915,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15055,7 +15055,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -15089,7 +15089,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15123,7 +15123,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15157,7 +15157,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15191,7 +15191,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15225,7 +15225,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . desert-race-level-deactivate) (35 . desert-race-level-activate)) :borrow #f @@ -15259,7 +15259,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "desrally-race-start" :level 'desrally @@ -15333,7 +15333,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "desert-hover-movie" :level 'deshover @@ -15387,7 +15387,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15421,7 +15421,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15455,7 +15455,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "desert-rescue-movie" :level 'desresc @@ -15552,7 +15552,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -15586,7 +15586,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15620,7 +15620,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "desert-ashelin-pre-start" :level 'desoasis @@ -15734,7 +15734,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -15768,7 +15768,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15802,7 +15802,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15836,7 +15836,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15870,7 +15870,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -15904,7 +15904,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -15938,7 +15938,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -15972,7 +15972,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16006,7 +16006,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16040,7 +16040,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16074,7 +16074,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16108,7 +16108,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16142,7 +16142,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16176,7 +16176,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16210,7 +16210,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16244,7 +16244,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16278,7 +16278,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16312,7 +16312,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16346,7 +16346,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16380,7 +16380,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16414,7 +16414,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16448,7 +16448,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16482,7 +16482,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16516,7 +16516,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16800,7 +16800,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16834,7 +16834,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16868,7 +16868,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16904,7 +16904,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id temple) + :bigmap-id (bigmap-id temple1) :continues '((new 'static 'continue-point :name "templex-start" :level 'templex @@ -17136,7 +17136,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0 primary0) - :bigmap-id (bigmap-id temple) + :bigmap-id (bigmap-id temple1) :continues '((new 'static 'continue-point :name "templea-start" :level 'templea @@ -17300,7 +17300,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id temple) + :bigmap-id (bigmap-id temple1) :continues '((new 'static 'continue-point :name "templeb-start" :level 'templeb @@ -17707,7 +17707,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id temple) + :bigmap-id (bigmap-id temple1) :continues '((new 'static 'continue-point :name "templec-start" :level 'templec @@ -17801,7 +17801,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id temple) + :bigmap-id (bigmap-id temple1) :continues '((new 'static 'continue-point :name "templed-start" :level 'templed @@ -17975,7 +17975,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id temple) + :bigmap-id (bigmap-id temple1) :continues '() :callback-list '((23 . init-mood-templea)) :borrow #f @@ -18087,7 +18087,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((12 . *hfrag-texture-anim-array*)) :borrow #f @@ -18656,7 +18656,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0 primary0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . factorya-deactivate) (35 . factorya-activate)) :borrow #f @@ -18689,7 +18689,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lfaccar-deactivate) (35 . lfaccar-activate)) :borrow #f @@ -18723,7 +18723,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "lfacrm1-start" :level 'lfacrm1 @@ -18776,7 +18776,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "factoryc-start-lfacrm2" :level 'lfacrm2 @@ -18827,7 +18827,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -18860,7 +18860,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -18894,7 +18894,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "factoryb-start" :level 'factoryb @@ -19325,7 +19325,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "factoryd-pre" :level 'factoryd @@ -19413,7 +19413,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -19446,7 +19446,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "warinta" :level 'warinta @@ -19496,7 +19496,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0 primary0) - :bigmap-id (bigmap-id precursor) + :bigmap-id (bigmap-id precursor1) :continues '((new 'static 'continue-point :name "precura-mech" :level 'precura @@ -19610,7 +19610,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id precursor) + :bigmap-id (bigmap-id precursor1) :continues '() :callback-list '((23 . init-mood-precurb)) :borrow #f @@ -19643,7 +19643,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id precursor) + :bigmap-id (bigmap-id precursor1) :continues '((new 'static 'continue-point :name "precurc-end" :level 'precurc @@ -19734,7 +19734,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -19767,7 +19767,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "precurd-start" :level 'precurd @@ -19851,7 +19851,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "bikearena-start" :level 'bikearena @@ -19902,7 +19902,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "halfpipe" :level 'halfpipe @@ -19952,7 +19952,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "sndtest" :level 'sndtest @@ -20002,7 +20002,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -20035,7 +20035,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -20068,7 +20068,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -20101,7 +20101,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -20134,7 +20134,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "chartest-1" :level 'chartest @@ -20184,7 +20184,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -20217,7 +20217,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "testisle-start" :level 'testisle @@ -20268,7 +20268,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "gregtest-start" :level 'gregtest @@ -20334,7 +20334,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "jump test" :level '4amy @@ -20683,7 +20683,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "test-zone-start" :level 'test-zone diff --git a/goal_src/jak3/engine/level/level.gc b/goal_src/jak3/engine/level/level.gc index 066bc40bb4..5d2b3fb88a 100644 --- a/goal_src/jak3/engine/level/level.gc +++ b/goal_src/jak3/engine/level/level.gc @@ -3832,12 +3832,13 @@ ) ) ) - (let ((v1-194 (- #x2000000 (the-as int (-> global current))))) - (if (and (not *debug-segment*) (or (< v1-194 #x4000) (= *cheat-mode* 'debug))) + ;; og:preserve-this this was hardcoded to the top of EE memory (#x2000000) + (let ((v1-194 (&- (-> global top-base) (-> global current)))) + (if (and (not *debug-segment*) (or (< v1-194 (* 16 1024)) (= *cheat-mode* 'debug))) (format *stdcon* "~3Lglobal heap fatally low at ~D.~DK free~%~0L" - (sar v1-194 10) + (/ v1-194 (* 1024 1024)) (/ (logand v1-194 1023) 103) ) ) diff --git a/goal_src/jak3/engine/load/file-io.gc b/goal_src/jak3/engine/load/file-io.gc index fd658610fd..1371dfa2ab 100644 --- a/goal_src/jak3/engine/load/file-io.gc +++ b/goal_src/jak3/engine/load/file-io.gc @@ -127,7 +127,9 @@ NOTE: this is a special type in three ways: (format *file-temp-string* "texture-page~D/dir-tpages" TPAGE_FILE_VERSION) ) ((= kind (file-kind tpage)) - (format *file-temp-string* "texture-page~D/tpage-~S" TPAGE_FILE_VERSION name) + ;; og:preserve-this removed texture-page8 prefix + ; (format *file-temp-string* "texture-page~D/tpage-~S" TPAGE_FILE_VERSION name) + (format *file-temp-string* "tpage-~S" name) ) ((= kind (file-kind level-bt)) (format *file-temp-string* "level~D/~S-bt" LEVEL_BT_FILE_VERSION name) diff --git a/goal_src/jak3/engine/load/loader.gc b/goal_src/jak3/engine/load/loader.gc index 99d645d5e6..b9cdb672c7 100644 --- a/goal_src/jak3/engine/load/loader.gc +++ b/goal_src/jak3/engine/load/loader.gc @@ -2212,6 +2212,10 @@ ) ) +;; og:preserve-this added for debugging +(#when PC_PORT +(define *gui-kick-str* #f)) + (defmethod update-connection ((this gui-control) (arg0 gui-connection) (arg1 process) (arg2 symbol)) (local-vars (v1-75 symbol)) (when (and (>= (the-as uint (-> arg0 channel)) (the-as uint 16)) @@ -2253,7 +2257,9 @@ ((= s3-0 (gui-status ready)) (case (shr (the-as int (-> arg0 channel)) 4) ((1 2) - (if (not (paused?)) + ;; og:preserve-this added condition + (if (#if PC_PORT (or *gui-kick-str* (not (paused?))) + (not (paused?))) (str-play-async (-> arg0 name) (-> arg0 id) @@ -2723,6 +2729,8 @@ (set! (-> gp-0 cmd 35) '((64 . wait) (21 . wait) (22 . wait) (23 . wait) (25 . wait) (19 . wait) (28 . wait) (35 . wait)) ) + ;; og:preserve-this added + (set! (-> gp-0 cmd (gui-channel subtitle-pc)) '(((the binteger (gui-channel blackout)) . wait))) (set! (-> gp-0 group 18) (sound-group)) (set! (-> gp-0 group 27) (sound-group)) (set! (-> gp-0 group 31) (sound-group)) diff --git a/goal_src/jak3/engine/physics/ragdoll-h.gc b/goal_src/jak3/engine/physics/ragdoll-h.gc index c7dee4d774..d0a89728bb 100644 --- a/goal_src/jak3/engine/physics/ragdoll-h.gc +++ b/goal_src/jak3/engine/physics/ragdoll-h.gc @@ -218,7 +218,7 @@ (disable-for-duration (_type_ time-frame) none) (ragdoll-proc-method-17 (_type_ ragdoll-edit-info) none) (ragdoll-proc-method-18 (_type_ ragdoll-edit-info) none) - (ragdoll-proc-method-19 (_type_) none) + (ragdoll-proc-method-19 (_type_) symbol) ) ) diff --git a/goal_src/jak3/engine/physics/ragdoll.gc b/goal_src/jak3/engine/physics/ragdoll.gc index 5c022c64c8..85efaffdb9 100644 --- a/goal_src/jak3/engine/physics/ragdoll.gc +++ b/goal_src/jak3/engine/physics/ragdoll.gc @@ -1567,13 +1567,11 @@ (none) ) -;; WARN: Return type mismatch symbol vs none. (defmethod ragdoll-proc-method-19 ((this ragdoll-proc)) (if (nonzero? (-> this ragdoll)) (logtest? (-> this ragdoll ragdoll-flags) (ragdoll-flag rf2)) #t ) - (none) ) (defstate idle (ragdoll-proc) diff --git a/goal_src/jak3/engine/physics/rigid-body.gc b/goal_src/jak3/engine/physics/rigid-body.gc index d23a6745c4..a184d0ad8f 100644 --- a/goal_src/jak3/engine/physics/rigid-body.gc +++ b/goal_src/jak3/engine/physics/rigid-body.gc @@ -5,6 +5,12 @@ ;; name in dgo: rigid-body ;; dgos: GAME +(deftype rigid-body-stack (structure) + ((vec vector :inline) + (mat matrix :inline) + ) + ) + ;; DECOMP BEGINS (deftype rigid-body-work (structure) @@ -92,10 +98,10 @@ ) (defmethod rigid-body-control-method-28 ((this rigid-body-control) (arg0 vector) (arg1 quaternion)) - (let ((s3-0 (new 'stack-no-clear 'rigid-body-impact))) - (quaternion->matrix (the-as matrix (-> s3-0 normal)) arg1) - (vector-rotate*! (-> s3-0 point) (-> this info cm-offset-joint) (the-as matrix (-> s3-0 normal))) - (vector+! (-> this position) arg0 (-> s3-0 point)) + (let ((s3-0 (new 'stack-no-clear 'rigid-body-stack))) + (quaternion->matrix (-> s3-0 mat) arg1) + (vector-rotate*! (-> s3-0 vec) (-> this info cm-offset-joint) (-> s3-0 mat)) + (vector+! (-> this position) arg0 (-> s3-0 vec)) ) (quaternion-copy! (the-as quaternion (-> this rot)) arg1) (quaternion-normalize! (the-as quaternion (-> this rot))) diff --git a/goal_src/jak3/engine/process-drawable/process-drawable.gc b/goal_src/jak3/engine/process-drawable/process-drawable.gc index af9c9cdc5d..80a4c2c3cb 100644 --- a/goal_src/jak3/engine/process-drawable/process-drawable.gc +++ b/goal_src/jak3/engine/process-drawable/process-drawable.gc @@ -426,60 +426,83 @@ 0 ) -(defmethod draw-control-method-14 ((this draw-control) (arg0 cspace-array) (arg1 joint-control)) - (let ((s5-0 (if (logtest? (-> arg1 status) (joint-control-status force-math)) - (+ (-> arg0 length) -3) - (-> this mgeo length) - ) - ) +(defmethod draw-control-method-14 ((this draw-control) (cspaces cspace-array) (jc joint-control)) + "This function determines the world-space bone transforms. + First, joint transforms are computed with the callback generate-frame-function. + Then, the cspace functions are called for each bone." + + ;; pick the number of "transformq joints" to compute. Most joints are transformq, except for the first three: + ;; cspace 0 is a special "root" with no joint. Its bone is typically set from the root. + ;; cspace 1 is align. This doesn't really do anything by default, but is used by the aligner. + ;; cspace 2 is prejoint. This is an animated matrix placed before any joints. + ;; so, if we force math on all bones, subtract off these three weird cspaces that don't have animated transformq's. + ;; otherwise, use the joint count from the currently active mgeo + (let ((num-tq-joints (if (logtest? (-> jc status) (joint-control-status force-math)) + (+ (-> cspaces length) -3) + (-> this mgeo length) + ) + ) ) - (let ((s3-0 (+ s5-0 2))) + + ;; tq joints, plus 2 for align and prejoint: + (let ((num-joints (+ num-tq-joints 2))) ;; og:preserve-this - ((-> arg1 generate-frame-function) (the-as joint-anim-frame (+ 2400 (scratchpad-object int))) s3-0 arg1) - (if (-> arg1 prebind-function) - ((-> arg1 prebind-function) (the-as joint-anim-frame (+ 2400 (scratchpad-object int))) s3-0 arg1) + + ;; generate joint transforms from animation. + ;; this dumps joint matrix/tq's to the scratchpad + ((-> jc generate-frame-function) (the-as joint-anim-frame (+ 2400 (scratchpad-object int))) num-joints jc) + + ;; user callback to modify animated joints + (if (-> jc prebind-function) + ((-> jc prebind-function) (the-as joint-anim-frame (+ 2400 (scratchpad-object int))) num-joints jc) ) ) - (dotimes (s3-1 1) - (let* ((v1-11 (-> arg0 data s3-1)) - (t9-2 (the-as function (-> v1-11 param0))) + + ;; First cspace: the root. Run the bone callback, which typically would copy the (-> pd root)'s transform to the bone. + ;; Future cspaces will access this. + (dotimes (i 1) + (let* ((root-cspace (-> cspaces data i)) + (bone-func (the-as (function cspace object object none) (-> root-cspace param0))) ) - (if (the-as (function cspace transformq none) t9-2) - ((the-as (function object object object none) t9-2) v1-11 (-> v1-11 param1) (-> v1-11 param2)) - ) + (when bone-func + (bone-func root-cspace (-> root-cspace param1) (-> root-cspace param2)) + ) ) ) - (dotimes (s3-2 2) - (let* ((a0-8 (-> arg0 data (+ s3-2 1))) - ;; og:preserve-this - (a1-5 (+ (* s3-2 64) 2400 (scratchpad-object int))) - (t9-3 (-> a0-8 param0)) + + ;; Cspaces for align and prejoint are computed with a matrix joint + (dotimes (matrix-num 2) + (let* ((mat-cspace (-> cspaces data (+ matrix-num 1))) + (mat (-> (scratchpad-object joint-work) mtx-acc matrix-num)) + (bone-func (-> mat-cspace param0)) ) - (if t9-3 - (t9-3 a0-8 (the-as transformq a1-5)) + (if bone-func + (bone-func mat-cspace (the-as transformq mat)) ) ) ) - (let ((s3-3 3)) + + ;; cspaces for tq joints. There's an option to disable custom callbacks and force all joints + ;; to use the standard cspace<-parented-transformq-joint, which does the right thing for playing + ;; back plain animations, no joint mods or anything fancy. + (let ((cspace-idx 3)) (cond - ((logtest? (-> arg1 status) (joint-control-status no-joint-callbacks)) - (dotimes (s4-1 s5-0) + ((logtest? (-> jc status) (joint-control-status no-joint-callbacks)) + (dotimes (i num-tq-joints) (cspace<-parented-transformq-joint! - (-> arg0 data (+ s4-1 s3-3)) - ;; og:preserve-this - (the-as transformq (+ (* 48 s4-1) 2528 (scratchpad-object int))) + (-> cspaces data (+ i cspace-idx)) + (-> (scratchpad-object joint-work) tq-acc i) ) ) ) (else - (dotimes (s4-2 s5-0) - (let ((a0-10 (-> arg0 data (+ s4-2 s3-3))) - ;; og:preserve-this - (a1-9 (+ (* 48 s4-2) 2528 (scratchpad-object int))) + (dotimes (i num-tq-joints) + (let ((csp (-> cspaces data (+ i cspace-idx))) + (tq (-> (scratchpad-object joint-work) tq-acc i)) ) - (if (-> a0-10 param0) - ((-> a0-10 param0) a0-10 (the-as transformq a1-9)) - (cspace<-parented-transformq-joint! a0-10 (the-as transformq a1-9)) + (if (-> csp param0) + ((-> csp param0) csp tq) + (cspace<-parented-transformq-joint! csp tq) ) ) ) diff --git a/goal_src/jak3/engine/process-drawable/process-taskable.gc b/goal_src/jak3/engine/process-drawable/process-taskable.gc index 7e2ffee9a4..e004ee2afa 100644 --- a/goal_src/jak3/engine/process-drawable/process-taskable.gc +++ b/goal_src/jak3/engine/process-drawable/process-taskable.gc @@ -377,11 +377,7 @@ (if (-> self skel effect) (do-effect (-> self skel effect) "death-default" 0.0 -1) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (if (logtest? (-> self flags) (process-taskable-flags ptf5)) (restart-mission) ) @@ -395,11 +391,7 @@ :enter (-> (method-of-type process-taskable active) enter) :exit (-> (method-of-type process-taskable active) exit) :code (behavior ((arg0 game-task-event)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (go-virtual hide) ) :post (-> (method-of-type process-taskable idle) post) diff --git a/goal_src/jak3/engine/ps2/pad.gc b/goal_src/jak3/engine/ps2/pad.gc index 4444a2f886..36dd12a6e1 100644 --- a/goal_src/jak3/engine/ps2/pad.gc +++ b/goal_src/jak3/engine/ps2/pad.gc @@ -49,6 +49,24 @@ ) ;; ---pad-buttons +;; +++abutton-idx +(defenum abutton-idx + :type uint8 + (right 0) + (left 1) + (up 2) + (down 3) + (triangle 4) + (circle 5) + (x 6) + (square 7) + (l1 8) + (r1 9) + (l2 10) + (r2 11) + ) +;; ---abutton-idx + ;; TODO ;; (#when PC_PORT ;; ;; redefined from C kernel @@ -459,73 +477,73 @@ (set! (-> history button0-rel 1) (-> pad button0-rel 0)) (when (= (-> pad status) 115) - (set! (-> pad abutton 0) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons right)) + (set! (-> pad abutton (abutton-idx right)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons right)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 1) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons left)) + (set! (-> pad abutton (abutton-idx left)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons left)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 2) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons up)) + (set! (-> pad abutton (abutton-idx up)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons up)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 3) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons down)) + (set! (-> pad abutton (abutton-idx down)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons down)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 6) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons x)) + (set! (-> pad abutton (abutton-idx x)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons x)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 5) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons circle)) + (set! (-> pad abutton (abutton-idx circle)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons circle)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 4) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons triangle)) + (set! (-> pad abutton (abutton-idx triangle)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons triangle)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 7) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons square)) + (set! (-> pad abutton (abutton-idx square)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons square)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 8) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons l1)) + (set! (-> pad abutton (abutton-idx l1)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons l1)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 10) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons l2)) + (set! (-> pad abutton (abutton-idx l2)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons l2)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 9) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons r1)) + (set! (-> pad abutton (abutton-idx r1)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons r1)) ;; og:preserve-this abutton indexing 255 0 ) ) ) - (set! (-> pad abutton 11) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons r2)) + (set! (-> pad abutton (abutton-idx r2)) (the-as uint (if (logtest? (-> pad button0-abs 0) (pad-buttons r2)) ;; og:preserve-this abutton indexing 255 0 ) diff --git a/goal_src/jak3/engine/scene/scene.gc b/goal_src/jak3/engine/scene/scene.gc index b61d1ec1cf..76ea9453e7 100644 --- a/goal_src/jak3/engine/scene/scene.gc +++ b/goal_src/jak3/engine/scene/scene.gc @@ -817,6 +817,10 @@ ) (let ((v1-9 (-> self skel root-channel 0 frame-group))) (when v1-9 + ;; og:preserve-this send a movie-no-subtitle message so the pc subtitle system at least knows there's a movie playing + (#when PC_PORT + (if (= (-> self type) scene-player) + (send-event (ppointer->process *subtitle3*) 'movie-no-subtitle (-> (the scene-player self) anim name) #f (ja-aframe-num 0)))) (let ((gp-0 (res-lump-struct (-> v1-9 extra) 'subtitle-range (array subtitle-range)))) (when gp-0 (let ((f30-0 (ja-aframe-num 0)) @@ -865,7 +869,14 @@ (+! (-> s2-0 origin y) 1.0) (set! (-> s2-0 color) (font-color default)) (set! (-> s2-0 flags) (font-flags shadow kerning middle middle-vert large)) - (print-game-text (the-as string s3-0) s2-0 #f 44 (bucket-id hud-draw-pris2)) + ;; og:preserve-this subtitle3 + (#if PC_PORT + (if (or (!= (-> self type) scene-player) + (not (send-event (ppointer->process *subtitle3*) 'movie (-> (the scene-player self) anim name) s3-0 f30-0))) + (print-game-text (the-as string s3-0) s2-0 #f 44 (bucket-id hud-draw-pris2))) + + (print-game-text (the-as string s3-0) s2-0 #f 44 (bucket-id hud-draw-pris2))) + ; (print-game-text (the-as string s3-0) s2-0 #f 44 (bucket-id hud-draw-pris2)) (gui-control-method-12 *gui-control* self @@ -1201,11 +1212,7 @@ #x33001 #t ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.05)) - (suspend) - ) - ) + (suspend-for (seconds 0.05)) (set! (-> *setting-control* user-current bg-a) 0.0) (remove-setting! 'movie) (remove-setting! 'movie-name) @@ -1538,15 +1545,13 @@ (the-as (function process-drawable symbol) (if (logtest? (-> self scene scene-flags) (scene-flags scf1)) - (lambda :behavior scene-player - () - (when (cpad-pressed? 0 triangle) - (set! (-> self aborted?) #t) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons triangle)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons triangle)) - #t - ) - ) + (lambda :behavior scene-player () (when (cpad-pressed? 0 triangle) + (set! (-> self aborted?) #t) + (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons triangle)) + (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons triangle)) + #t + ) + ) false-func ) ) diff --git a/goal_src/jak3/engine/sound/gsound-h.gc b/goal_src/jak3/engine/sound/gsound-h.gc index f346d2583f..3577143843 100644 --- a/goal_src/jak3/engine/sound/gsound-h.gc +++ b/goal_src/jak3/engine/sound/gsound-h.gc @@ -141,12 +141,32 @@ ) ) +;; og:modbase set to #t to enable sound-replacements. disabled by default to avoid extra PC function calls +;; e.g. replace "skill-pickup" with custom_assets/jak3/audio/sound_replacements/skill-pickup.mp3 +(define *enable-sound-replacements?* #f) +;; og:modbase temp-string to be used by sound-play replacements only +(define *sound-play-temp-string* (new 'global 'string 2048 (the string #f))) +;; same as string-format but will only use the specified temp-string provided when called +(defmacro temp-string-format (temp-str &rest args) + `(begin + (format (clear ,temp-str) ,@args) + ,temp-str)) + ;; TODO change macro back once sound-group is figured out for jak 3 -(defmacro sound-play (name &key (id (new-sound-id)) - &key (vol 100.0) &key (pitch 0) &key (bend 0) - &key (group sfx) - &key (position #t)) - `(sound-play-by-name (static-sound-name ,name) ,id (the int (* (/ 1024.0 100.0) ,vol)) (the int (* 1524.0 ,pitch)) ,bend (sound-group) ,position)) +;; og:modbase try to play replacement sound, nonzero results means it wasnt found, so fall back to playing original sound +;; force-vanilla? flag lets you force vanilla sound for specific caller +(defmacro sound-play (name &key (id (new-sound-id)) &key (vol 100.0) &key (pitch 0) &key (bend 0) &key (group sfx) &key (position #t) &key (force-vanilla? #f)) + `(let ((sound-played? (and *enable-sound-replacements?* (not ,force-vanilla?) + (play-sound-file (temp-string-format *sound-play-temp-string* "sound_replacements/~S.mp3" ,name) 50)))) + ;; the below line would use vanilla volume instead, if you're sure your custom sounds won't be too loud + ;; (the-as sound-id (play-sound-file filepath (the int (* (/ 1024.0 100.0) ,vol)))) + (cond + (sound-played? + ;; Custom sound was found + (the-as sound-id sound-played?)) + (else + ;; Custom sound not found, play the original instead + (sound-play-by-name (static-sound-name ,name) ,id (the int (* (/ 1024.0 100.0) ,vol)) (the int (* 1524.0 ,pitch)) ,bend (sound-group ,group) ,position))))) (defmacro sound-vol (vol) "convert to sound volume units" diff --git a/goal_src/jak3/engine/sound/gsound.gc b/goal_src/jak3/engine/sound/gsound.gc index 3ad7bcfae2..bc6e1c5506 100644 --- a/goal_src/jak3/engine/sound/gsound.gc +++ b/goal_src/jak3/engine/sound/gsound.gc @@ -1291,11 +1291,7 @@ (set! (-> a1-3 0) 'empty0) (want-sound-banks *load-state* a1-3) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (let ((a1-4 (new 'stack-no-clear 'array 'symbol 4))) (set! (-> a1-4 2) (-> gp-0 4)) (set! (-> a1-4 1) (-> gp-0 2)) diff --git a/goal_src/jak3/engine/target/board/board-states.gc b/goal_src/jak3/engine/target/board/board-states.gc index da0f29f99f..5bb52ebe41 100644 --- a/goal_src/jak3/engine/target/board/board-states.gc +++ b/goal_src/jak3/engine/target/board/board-states.gc @@ -1072,7 +1072,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (mod-var-jump #t #f (cpad-hold? (-> self control cpad number) x) (-> self control transv)) @@ -1658,7 +1658,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (mod-var-jump #t #f (cpad-hold? (-> self control cpad number) x) (-> self control transv)) @@ -1810,7 +1810,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (mod-var-jump #t #f (cpad-hold? (-> self control cpad number) x) (-> self control transv)) @@ -2046,7 +2046,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (mod-var-jump #t #f (cpad-hold? (-> self control cpad number) x) (-> self control transv)) @@ -2173,7 +2173,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (mod-var-jump #t #f (cpad-hold? (-> self control cpad number) x) (-> self control transv)) @@ -3373,11 +3373,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s3-2 (current-time))) - (until (time-elapsed? s3-2 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (move-to-point! (-> self control) s4-1) ) (set! (-> self control camera-pos quad) (-> self control trans quad)) diff --git a/goal_src/jak3/engine/target/flut/flut-racer.gc b/goal_src/jak3/engine/target/flut/flut-racer.gc index 0fd807d148..ffec7faed9 100644 --- a/goal_src/jak3/engine/target/flut/flut-racer.gc +++ b/goal_src/jak3/engine/target/flut/flut-racer.gc @@ -512,8 +512,7 @@ (set! (-> s5-0 danger-level) 0.5) (set! (-> s5-0 notify-radius) 491520.0) (set! (-> s5-0 decay-rate) 0.0) - ;; og:preserve-this not-yet-implemented - ; (add-danger *traffic-engine* s5-0) + (add-danger *traffic-engine* s5-0) ) (let ((s5-1 (new 'stack-no-clear 'vector))) (vector-normalize! diff --git a/goal_src/jak3/engine/target/flut/flut.gc b/goal_src/jak3/engine/target/flut/flut.gc index ad755f3162..979e7615ec 100644 --- a/goal_src/jak3/engine/target/flut/flut.gc +++ b/goal_src/jak3/engine/target/flut/flut.gc @@ -352,12 +352,7 @@ (ja-channel-set! 0) (ja-post) (when (not (and (-> self entity) (= (-> self entity extra process) self))) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.1)) - (spawn-part-and-sound! self) - (suspend) - ) - ) + (suspend-for (seconds 0.1) (spawn-part-and-sound! self)) (deactivate self) ) (while (zero? (ja-group-size)) @@ -374,12 +369,7 @@ (spawn-part-and-sound! self) (suspend) ) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 1)) - (spawn-part-and-sound! self) - (suspend) - ) - ) + (suspend-for (seconds 1) (spawn-part-and-sound! self)) (go arg0) ) ) diff --git a/goal_src/jak3/engine/target/flut/target-flut.gc b/goal_src/jak3/engine/target/flut/target-flut.gc index 8055f292b1..4bff0c3618 100644 --- a/goal_src/jak3/engine/target/flut/target-flut.gc +++ b/goal_src/jak3/engine/target/flut/target-flut.gc @@ -1929,7 +1929,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) ((-> target-flut-falling trans)) @@ -2859,11 +2859,7 @@ (let ((s3-2 (new-stack-vector0))) (set! (-> s3-2 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s2-0 (current-time))) - (until (time-elapsed? s2-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (move-to-point! (-> self control) s3-2) ) (set! (-> self control camera-pos quad) (-> self control trans quad)) @@ -3046,33 +3042,31 @@ ) ) ) - (let ((s5-3 (current-time))) - (until (time-elapsed? s5-3 (seconds 1)) - (target-flut-falling-anim-trans) - (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) - (let ((v1-39 (new-stack-vector0)) - (f0-6 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) - ) - 0.0 - (vector-! - v1-39 - (-> self control transv) - (vector-float*! v1-39 (-> self control dynam gravity-normal) (the-as float f0-6)) + (suspend-for + (seconds 1) + (target-flut-falling-anim-trans) + (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) + (let ((v1-39 (new-stack-vector0)) + (f0-6 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) ) - (let* ((f1-7 (vector-length v1-39)) - (f2-2 f1-7) - ) - (if (< (the-as float (-> self control unknown-word04)) (the-as float f0-6)) - (set! f0-6 (-> self control unknown-word04)) - ) - (vector+! - (-> self control transv) - (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f0-6)) - (vector-float*! v1-39 v1-39 (/ f1-7 f2-2)) + 0.0 + (vector-! + v1-39 + (-> self control transv) + (vector-float*! v1-39 (-> self control dynam gravity-normal) (the-as float f0-6)) + ) + (let* ((f1-7 (vector-length v1-39)) + (f2-2 f1-7) + ) + (if (< (the-as float (-> self control unknown-word04)) (the-as float f0-6)) + (set! f0-6 (-> self control unknown-word04)) ) + (vector+! + (-> self control transv) + (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f0-6)) + (vector-float*! v1-39 v1-39 (/ f1-7 f2-2)) ) ) - (suspend) ) ) (remove-setting! 'mode-name) @@ -3108,11 +3102,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-8 (current-time))) - (until (time-elapsed? s5-8 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) (('lava 'melt 'fry 'slime) (sound-play "death-melt") @@ -3134,11 +3124,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-12 (current-time))) - (until (time-elapsed? s5-12 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) ) ) diff --git a/goal_src/jak3/engine/target/gun/gun-blue-shot.gc b/goal_src/jak3/engine/target/gun/gun-blue-shot.gc index d366c28f3b..1d13854152 100644 --- a/goal_src/jak3/engine/target/gun/gun-blue-shot.gc +++ b/goal_src/jak3/engine/target/gun/gun-blue-shot.gc @@ -2668,11 +2668,7 @@ (defstate dissipate (gun-blue-shot-3) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (go-virtual die) ) ) @@ -2680,11 +2676,7 @@ (defstate impact (gun-blue-shot-3) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (go-virtual die) ) ) diff --git a/goal_src/jak3/engine/target/gun/gun-dark-shot.gc b/goal_src/jak3/engine/target/gun/gun-dark-shot.gc index d203d33968..7d9f00b95c 100644 --- a/goal_src/jak3/engine/target/gun/gun-dark-shot.gc +++ b/goal_src/jak3/engine/target/gun/gun-dark-shot.gc @@ -847,7 +847,7 @@ (f0-4 (evaluate (-> this blur-curve) f0-3 (loop-behavior use-default))) (f0-5 (- 1.0 f0-4)) ) - (blit-displays-work-method-17 + (setup-zoom-blur-2d *blit-displays-work* (-> this root trans) (the-as int (-> this num-blur-segments)) @@ -1050,7 +1050,7 @@ :exit (behavior () (when (= (process->handle self) (-> *last-active-nuke* last-active-nuke)) (disable *screen-filter*) - (blit-displays-work-method-17 *blit-displays-work* (-> self root trans) 0 1.0 #f) + (setup-zoom-blur-2d *blit-displays-work* (-> self root trans) 0 1.0 #f) ) ) :trans (behavior () @@ -1225,7 +1225,7 @@ :exit (behavior () (when (= (process->handle self) (-> *last-active-nuke* last-active-nuke)) (disable *screen-filter*) - (blit-displays-work-method-17 *blit-displays-work* (-> self root trans) 0 1.0 #f) + (setup-zoom-blur-2d *blit-displays-work* (-> self root trans) 0 1.0 #f) ) ) :trans (behavior () @@ -2915,64 +2915,62 @@ ;; WARN: Return type mismatch int vs object. (defbehavior zero-g-wait-for-land gravity-spinner () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.5)) - (let* ((s4-0 (handle->process (-> self parent-hand))) - (s5-0 (if (type? s4-0 process-focusable) - s4-0 + (suspend-for + (seconds 1.5) + (let* ((s4-0 (handle->process (-> self parent-hand))) + (s5-0 (if (type? s4-0 process-focusable) + s4-0 + ) + ) + ) + (cond + ((and s5-0 + (not (logtest? (-> (the-as process-focusable s5-0) focus-status) (focus-status disable dead inactive))) + ) + (if (or (< (- (-> (get-trans (the-as process-focusable s5-0) 3) y) + (-> (the-as process-focusable s5-0) root root-prim local-sphere w) ) + (-> self ground-height) + ) + (let ((s4-1 (-> (the-as process-focusable s5-0) root))) + (and (if (type? s4-1 collide-shape-moving) + s4-1 + ) + (logtest? (-> (the-as collide-shape-moving (-> (the-as process-focusable s5-0) root)) status) + (collide-status on-surface touch-surface) + ) + ) ) + ) + (return (the-as object 0)) ) - (cond - ((and s5-0 - (not (logtest? (-> (the-as process-focusable s5-0) focus-status) (focus-status disable dead inactive))) - ) - (if (or (< (- (-> (get-trans (the-as process-focusable s5-0) 3) y) - (-> (the-as process-focusable s5-0) root root-prim local-sphere w) - ) - (-> self ground-height) - ) - (let ((s4-1 (-> (the-as process-focusable s5-0) root))) - (and (if (type? s4-1 collide-shape-moving) - s4-1 - ) - (logtest? (-> (the-as collide-shape-moving (-> (the-as process-focusable s5-0) root)) status) - (collide-status on-surface touch-surface) - ) - ) - ) - ) - (return (the-as object 0)) + (when (not (logtest? (process-mask vehicle) (-> (the-as process-focusable s5-0) mask))) + (let ((s4-2 (new 'stack 'sphere))) + (vector-lerp! + s4-2 + (-> (the-as process-focusable s5-0) root root-prim local-sphere) + (-> self original-sphere-offset) + (* 3.0 (seconds-per-frame)) ) - (when (not (logtest? (process-mask vehicle) (-> (the-as process-focusable s5-0) mask))) - (let ((s4-2 (new 'stack 'sphere))) - (vector-lerp! - s4-2 - (-> (the-as process-focusable s5-0) root root-prim local-sphere) - (-> self original-sphere-offset) - (* 3.0 (seconds-per-frame)) - ) - (set! (-> s4-2 r) (lerp - (-> (the-as process-focusable s5-0) root root-prim local-sphere w) - (-> self original-sphere-offset r) - (* 3.0 (seconds-per-frame)) - ) + (set! (-> s4-2 r) (lerp + (-> (the-as process-focusable s5-0) root root-prim local-sphere w) + (-> self original-sphere-offset r) + (* 3.0 (seconds-per-frame)) + ) + ) + (set! (-> (the-as process-focusable s5-0) root root-prim local-sphere quad) (-> s4-2 quad)) + ) + (if (>= (+ (current-time) (seconds -1)) time) + (set! (-> (the-as process-focusable s5-0) root root-prim local-sphere quad) + (-> self original-sphere-offset quad) ) - (set! (-> (the-as process-focusable s5-0) root root-prim local-sphere quad) (-> s4-2 quad)) ) - (if (>= (+ (current-time) (seconds -1)) gp-0) - (set! (-> (the-as process-focusable s5-0) root root-prim local-sphere quad) - (-> self original-sphere-offset quad) - ) - ) - ) ) - (else - (return (the-as object 0)) - ) + ) + (else + (return (the-as object 0)) ) ) - (suspend) ) ) (the-as int #f) @@ -3615,17 +3613,9 @@ ) ) (set! f30-0 (+ -0.6 f30-0)) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.15)) - (suspend) - ) - ) - ) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 13.5)) - (suspend) - ) + (suspend-for (seconds 0.15)) ) + (suspend-for (seconds 13.5)) (go empty-state) (set! f30-0 4.0) ) diff --git a/goal_src/jak3/engine/target/gun/gun-red-shot.gc b/goal_src/jak3/engine/target/gun/gun-red-shot.gc index 0d7f4c3a39..3b1d386633 100644 --- a/goal_src/jak3/engine/target/gun/gun-red-shot.gc +++ b/goal_src/jak3/engine/target/gun/gun-red-shot.gc @@ -1416,7 +1416,7 @@ (defmethod deactivate ((this gun-red-2-shockwave)) "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." - (blit-displays-work-method-17 *blit-displays-work* (-> this origin) 0 1.0 #f) + (setup-zoom-blur-2d *blit-displays-work* (-> this origin) 0 1.0 #f) (call-parent-method this) (none) ) @@ -1455,7 +1455,7 @@ (set! (-> self current-warp-alpha) 1.0) ) :exit (behavior () - (blit-displays-work-method-17 *blit-displays-work* (-> self origin) 0 1.0 #f) + (setup-zoom-blur-2d *blit-displays-work* (-> self origin) 0 1.0 #f) ) :trans (behavior () (let ((f0-1 @@ -1491,7 +1491,7 @@ (let* ((f0-16 (- 1.0 (evaluate *impact-blur* f0-14 (loop-behavior use-default)))) (f0-19 (lerp f0-16 1.0 (fmax 0.0 (- 0.5 (-> self strength))))) ) - (blit-displays-work-method-17 *blit-displays-work* (-> self origin) 2 (fmin 1.0 f0-19) #f) + (setup-zoom-blur-2d *blit-displays-work* (-> self origin) 2 (fmin 1.0 f0-19) #f) ) ) (if (< (-> self current-stage-t) 1.0) @@ -1840,11 +1840,7 @@ :virtual #t :trans (behavior () (go-impact self) - (let ((t9-2 (-> (find-parent-state) trans))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler trans) ) ) @@ -1852,11 +1848,7 @@ :virtual #t :trans (behavior () (go-impact self) - (let ((t9-2 (-> (find-parent-state) trans))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler trans) ) ) @@ -1891,7 +1883,7 @@ (defmethod deactivate ((this gun-red-3-grenade)) "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." - (blit-displays-work-method-17 *blit-displays-work* *zero-vector* 0 1.0 #f) + (setup-zoom-blur-2d *blit-displays-work* *zero-vector* 0 1.0 #f) (call-parent-method this) (none) ) @@ -1970,7 +1962,7 @@ (f0-14 (lerp f0-13 1.0 f30-1)) ) (set! (-> *display* force-sync) (the-as uint 2)) - (blit-displays-work-method-17 *blit-displays-work* (-> self root trans) 2 (fmin 1.0 f0-14) #f) + (setup-zoom-blur-2d *blit-displays-work* (-> self root trans) 2 (fmin 1.0 f0-14) #f) ) ) (let ((gp-8 (-> self child))) @@ -1984,7 +1976,7 @@ ) ) ) - (blit-displays-work-method-17 *blit-displays-work* (-> self root trans) 15 1.0 #f) + (setup-zoom-blur-2d *blit-displays-work* (-> self root trans) 15 1.0 #f) (deactivate self) ) ) diff --git a/goal_src/jak3/engine/target/gun/gun-yellow-shot.gc b/goal_src/jak3/engine/target/gun/gun-yellow-shot.gc index 86e95cd852..b615be1126 100644 --- a/goal_src/jak3/engine/target/gun/gun-yellow-shot.gc +++ b/goal_src/jak3/engine/target/gun/gun-yellow-shot.gc @@ -566,11 +566,7 @@ process (lambda :behavior process ((arg0 handle)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (send-event (handle->process arg0) 'die) ) gp-4 @@ -600,11 +596,7 @@ ) (logior! (-> self draw status) (draw-control-status no-draw)) (transform-post) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (deactivate self) ) :post ja-post @@ -742,11 +734,7 @@ ) ) ) - (let ((t9-5 (-> (find-parent-state) trans))) - (if t9-5 - (t9-5) - ) - ) + (call-parent-state-handler trans) (ja-post) ) ) @@ -1713,7 +1701,7 @@ (set! (-> s5-1 track-immediately?) #t) (let* ((v1-34 (estimate-light-trail-mem-usage (the-as uint (-> s5-1 max-num-crumbs)) - (the-as uint (= (-> s5-1 appearance lie-mode) 3)) + (the-as uint (= (-> s5-1 appearance lie-mode) (lie-mode use-two-strips))) ) ) (gp-1 (get-process *default-dead-pool* light-trail-tracker-projectile (+ v1-34 8192) 1)) @@ -1870,11 +1858,7 @@ :virtual #t :enter (behavior () (sound-stop (-> self snd-trail)) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) ) diff --git a/goal_src/jak3/engine/target/indax/target-indax.gc b/goal_src/jak3/engine/target/indax/target-indax.gc index 22447af858..ed4b9e6853 100644 --- a/goal_src/jak3/engine/target/indax/target-indax.gc +++ b/goal_src/jak3/engine/target/indax/target-indax.gc @@ -702,7 +702,7 @@ #f ) :post target-indax-post -) + ) (defstate target-indax-walk (target) :event target-indax-handler @@ -855,7 +855,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (case (-> self control unknown-spool-anim00) @@ -1510,11 +1510,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (move-to-point! (-> self control) s4-1) ) (set! (-> self control camera-pos quad) (-> self control trans quad)) @@ -1743,11 +1739,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) ((= arg0 'bot) (set! (-> self post-hook) target-no-move-post) diff --git a/goal_src/jak3/engine/target/mech/mech-states.gc b/goal_src/jak3/engine/target/mech/mech-states.gc index e8a2b4aef8..08899e3c23 100644 --- a/goal_src/jak3/engine/target/mech/mech-states.gc +++ b/goal_src/jak3/engine/target/mech/mech-states.gc @@ -1002,11 +1002,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (move-to-point! (-> self control) s4-1) ) (set! (-> self control camera-pos quad) (-> self control trans quad)) @@ -1146,12 +1142,7 @@ ) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! jakb-mech-jump-loop-ja :num! (loop! 0.5) :frame-num 0.0) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.8)) - (ja :group! jakb-mech-jump-loop-ja :num! (loop! 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.8) (ja :group! jakb-mech-jump-loop-ja :num! (loop! 0.5))) (remove-setting! 'mode-name) ) (else @@ -1253,11 +1244,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-10 (current-time))) - (until (time-elapsed? gp-10 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) ) (set! (-> self control transv quad) (the-as uint128 0)) @@ -2267,7 +2254,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) ((-> target-mech-carry-falling trans)) diff --git a/goal_src/jak3/engine/target/mech/mech.gc b/goal_src/jak3/engine/target/mech/mech.gc index 9a22c4cb4b..64d010b24e 100644 --- a/goal_src/jak3/engine/target/mech/mech.gc +++ b/goal_src/jak3/engine/target/mech/mech.gc @@ -251,12 +251,7 @@ (mech-method-24 self) (suspend) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (mech-method-24 self) - (suspend) - ) - ) + (suspend-for (seconds 1) (mech-method-24 self)) (go arg0) ) ) diff --git a/goal_src/jak3/engine/target/pilot-states.gc b/goal_src/jak3/engine/target/pilot-states.gc index a42298f041..a88a2ee252 100644 --- a/goal_src/jak3/engine/target/pilot-states.gc +++ b/goal_src/jak3/engine/target/pilot-states.gc @@ -1016,11 +1016,7 @@ (logior! (-> self focus-status) (focus-status dead)) (case arg0 (('melt 'grenade 'explode) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (case arg0 (('dark-eco-pool) (sound-play "death-darkeco") @@ -1068,11 +1064,7 @@ ) 0 (ja-channel-set! 0) - (let ((s5-11 (current-time))) - (until (time-elapsed? s5-11 (seconds 1.8)) - (suspend) - ) - ) + (suspend-for (seconds 1.8)) ) (('endlessfall) (sound-play "death-fall") @@ -1101,11 +1093,7 @@ ) ) ) - (let ((s5-13 (current-time))) - (until (time-elapsed? s5-13 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) ) (('drown-death) (logclear! (-> self water flags) (water-flag swim-ground)) @@ -1127,11 +1115,7 @@ ) ) ) - (let ((s5-14 (current-time))) - (until (time-elapsed? s5-14 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) (('bot) (set! (-> self trans-hook) #f) @@ -1141,11 +1125,7 @@ ) ) (('big-explosion) - (let ((s5-15 (current-time))) - (until (time-elapsed? s5-15 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) (else ) diff --git a/goal_src/jak3/engine/target/target-darkjak.gc b/goal_src/jak3/engine/target/target-darkjak.gc index 6902ea0aaa..7f48ca9341 100644 --- a/goal_src/jak3/engine/target/target-darkjak.gc +++ b/goal_src/jak3/engine/target/target-darkjak.gc @@ -292,11 +292,7 @@ (set! (-> self part) (the-as sparticle-launch-control 0)) 0 ) - (let ((t9-5 (-> (find-parent-state) enter))) - (if t9-5 - (t9-5) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () (dotimes (gp-0 (-> self bolts length)) diff --git a/goal_src/jak3/engine/target/target-death.gc b/goal_src/jak3/engine/target/target-death.gc index 944b8253af..24c68da7b5 100644 --- a/goal_src/jak3/engine/target/target-death.gc +++ b/goal_src/jak3/engine/target/target-death.gc @@ -57,11 +57,7 @@ (intro-play) ) ((logtest? (-> arg0 flags) (continue-flags warp-gate)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.05)) - (suspend) - ) - ) + (suspend-for (seconds 0.05)) (let ((s5-1 (new 'static 'vector)) (a2-0 (find-nearest-entity (-> arg0 trans) warp-gate)) ) @@ -220,11 +216,7 @@ (go target-grab 'stance) ) (else - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.05)) - (suspend) - ) - ) + (suspend-for (seconds 0.05)) ) ) 0 @@ -1458,11 +1450,7 @@ (let ((gp-1 (new-stack-vector0))) (set! (-> gp-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (move-to-point! (-> self control) gp-1) ) (set! (-> self control camera-pos quad) (-> self control trans quad)) @@ -2290,11 +2278,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-5 (current-time))) - (until (time-elapsed? s5-5 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) (('grenade 'big-explosion 'explode) (set! (-> self post-hook) target-no-stick-post) @@ -2373,11 +2357,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((s5-10 (current-time))) - (until (time-elapsed? s5-10 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) ) ) @@ -2393,11 +2373,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-11 (current-time))) - (until (time-elapsed? s5-11 (seconds 1.2)) - (suspend) - ) - ) + (suspend-for (seconds 1.2)) ) ((= v1-61 'endlessfall) ((lambda :behavior target @@ -2435,38 +2411,36 @@ (target-falling-anim 30 (seconds 0.33)) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! jakb-launch-jump-loop-ja :num! (loop! 0.5) :frame-num 0.0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.8)) - (when (and (logtest? (-> self control status) (collide-status on-surface)) (!= (-> self control cur-pat event) 2)) - (set! v1-24 'target-hit-ground-hard) - (goto cfg-17) + (suspend-for + (seconds 0.8) + (when (and (logtest? (-> self control status) (collide-status on-surface)) (!= (-> self control cur-pat event) 2)) + (set! v1-24 'target-hit-ground-hard) + (goto cfg-17) + ) + (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) + (let ((v1-49 (new-stack-vector0)) + (f0-7 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) + ) + 0.0 + (vector-! + v1-49 + (-> self control transv) + (vector-float*! v1-49 (-> self control dynam gravity-normal) (the-as float f0-7)) ) - (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) - (let ((v1-49 (new-stack-vector0)) - (f0-7 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) + (let* ((f1-7 (vector-length v1-49)) + (f2-2 f1-7) + ) + (if (< (the-as float (-> self control unknown-word04)) (the-as float f0-7)) + (set! f0-7 (-> self control unknown-word04)) ) - 0.0 - (vector-! - v1-49 + (vector+! (-> self control transv) - (vector-float*! v1-49 (-> self control dynam gravity-normal) (the-as float f0-7)) - ) - (let* ((f1-7 (vector-length v1-49)) - (f2-2 f1-7) - ) - (if (< (the-as float (-> self control unknown-word04)) (the-as float f0-7)) - (set! f0-7 (-> self control unknown-word04)) - ) - (vector+! - (-> self control transv) - (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f0-7)) - (vector-float*! v1-49 v1-49 (/ f1-7 f2-2)) - ) + (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f0-7)) + (vector-float*! v1-49 v1-49 (/ f1-7 f2-2)) ) ) - (ja :group! jakb-launch-jump-loop-ja :num! (loop! 0.5)) - (suspend) ) + (ja :group! jakb-launch-jump-loop-ja :num! (loop! 0.5)) ) (set! v1-24 #f) (label cfg-17) @@ -2491,11 +2465,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) (remove-setting! 'mode-name) ) @@ -2660,11 +2630,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((s5-14 (current-time))) - (until (time-elapsed? s5-14 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) ((= v1-61 'centipede) (set! (-> self trans-hook) #f) diff --git a/goal_src/jak3/engine/target/target-handler.gc b/goal_src/jak3/engine/target/target-handler.gc index d0a4571d1a..653348400f 100644 --- a/goal_src/jak3/engine/target/target-handler.gc +++ b/goal_src/jak3/engine/target/target-handler.gc @@ -204,24 +204,20 @@ process (lambda :behavior target () - (let ((gp-0 (current-time)) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 (seconds 1)) - (when (time-elapsed? gp-0 (seconds 0.03)) - (set! gp-0 (current-time)) - (process-drawable-shock-effect - *target* - (-> *lightning-spec-id-table* 1) - lightning-probe-callback - (-> *part-id-table* 160) - 0 - 0 - 40960.0 - ) - ) - (suspend) - ) + (let ((gp-0 (current-time))) + (suspend-for (seconds 1) (when (time-elapsed? gp-0 (seconds 0.03)) + (set! gp-0 (current-time)) + (process-drawable-shock-effect + *target* + (-> *lightning-spec-id-table* 1) + lightning-probe-callback + (-> *part-id-table* 160) + 0 + 0 + 40960.0 + ) + ) + ) ) (none) ) diff --git a/goal_src/jak3/engine/target/target-invisible.gc b/goal_src/jak3/engine/target/target-invisible.gc index cfcbbbe32b..468be4ddda 100644 --- a/goal_src/jak3/engine/target/target-invisible.gc +++ b/goal_src/jak3/engine/target/target-invisible.gc @@ -442,11 +442,7 @@ (set-time! (-> self state-time)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.66)) - (suspend) - ) - ) + (suspend-for (seconds 0.66)) (cond ((logtest? (-> *part-group-id-table* 182 flags) (sp-group-flag sp13)) (set! (-> *launch-matrix* trans quad) (-> self root trans quad)) @@ -473,11 +469,7 @@ ) ) (sound-play "dark-maker") - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (go-virtual idle) ) :post (behavior () diff --git a/goal_src/jak3/engine/target/target-lightjak.gc b/goal_src/jak3/engine/target/target-lightjak.gc index 2e5ac14176..e8aa500cfa 100644 --- a/goal_src/jak3/engine/target/target-lightjak.gc +++ b/goal_src/jak3/engine/target/target-lightjak.gc @@ -2275,12 +2275,7 @@ (defstate die (freeze-screen) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (seek! (-> self transition) 0.0 (seconds-per-frame)) - (suspend) - ) - ) + (suspend-for (seconds 1) (seek! (-> self transition) 0.0 (seconds-per-frame))) ) ) @@ -2298,8 +2293,9 @@ (gp-0 (new 'stack-no-clear 'vector)) (f30-0 4096.0) ) + ;; og:preserve-this resize effect based on aspect ratio (let ((f0-4 (* 0.00013563369 (tan (* 0.5 (-> *math-camera* fov))) f30-0))) - (set-vector! (-> this root scale) f0-4 f0-4 f0-4 1.0) + (set-vector! (-> this root scale) (* f0-4 (if (-> *pc-settings* use-vis?) 1.0 (-> *pc-settings* aspect-ratio-scale))) f0-4 f0-4 1.0) ) (set! (-> gp-0 quad) (-> (camera-pos) quad)) (vector-normalize-copy! s5-0 (-> s3-0 fvec) 1.0) diff --git a/goal_src/jak3/engine/target/target-turret.gc b/goal_src/jak3/engine/target/target-turret.gc index d3ef6d4fe2..fb6af882c6 100644 --- a/goal_src/jak3/engine/target/target-turret.gc +++ b/goal_src/jak3/engine/target/target-turret.gc @@ -1018,11 +1018,7 @@ (sound-stop (-> self sound-id 1)) (sound-stop (-> self sound-id 2)) (logior! (-> self focus-status) (focus-status disable ignore inactive)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.8)) - (suspend) - ) - ) + (suspend-for (seconds 0.8)) (send-event (handle->process (-> self rider)) 'attack diff --git a/goal_src/jak3/engine/target/target.gc b/goal_src/jak3/engine/target/target.gc index db98808b87..0890c7ed7f 100644 --- a/goal_src/jak3/engine/target/target.gc +++ b/goal_src/jak3/engine/target/target.gc @@ -1137,7 +1137,7 @@ (set! (-> self control unknown-float36) (fmax (-> self control unknown-float36) - (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton 6))) + (* 0.003921569 (the float (-> *cpad-list* cpads (-> self control cpad number) abutton (abutton-idx x)))) ;; og:preserve-this abutton indexing ) ) (let ((t9-0 target-falling-trans) diff --git a/goal_src/jak3/engine/target/target2.gc b/goal_src/jak3/engine/target/target2.gc index c8dfaea6f7..1fc5ab716c 100644 --- a/goal_src/jak3/engine/target/target2.gc +++ b/goal_src/jak3/engine/target/target2.gc @@ -47,13 +47,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.3)) - (suspend) - (ja :num! (seek! (ja-aframe 19.0 0) 0.05)) - (suspend) - ) - ) + (suspend-for (seconds 0.3) (suspend) (ja :num! (seek! (ja-aframe 19.0 0) 0.05))) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! jakb-painful-land-ja :num! (seek!) :frame-num (ja-aframe 40.0 0)) (until (ja-done? 0) @@ -1545,12 +1539,7 @@ (until #f (let ((s5-0 (rand-vu-int-range 30 600))) (ja :group! jakb-wall-hide-head-ja) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 s5-0) - (gp-0) - (suspend) - ) - ) + (suspend-for s5-0 (gp-0)) ) (let ((f30-0 (rand-vu-float-range 0.5 1.5))) (cond @@ -1587,13 +1576,8 @@ (suspend) (ja :num! (seek! max f30-0)) ) - (let ((s5-2 (rand-vu-int-range 60 300)) - (s4-2 (current-time)) - ) - (until (time-elapsed? s4-2 s5-2) - (gp-0) - (suspend) - ) + (let ((s5-2 (rand-vu-int-range 60 300))) + (suspend-for s5-2 (gp-0)) ) (ja-no-eval :group! jakb-wall-hide-head-left-ja :num! (seek! 0.0 f30-0) :frame-num max) (until (ja-done? 0) @@ -1609,13 +1593,8 @@ (suspend) (ja :num! (seek! 0.0 f30-0)) ) - (let ((s5-3 (rand-vu-int-range 60 300)) - (s4-3 (current-time)) - ) - (until (time-elapsed? s4-3 s5-3) - (gp-0) - (suspend) - ) + (let ((s5-3 (rand-vu-int-range 60 300))) + (suspend-for s5-3 (gp-0)) ) (ja-no-eval :group! jakb-wall-hide-head-right-ja :num! (seek! max f30-0) :frame-num 0.0) (until (ja-done? 0) @@ -1962,14 +1941,14 @@ (suspend) (ja :num! (seek!)) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (the-as time-frame arg0)) - (ja-no-eval :group! jakb-blast-recover-loop-ja :num! (seek!) :frame-num 0.0) - (until (ja-done? 0) - (suspend) - (ja :num! (seek!)) - ) + (suspend-for + (the-as time-frame arg0) + (ja-no-eval :group! jakb-blast-recover-loop-ja :num! (seek!) :frame-num 0.0) + (until (ja-done? 0) + (suspend) + (ja :num! (seek!)) ) + (empty-form) ) (ja-no-eval :group! jakb-blast-recover-end-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) diff --git a/goal_src/jak3/engine/ui/bigmap-h.gc b/goal_src/jak3/engine/ui/bigmap-h.gc index b220a59ff5..2572aa83f3 100644 --- a/goal_src/jak3/engine/ui/bigmap-h.gc +++ b/goal_src/jak3/engine/ui/bigmap-h.gc @@ -5,6 +5,46 @@ ;; name in dgo: bigmap-h ;; dgos: GAME +;; +++bigmap-flag +(defenum bigmap-flag + :type uint32 + :bitfield #t + (bf00 0) + (bf01 1) + (bf02 2) + (bf03 3) + (bf04 4) + (bf05 5) + (bf06 6) + (bf07 7) + (bf08 8) + (bf09 9) + (bf10 10) + (bf11 11) + (bf12 12) + (bf13 13) + (bf14 14) + (bf15 15) + (bf16 16) + (bf17 17) + (ctywide 18) + (waswide 19) + (wasall 20) + (desert 21) + (bf22 22) + (bf23 23) + (bf24 24) + (bf25 25) + (bf26 26) + (bf27 27) + (bf28 28) + (bf29 29) + (bf30 30) + (bf31 31) + ) +;; ---bigmap-flag + + ;; DECOMP BEGINS (deftype bigmap-image (structure) @@ -33,13 +73,13 @@ (deftype bigmap (basic) ((drawing-flag symbol) (loading-flag symbol) - (bigmap-index uint32) + (bigmap-index bigmap-id) (bigmap-image external-art-buffer) (tpage external-art-buffer) - (tpage2 basic) + (tpage2 external-art-buffer) (progress-minimap texture-page) (progress-minimap2 texture-page) - (load-index uint32) + (load-index bigmap-id) (x0 int32) (y0 int32) (x1 int32) @@ -56,24 +96,24 @@ (color vector4w :inline) (corner vector 4 :inline) (auto-save-icon-flag symbol) - (global-flags uint32) + (global-flags bigmap-flag) ) (:methods (new (symbol type) _type_) - (bigmap-method-9 () none) + (initialize (_type_) none) (update (_type_) none) - (bigmap-method-11 (_type_) symbol) - (bigmap-method-12 () none) - (bigmap-method-13 () none) + (loaded? (_type_) symbol) + (draw! (_type_ int int int int) none) + (handle-cpad-input (_type_) none) (enable-drawing (_type_) none) (disable-drawing (_type_) int) - (bigmap-method-16 (_type_) none) - (bigmap-method-17 () none) - (bigmap-method-18 () none) - (bigmap-method-19 () none) - (bigmap-method-20 () none) - (bigmap-method-21 () none) - (bigmap-method-22 () none) + (set-map-indices! (_type_) none) + (set-pos! (_type_ vector) none) + (bigmap-method-18 (_type_ (pointer int32)) none) + (texture-upload-dma (_type_ dma-buffer (pointer uint32) int int int gs-psm) none) + (bigmap-method-20 (_type_ dma-buffer) symbol) + (sprite-dma (_type_ dma-buffer int int int int int int) object) + (draw-from-minimap (_type_ dma-buffer connection-minimap) none) ) ) diff --git a/goal_src/jak3/engine/ui/bigmap.gc b/goal_src/jak3/engine/ui/bigmap.gc index 94f191eeb1..bc1a31e8a7 100644 --- a/goal_src/jak3/engine/ui/bigmap.gc +++ b/goal_src/jak3/engine/ui/bigmap.gc @@ -7,9 +7,944 @@ ;; DECOMP BEGINS -(kmemopen global "bigmap") +(defmethod new bigmap ((allocation symbol) (type-to-make type)) + (let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size))))) + (set! (-> gp-0 bigmap-image) + ((method-of-type external-art-buffer new) + allocation + external-art-buffer + 0 + (lambda ((arg0 external-art-buffer)) + (let ((a1-3 (logand -64 (+ -591936 (-> *display* frames 0 global-buf real-buffer-end) 63))) + (v1-1 (-> arg0 heap)) + ) + (set! (-> v1-1 base) (the-as pointer a1-3)) + (set! (-> v1-1 current) (-> v1-1 base)) + (set! (-> v1-1 top-base) (&+ (-> v1-1 base) #x90800)) + (set! (-> v1-1 top) (-> v1-1 top-base)) + ) + 0 + ) + #f + ) + ) + (set! (-> gp-0 tpage) + ((method-of-type external-art-buffer new) + allocation + external-art-buffer + 0 + (lambda ((arg0 external-art-buffer)) + (let ((a1-3 (logand -64 (+ -597056 (-> *display* frames 1 global-buf real-buffer-end) 63))) + (v1-1 (-> arg0 heap)) + ) + (set! (-> v1-1 base) (the-as pointer a1-3)) + (set! (-> v1-1 current) (-> v1-1 base)) + (set! (-> v1-1 top-base) (&+ (-> v1-1 base) #x54000)) + (set! (-> v1-1 top) (-> v1-1 top-base)) + ) + 0 + ) + #f + ) + ) + (set! (-> gp-0 tpage2) + ((method-of-type external-art-buffer new) + allocation + external-art-buffer + 0 + (lambda ((arg0 external-art-buffer)) + (let ((a1-3 (logand -64 (+ -941120 (-> *display* frames 1 global-buf real-buffer-end) 63))) + (v1-1 (-> arg0 heap)) + ) + (set! (-> v1-1 base) (the-as pointer a1-3)) + (set! (-> v1-1 current) (-> v1-1 base)) + (set! (-> v1-1 top-base) (&+ (-> v1-1 base) #x54000)) + (set! (-> v1-1 top) (-> v1-1 top-base)) + ) + 0 + ) + #f + ) + ) + (set! (-> gp-0 sprite-tmpl dma-vif dma) (new 'static 'dma-tag :qwc #x6 :id (dma-tag-id cnt))) + (set! (-> gp-0 sprite-tmpl dma-vif vif0) (new 'static 'vif-tag)) + (set! (-> gp-0 sprite-tmpl dma-vif vif1) (new 'static 'vif-tag :imm #x6 :cmd (vif-cmd direct) :msk #x1)) + (set! (-> gp-0 sprite-tmpl gif0) (the-as uint #x50ab400000008001)) + (set! (-> gp-0 sprite-tmpl gif1) (the-as uint #x53531)) + (set! (-> gp-0 draw-tmpl dma-vif dma) (new 'static 'dma-tag :qwc #xa :id (dma-tag-id cnt))) + (set! (-> gp-0 draw-tmpl dma-vif vif0) (new 'static 'vif-tag)) + (set! (-> gp-0 draw-tmpl dma-vif vif1) (new 'static 'vif-tag :imm #xa :cmd (vif-cmd direct) :msk #x1)) + (set! (-> gp-0 draw-tmpl gif0) (the-as uint #x90aa400000008001)) + (set! (-> gp-0 draw-tmpl gif1) (the-as uint #x535353531)) + (set! (-> gp-0 adgif-tmpl dma-vif dma) (new 'static 'dma-tag :qwc #x6 :id (dma-tag-id cnt))) + (set! (-> gp-0 adgif-tmpl dma-vif vif0) (new 'static 'vif-tag)) + (set! (-> gp-0 adgif-tmpl dma-vif vif1) (new 'static 'vif-tag :imm #x6 :cmd (vif-cmd direct) :msk #x1)) + (set! (-> gp-0 adgif-tmpl gif0) (the-as uint #x1000000000008005)) + (set! (-> gp-0 adgif-tmpl gif1) (the-as uint 14)) + (set-vector! (-> gp-0 offset) 0.0 0.0 0.0 0.0) + (set-vector! (-> gp-0 scroll) 0.0 0.0 0.0 0.0) + (set-vector! (-> gp-0 pos) 0 0 0 0) + (set-vector! (-> gp-0 color) 128 128 128 128) + (set! (-> gp-0 drawing-flag) #f) + (set! (-> gp-0 loading-flag) #f) + (set! (-> gp-0 progress-minimap) #f) + (set! (-> gp-0 progress-minimap2) #f) + (set! (-> gp-0 auto-save-icon-flag) #f) + (initialize gp-0) + gp-0 + ) + ) + +(define *bigmap-info-array* + (new 'static 'bigmap-info-array + :data (new 'static 'inline-array bigmap-info 24 + (new 'static 'bigmap-info :x -2621440.0 :y -4456448.0 :z 16384.0 :w 0.000061035156) + (new 'static 'bigmap-info :x -2621440.0 :y -4456448.0 :z 16384.0 :w 0.000061035156) + (new 'static 'bigmap-info :x -2038169.6 :y -2301542.5 :z 27443.2 :w 0.0000364389) + (new 'static 'bigmap-info :x -354713.6 :y -1128448.0 :z 4505.6 :w 0.00022194601) + (new 'static 'bigmap-info :x -4205363.0 :y 3437363.2 :z 4628.48 :w 0.00021605365) + (new 'static 'bigmap-info :x -3381657.5 :y 2019737.6 :z 7618.56 :w 0.0001312584) + (new 'static 'bigmap-info :x -1399193.6 :y -1023590.4 :z 5406.72 :w 0.00018495502) + (new 'static 'bigmap-info :x 2215526.5 :y 615055.4 :z 10444.8 :w 0.00009574142) + (new 'static 'bigmap-info :x 2215526.5 :y 615055.4 :z 10444.8 :w 0.00009574142) + (new 'static 'bigmap-info :z 16384.0 :w 0.000061035156) + (new 'static 'bigmap-info :x -1481932.8 :y -918323.2 :z 5857.28 :w 0.00017072771) + (new 'static 'bigmap-info :x -1481932.8 :y -918323.2 :z 5857.28 :w 0.00017072771) + (new 'static 'bigmap-info :x -2614886.5 :y -1766195.2 :z 9052.16 :w 0.00011047087) + (new 'static 'bigmap-info :x -2530508.8 :y -1041203.2 :z 5591.04 :w 0.0001788576) + (new 'static 'bigmap-info :x -2374451.2 :y -4505.6 :z 4628.48 :w 0.00021605365) + (new 'static 'bigmap-info :x -2712780.8 :y -2477260.8 :z 6471.68 :w 0.00015451938) + (new 'static 'bigmap-info :x -1218560.0 :y -3392307.2 :z 5857.28 :w 0.00017072771) + (new 'static 'bigmap-info :x 16039117.0 :y 16509747.0 :z 3317.76 :w 0.00030140817) + (new 'static 'bigmap-info :x 15403827.0 :y 16360653.0 :z 5283.84 :w 0.0001892563) + (new 'static 'bigmap-info :x 15403827.0 :y 16360653.0 :z 5283.84 :w 0.0001892563) + (new 'static 'bigmap-info :x 15403827.0 :y 16360653.0 :z 5283.84 :w 0.0001892563) + (new 'static 'bigmap-info :x -1716224.0 :y 1286144.0 :z 3604.48 :w 0.00027743253) + (new 'static 'bigmap-info :x -1316864.0 :y -2084126.8 :z 4014.08 :w 0.00024912308) + (new 'static 'bigmap-info :x 5619712.0 :y -2914304.0 :z 9830.4 :w 0.00010172526) + ) + ) + ) + +(defmethod set-pos! ((this bigmap) (arg0 vector)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (init-vf0-vector) + (.lvf vf1 (&-> arg0 quad)) + (.lvf vf2 (&-> this offset quad)) + (.add.z.vf vf1 vf0 vf1 :mask #b10) + (.sub.vf vf1 vf1 vf2) + (.mul.w.vf vf1 vf1 vf2) + (.ftoi.vf vf1 vf1) + (.svf (&-> this pos quad) vf1) + 0 + (none) + ) + ) + +(defmethod bigmap-method-18 ((this bigmap) (arg0 (pointer int32))) + (when (or (= (-> this load-index) (bigmap-id sewer-met-hum)) (= (-> this load-index) (bigmap-id sewer-hum-kg))) + (let ((v1-4 (-> arg0 0))) + (set! (-> arg0 0) (-> arg0 1)) + (set! (-> arg0 1) (- 832 v1-4)) + ) + ) + (none) + ) + +;; og:preserve-this +(defun pc-upload-map-texture ((dma-buf dma-buffer) (image-data pointer) (clut-data pointer) (width int) (height int) (tbp int) (cbp int)) + "Added function in the PC port to create a map texture. The format should be mt8 for the image and ct32 for the clut (16 x 16)" + (pc-texture-anim-flag start-anim-array dma-buf) + (pc-texture-anim-flag upload-clut-16-16 dma-buf :qwc 1) + (let ((upload-record (the texture-anim-pc-upload (-> dma-buf base)))) + (set! (-> upload-record data) clut-data) + (set! (-> upload-record width) 16) + (set! (-> upload-record height) 16) + (set! (-> upload-record dest) cbp) + (set! (-> upload-record format) (gs-psm ct32)) + (set! (-> upload-record force-to-gpu) 0) + ) + (&+! (-> dma-buf base) 16) + + (pc-texture-anim-flag upload-generic-vram dma-buf :qwc 1) + (let ((upload-record (the texture-anim-pc-upload (-> dma-buf base)))) + (set! (-> upload-record data) image-data) + (set! (-> upload-record width) width) + (set! (-> upload-record height) height) + (set! (-> upload-record dest) tbp) + (set! (-> upload-record format) (gs-psm mt8)) + (set! (-> upload-record force-to-gpu) 1) + ) + (&+! (-> dma-buf base) 16) + (pc-texture-anim-flag finish-anim-array dma-buf) + ) + +(defmethod texture-upload-dma ((this bigmap) (arg0 dma-buffer) (arg1 (pointer uint32)) (arg2 int) (arg3 int) (arg4 int) (arg5 gs-psm)) + (local-vars (sv-16 int)) + (set! sv-16 arg2) + (dma-buffer-add-gs-set arg0 + (bitbltbuf (new 'static 'gs-bitbltbuf :dpsm (the-as int arg5) :dbp sv-16 :dbw (/ arg3 64))) + (trxpos (new 'static 'gs-trxpos)) + (trxreg (new 'static 'gs-trxreg :rrw arg3 :rrh arg4)) + (trxdir (new 'static 'gs-trxdir)) + ) + (dma-buffer-add-ref-texture arg0 arg1 arg3 arg4 arg5) + 0 + (none) + ) + +;; WARN: Return type mismatch pointer vs object. +(defmethod sprite-dma ((this bigmap) (arg0 dma-buffer) (arg1 int) (arg2 int) (arg3 int) (arg4 int) (arg5 int) (arg6 int)) + (let ((v1-0 (the-as object (-> arg0 base)))) + (let ((t5-0 0) + (t4-2 (the int (* 416.0 (-> *video-params* relative-x-scale)))) + ) + (set! (-> (the-as (inline-array vector4w) v1-0) 0 quad) (-> this sprite-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-0) 1 quad) (-> this sprite-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) v1-0) 2 quad) (-> this color quad)) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 3) (* arg5 16) (* t5-0 16) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 4) (* arg1 16) (* arg3 16) #xfffff0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 5) (* arg6 16) (* t4-2 16) 0 0) + ) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 6) (* arg2 16) (* arg4 16) #xfffff0 0) + ) + (let ((v0-0 (&+ (-> arg0 base) 112))) + (set! (-> arg0 base) v0-0) + v0-0 + ) + ) + +(defmethod bigmap-method-20 ((this bigmap) (arg0 dma-buffer)) + (local-vars (sv-16 uint)) + (let* ((s4-0 (the-as (pointer uint32) (-> this bigmap-image art-group))) + (f0-1 (* 0.001953125 (the float (- (-> this x1) (-> this x0))))) + (s3-0 (the int (* 256.0 f0-1))) + (v1-5 (the int (-> this scroll x))) + (a0-2 (-> this x0)) + (f1-7 (-> this scroll x)) + (s2-0 (- a0-2 (the int (* (- f1-7 (* (the float (the int (/ f1-7 256.0))) 256.0)) f0-1)))) + (s1-0 (/ v1-5 256)) + (s0-0 (/ (+ v1-5 511) 256)) + ) + (-> s4-0 2) + (set! sv-16 (* (-> s4-0 3) 256)) + (while (>= s0-0 s1-0) + ;; og:preserve-this + ; (texture-upload-dma this arg0 (+ (+ (-> s4-0 0) 16) (the-as uint s4-0)) 0 16 16 (gs-psm ct32)) + ; (dma-buffer-add-gs-set arg0 (texflush 0)) + (let ((v1-18 (+ (-> s4-0 1) (* (the-as uint s1-0) sv-16) (* (the int (-> this scroll y)) 256)))) + ; (texture-upload-dma this arg0 (+ (+ v1-18 16) (the-as uint s4-0)) 8 256 416 (gs-psm mt8)) + (pc-upload-map-texture arg0 (&+ s4-0 v1-18 16) (&+ s4-0 (-> s4-0 0) 16) 256 416 8 0) + ) + (dma-buffer-add-gs-set arg0 + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x8 :tbw #x4 :psm #x13 :tw #x8 :th #x9 :cld #x1)) + ;; og:preserve-this added mmag and mmin for texture filtering + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (texflush 0) + ) + (sprite-dma this arg0 (+ s2-0 1792) (+ s3-0 1792 s2-0) (-> this y0) (-> this y1) 0 256) + (+! s2-0 s3-0) + (+! s1-0 1) + ) + ) + #f + ) + +(defmethod draw-from-minimap ((this bigmap) (arg0 dma-buffer) (arg1 connection-minimap)) + (local-vars (sv-80 vector4w)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (init-vf0-vector) + (cond + ((= (-> arg1 position) #t) + (let* ((s3-0 (handle->process (-> arg1 handle))) + (v1-4 (if (type? s3-0 process-drawable) + (the-as process-drawable s3-0) + ) + ) + ) + (if (and v1-4 (nonzero? (-> v1-4 root))) + (set! (-> arg1 last-world-pos quad) (-> v1-4 root trans quad)) + ) + ) + ) + ((and (= (logand (the-as int (-> arg1 position)) 7) 4) + (= (-> (the-as entity-actor (-> arg1 position)) type) entity-actor) + ) + (let* ((v1-14 (the-as entity-actor (-> arg1 position))) + (s3-1 (if v1-14 + (-> v1-14 extra process) + ) + ) + (a0-13 (if (type? s3-1 process-drawable) + (the-as process-drawable s3-1) + ) + ) + ) + (if a0-13 + (set! (-> arg1 last-world-pos quad) (-> a0-13 root trans quad)) + (set! (-> arg1 last-world-pos quad) (-> (the-as entity-actor (-> arg1 position)) extra trans quad)) + ) + ) + ) + (else + (set! (-> arg1 last-world-pos quad) (-> arg1 position quad)) + ) + ) + (let ((f30-0 (-> arg1 class scale)) + (s1-0 (-> arg1 class color)) + ) + (set! sv-80 (new 'stack-no-clear 'vector4w)) + (let ((s0-0 (new-stack-vector0)) + (s2-0 (new-stack-vector0)) + (s3-2 (new-stack-vector0)) + ) + (let ((f26-0 (-> *video-params* relative-x-scale)) + (f28-0 (-> *video-params* relative-x-scale-reciprical)) + ) + (-> arg1 class) + (.lvf vf1 (&-> arg1 last-world-pos quad)) + (.lvf vf2 (&-> this offset quad)) + (.add.z.vf vf1 vf0 vf1 :mask #b10) + (.sub.vf vf1 vf1 vf2) + (.mul.w.vf vf1 vf1 vf2) + (.ftoi.vf vf1 vf1) + (.svf (&-> sv-80 quad) vf1) + (if (logtest? (-> arg1 class flags) (minimap-flag goal)) + (set! (-> arg1 class icon-xy x) (the-as uint (mod (the int (-> this goal-time)) 6))) + ) + (bigmap-method-18 this (the-as (pointer int32) sv-80)) + (cond + ((get-horizontal-flip-flag *blit-displays-work*) + (set! f26-0 (- f26-0)) + (set! (-> s0-0 x) (+ (the float (+ (- 2304 (-> sv-80 x)) (-> this x1))) (-> this scroll x))) + ) + (else + (set! (-> s0-0 x) (- (the float (+ (-> sv-80 x) 1792 (-> this x0))) (-> this scroll x))) + ) + ) + (set! (-> s0-0 y) (+ 1840.0 (* (- (the float (-> sv-80 y)) (-> this scroll y)) f28-0))) + (let ((f0-12 (* 20.0 f26-0 f30-0)) + (f1-8 (* 20.0 f28-0 f30-0)) + ) + (set! (-> s2-0 x) (the float (the int (- (-> s0-0 x) (* 0.5 f0-12))))) + (set! (-> s2-0 y) (the float (the int (- (-> s0-0 y) (* 0.5 f1-8))))) + (set! (-> s3-2 x) (+ (-> s2-0 x) f0-12)) + (set! (-> s3-2 y) (+ (-> s2-0 y) f1-8)) + ) + ) + ;; og:preserve-this cast + (let* ((a2-1 (the int (+ (* (the-as uint 320) (-> arg1 class icon-xy x)) 8))) + (a3-0 (the int (+ (* (the-as uint 320) (-> arg1 class icon-xy y)) 8))) + ;; og:preserve-this fix icon misalignment + (v1-55 (+ a2-1 300)) + (a0-35 (+ a3-0 300)) + (a1-6 (the-as object (-> arg0 base))) + ) + (set! (-> (the-as (inline-array vector4w) a1-6) 0 quad) (-> this sprite-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) a1-6) 1 quad) (-> this sprite-tmpl quad 1)) + (set-vector! + (-> (the-as (inline-array vector4w) a1-6) 2) + (the-as int (-> s1-0 r)) + (the-as int (-> s1-0 g)) + (the-as int (-> s1-0 b)) + 128 + ) + (set-vector! (-> (the-as (inline-array vector4w) a1-6) 3) a2-1 a3-0 0 0) + (set-vector! + (-> (the-as (inline-array vector4w) a1-6) 4) + (the int (* 16.0 (-> s2-0 x))) + (the int (* 16.0 (-> s2-0 y))) + #xffffff + 0 + ) + (set-vector! (-> (the-as (inline-array vector4w) a1-6) 5) v1-55 a0-35 0 0) + (set-vector! + (-> (the-as (inline-array vector4w) a1-6) 6) + (the int (* 16.0 (-> s3-2 x))) + (the int (* 16.0 (-> s3-2 y))) + #xffffff + 0 + ) + ) + ) + ) + (&+! (-> arg0 base) 112) + 0 + (none) + ) + ) + +(defmethod initialize ((this bigmap)) + (set! (-> this bigmap-index) (bigmap-id city)) + (set-pending-file (-> this bigmap-image) (the-as string #f) 0 (process->handle *dproc*) 0.0) + 0 + (none) + ) + +(defmethod update ((this bigmap)) + (when (-> this drawing-flag) + (update! *minimap*) + (cond + ((= (-> *blit-displays-work* count-down) 1) + (set-pending-file + (-> this bigmap-image) + "world-map" + (the-as int (-> this load-index)) + (process->handle *dproc*) + 0.0 + ) + (set-pending-file (-> this tpage) "progress-minimap" 0 (process->handle *dproc*) 0.0) + (set-pending-file (-> this tpage2) "progress-minimap" 1 (process->handle *dproc*) 0.0) + (set! (-> this loading-flag) #t) + ) + (else + (update (-> this bigmap-image)) + (update (-> this tpage)) + (update (-> this tpage2)) + (when (and (-> this loading-flag) + (= (file-status (-> this bigmap-image) "world-map" (the-as int (-> this load-index))) 'active) + (= (file-status (-> this tpage) "progress-minimap" 0) 'active) + (= (file-status (-> this tpage2) "progress-minimap" 1) 'active) + (not (load-in-progress? *level*)) + ) + (let ((s5-0 (-> *level* loading-level)) + (s4-0 (-> *texture-pool* allocate-func)) + (s3-0 (-> *texture-relocate-later* memcpy)) + (s2-0 loading-level) + ) + (set! (-> *texture-pool* allocate-func) texture-page-common-boot-allocate) + (set! (-> *level* loading-level) #f) + (set! (-> *texture-relocate-later* memcpy) #f) + (set! loading-level (-> this tpage heap)) + (set! (-> this progress-minimap) + (the-as + texture-page + (link (-> this tpage buf) (-> this tpage load-file data) (-> this tpage len) (-> this tpage heap) 4) + ) + ) + (set! (-> this progress-minimap2) + (the-as + texture-page + (link (-> this tpage2 buf) (-> this tpage2 load-file data) (-> this tpage2 len) (-> this tpage2 heap) 4) + ) + ) + (set! (-> *level* loading-level) s5-0) + (set! (-> *texture-pool* allocate-func) s4-0) + (set! (-> *texture-relocate-later* memcpy) s3-0) + (set! loading-level s2-0) + ) + (set! (-> this loading-flag) #f) + ) + ) + ) + ) + 0 + (none) + ) + +;; WARN: Return type mismatch texture-page vs symbol. +(defmethod loaded? ((this bigmap)) + (the-as symbol (and (-> *bigmap* progress-minimap) (-> *bigmap* progress-minimap2))) + ) + +(defmethod draw! ((this bigmap) (arg0 int) (arg1 int) (arg2 int) (arg3 int)) + (local-vars + (sv-96 (inline-array vector4w)) + (sv-100 texture) + (sv-104 matrix) + (sv-112 int) + (sv-120 float) + (sv-240 (function bigmap vector none)) + ) + (when (and (= (file-status (-> this bigmap-image) "world-map" (the-as int (-> this load-index))) 'active) + (not (-> this loading-flag)) + ) + (with-dma-buffer-add-bucket ((s2-0 (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id tex-hud-hud-alpha) + ) + (dma-buffer-add-gs-set s2-0 + (scissor-1 (new 'static 'gs-scissor + :scax0 (+ arg0 -1792) + :scay0 (+ arg1 -1840) + :scax1 (+ arg2 -1792) + :scay1 (+ arg3 -1840) + ) + ) + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + ) + (let ((v1-14 (the-as object (-> this bigmap-image art-group))) + (f0-0 (-> *video-params* relative-x-scale)) + ) + (set! (-> this scroll x) + (fmax 0.0 (fmin (-> this scroll x) (the float (+ (-> (the-as (pointer uint32) v1-14) 2) -513)))) + ) + (set! (-> this scroll y) + (fmax + 0.0 + (fmin (-> this scroll y) (+ (- -1.0 (* 416.0 f0-0)) (the float (-> (the-as (pointer uint32) v1-14) 3)))) + ) + ) + ) + (cond + ((get-horizontal-flip-flag *blit-displays-work*) + (set! (-> this x0) (+ arg2 -1792)) + (set! (-> this x1) (+ arg0 -1792)) + ) + (else + (set! (-> this x0) (+ arg0 -1792)) + (set! (-> this x1) (+ arg2 -1792)) + ) + ) + (set! (-> this y0) arg1) + (set! (-> this y1) arg3) + (bigmap-method-20 this s2-0) + (when (!= (-> this load-index) (bigmap-id none)) + (when (= (-> this y0) 1840) + (let ((s0-1 (-> s2-0 base)) + (s1-1 (lookup-texture-by-id-fast (new 'static 'texture-id :index #x4 :page #x11))) + ) + (when s1-1 + (set! (-> (the-as (pointer uint128) s0-1) 0) (-> this adgif-tmpl dma-vif quad)) + (set! (-> (the-as (pointer uint128) s0-1) 1) (-> this adgif-tmpl quad 1)) + (adgif-shader<-texture-simple! (the-as adgif-shader (&+ s0-1 32)) s1-1) + (&+! (-> s2-0 base) 112) + ) + (if (not s1-1) + (format 0 "ERROR: bigmap: mini-map-icons texture is #f~%") + ) + ) + (let ((s1-2 (-> *minimap* engine alive-list))) + (while s1-2 + (let ((a2-11 s1-2)) + (when (logtest? (-> a2-11 class flags) (minimap-flag bigmap bigmap-only)) + (if (not (and (logtest? (minimap-flag local-only) (-> a2-11 class flags)) + (not (logtest? (the-as minimap-flag (logand (bigmap-flag ctywide waswide wasall desert) (-> this global-flags))) + (-> a2-11 class flags) + ) + ) + ) + ) + (draw-from-minimap this s2-0 a2-11) + ) + ) + ) + (set! s1-2 (-> s1-2 next)) + ) + ) + (let ((s1-3 (new 'stack-no-clear 'vector)) + (f30-0 (-> *video-params* relative-x-scale)) + ) + (vector-z-quaternion! s1-3 (-> *target* control quat)) + (vector-xz-normalize! s1-3 -1.0) + (set! (-> s1-3 y) 0.0) + (set! (-> s1-3 w) 0.0) + (set! sv-96 (the-as (inline-array vector4w) (-> s2-0 base))) + (set! sv-100 (lookup-texture-by-id-fast (new 'static 'texture-id :index #x1 :page #x11))) + (set! sv-104 (new 'stack-no-clear 'matrix)) + (set! sv-112 (the int (* 56.0 f30-0))) + (set! sv-120 (-> *video-params* relative-x-scale-reciprical)) + (when sv-100 + (let ((s0-2 this)) + (set! sv-240 (method-of-object s0-2 set-pos!)) + (let ((a1-29 (target-pos 0))) + (sv-240 s0-2 a1-29) + ) + ) + (let ((s0-3 (new 'stack 'vector4w))) + 0.0 + (set! (-> s0-3 quad) (-> this pos quad)) + (bigmap-method-18 this (the-as (pointer int32) s0-3)) + (let ((f0-15 (cond + ((get-horizontal-flip-flag *blit-displays-work*) + (set! f30-0 (- f30-0)) + (+ (the float (+ (- 2304 (-> s0-3 x)) (-> this x1))) (-> this scroll x)) + ) + (else + (- (the float (+ (-> s0-3 x) 1792 (-> this x0))) (-> this scroll x)) + ) + ) + ) + ) + (set-vector! (-> sv-104 rvec) (* (-> s1-3 z) f30-0) 0.0 (- (-> s1-3 x)) 0.0) + (set-vector! (-> sv-104 uvec) 0.0 1.0 0.0 0.0) + (set-vector! (-> sv-104 fvec) (* (-> s1-3 x) f30-0) 0.0 (-> s1-3 z) 1.0) + (set-vector! + (-> sv-104 trans) + f0-15 + 0.0 + (+ 1840.0 (* (- (the float (-> s0-3 y)) (-> this scroll y)) sv-120)) + 1.0 + ) + ) + ) + (let* ((v1-83 (mod (-> *display* real-clock frame-counter) 360)) + (f0-26 (+ 1.5 (* 0.25 (cos (* 182.04445 (the float v1-83)))))) + (f0-27 (* 7.0 f0-26)) + ) + (cond + ((or (= (-> this load-index) (bigmap-id sewer-met-hum)) (= (-> this load-index) (bigmap-id sewer-hum-kg))) + (set-vector! (-> this corner 0) (- f0-27) 0.0 0.0 1.0) + (set-vector! (-> this corner 1) 0.0 0.0 f0-27 1.0) + (set-vector! (-> this corner 2) 0.0 0.0 (- f0-27) 1.0) + (set-vector! (-> this corner 3) f0-27 0.0 0.0 1.0) + ) + (else + (set-vector! (-> this corner 0) 0.0 0.0 (- f0-27) 1.0) + (set-vector! (-> this corner 1) f0-27 0.0 0.0 1.0) + (set-vector! (-> this corner 2) (- f0-27) 0.0 0.0 1.0) + (set-vector! (-> this corner 3) 0.0 0.0 f0-27 1.0) + ) + ) + ) + (vector-matrix*! (the-as vector (-> this corner)) (the-as vector (-> this corner)) sv-104) + (vector-matrix*! (-> this corner 1) (-> this corner 1) sv-104) + (vector-matrix*! (-> this corner 2) (-> this corner 2) sv-104) + (vector-matrix*! (-> this corner 3) (-> this corner 3) sv-104) + (let ((v1-97 (-> this adgif-tmpl dma-vif quad))) + (set! (-> sv-96 0 quad) v1-97) + ) + (let ((v1-98 (-> this adgif-tmpl quad 1))) + (set! (-> sv-96 1 quad) v1-98) + ) + (adgif-shader<-texture-simple! (the-as adgif-shader (-> sv-96 2)) sv-100) + (let ((v1-100 (-> this draw-tmpl dma-vif quad))) + (set! (-> sv-96 7 quad) v1-100) + ) + (let ((v1-101 (-> this draw-tmpl quad 1))) + (set! (-> sv-96 8 quad) v1-101) + ) + (set-vector! (-> sv-96 9) 0 255 255 128) + (set-vector! (-> sv-96 10) 0 0 0 0) + (set-vector! + (-> sv-96 11) + (the int (* 16.0 (-> this corner 0 x))) + (the int (* 16.0 (-> this corner 0 z))) + #xffffff + 0 + ) + (set-vector! (-> sv-96 12) 256 0 0 0) + (set-vector! + (-> sv-96 13) + (the int (* 16.0 (-> this corner 1 x))) + (the int (* 16.0 (-> this corner 1 z))) + #xffffff + 0 + ) + (set-vector! (-> sv-96 14) 0 256 0 0) + (set-vector! + (-> sv-96 15) + (the int (* 16.0 (-> this corner 2 x))) + (the int (* 16.0 (-> this corner 2 z))) + #xffffff + 0 + ) + (set-vector! (-> sv-96 16) 256 256 0 0) + (set-vector! + (-> sv-96 17) + (the int (* 16.0 (-> this corner 3 x))) + (the int (* 16.0 (-> this corner 3 z))) + #xffffff + 0 + ) + (&+! (-> s2-0 base) 288) + ) + ) + ) + ) + (dma-buffer-add-gs-set s2-0 (scissor-1 (new 'static 'gs-scissor :scax1 #x1ff :scay1 #x19f))) + ) + (when (= (-> this load-index) (bigmap-id none)) + (let ((s3-1 + (new 'stack 'font-context *font-default-matrix* 0 0 0.0 (font-color default) (font-flags shadow kerning)) + ) + ) + (let ((f30-2 (* 0.0024038462 (the float (- arg3 arg1))))) + (let ((v1-138 s3-1)) + (set! (-> v1-138 scale) f30-2) + ) + (let ((v1-139 s3-1)) + (set! (-> v1-139 width) (the float (the int (* 400.0 f30-2)))) + ) + (let ((a0-100 s3-1)) + (set! (-> a0-100 flags) (font-flags kerning middle large)) + ) + (let ((s5-1 print-game-text)) + (format (clear *temp-string*) "~S" (lookup-text! *common-text* (text-id map-data-unavailable) #f)) + (let* ((f0-63 (s5-1 *temp-string* s3-1 #t 44 (bucket-id hud-draw-hud-alpha))) + (v1-142 s3-1) + (a0-106 (- 256 (the int (* 200.0 f30-2)))) + (a1-52 (- 208 (the int (* 0.5 f0-63)))) + ) + (set! (-> v1-142 origin x) (the float a0-106)) + (set! (-> v1-142 origin y) (the float a1-52)) + ) + ) + ) + (let ((s5-2 print-game-text)) + (format (clear *temp-string*) "~S" (lookup-text! *common-text* (text-id map-data-unavailable) #f)) + (s5-2 *temp-string* s3-1 #f 44 (bucket-id hud-draw-hud-alpha)) + ) + ) + ) + (+! (-> this goal-time) (* 16.0 (seconds-per-frame))) + (set-dirty-mask! (-> *level* level-default) 4 #x1a400 0) + ) + 0 + (none) + ) + +(defmethod handle-cpad-input ((this bigmap)) + (let ((v1-1 (-> this bigmap-image art-group)) + (s5-0 (-> *cpad-list* cpads 0)) + ) + (when v1-1 + (let ((f30-0 (analog-input (the-as int (-> s5-0 leftx)) 128.0 32.0 110.0 4.0)) + (f0-0 (analog-input (the-as int (-> s5-0 lefty)) 128.0 32.0 110.0 4.0)) + ) + (+! (-> this scroll x) f30-0) + (+! (-> this scroll y) f0-0) + ) + ) + ) + 0 + (none) + ) + +(defmethod set-map-indices! ((this bigmap)) + (let ((s5-0 (level-get-target-inside *level*))) + (let ((v1-2 (-> *setting-control* user-current bigmap-level))) + (cond + (v1-2 + (cond + ((= v1-2 'city) + (set! (-> this bigmap-index) (bigmap-id city)) + 0 + ) + ((= v1-2 'comb) + (set! (-> this bigmap-index) (bigmap-id comb)) + ) + ((= v1-2 'desert) + (set! (-> this bigmap-index) (bigmap-id desert)) + ) + ((= v1-2 'factory) + (set! (-> this bigmap-index) (bigmap-id factory)) + ) + ((= v1-2 'forest) + (set! (-> this bigmap-index) (bigmap-id forest)) + ) + ((= v1-2 'metalhead-city) + (set! (-> this bigmap-index) (bigmap-id mhcity)) + ) + ((= v1-2 'mine) + (set! (-> this bigmap-index) (bigmap-id mine)) + ) + ((= v1-2 'nest) + (set! (-> this bigmap-index) (bigmap-id nest)) + ) + ((= v1-2 'nest2) + (set! (-> this bigmap-index) (bigmap-id nest2)) + ) + ((= v1-2 'none) + (set! (-> this bigmap-index) (bigmap-id none)) + ) + ((= v1-2 'precursor1) + (set! (-> this bigmap-index) (bigmap-id precursor1)) + ) + ((= v1-2 'precursor2) + (set! (-> this bigmap-index) (bigmap-id precursor2)) + ) + ((= v1-2 'rubble) + (set! (-> this bigmap-index) (bigmap-id rubble)) + ) + ((= v1-2 'sewer-hum-kg) + (set! (-> this bigmap-index) (bigmap-id sewer-hum-kg)) + ) + ((= v1-2 'sewer-kg-met) + (set! (-> this bigmap-index) (bigmap-id sewer-kg-met)) + ) + ((= v1-2 'sewer-met-hum) + (set! (-> this bigmap-index) (bigmap-id sewer-met-hum)) + ) + ((= v1-2 'stadium) + (set! (-> this bigmap-index) (bigmap-id stadium)) + ) + ((= v1-2 'temple1) + (set! (-> this bigmap-index) (bigmap-id temple1)) + ) + ((= v1-2 'temple2) + (set! (-> this bigmap-index) (bigmap-id temple2)) + ) + ((= v1-2 'temple3) + (set! (-> this bigmap-index) (bigmap-id temple3)) + ) + ((= v1-2 'temple4) + (set! (-> this bigmap-index) (bigmap-id temple4)) + ) + ((= v1-2 'tower) + (set! (-> this bigmap-index) (bigmap-id tower)) + ) + ((= v1-2 'volcano) + (set! (-> this bigmap-index) (bigmap-id volcano)) + ) + ((= v1-2 'wascity) + (set! (-> this bigmap-index) (bigmap-id wascity)) + ) + ) + ) + (s5-0 + (set! (-> this bigmap-index) (-> s5-0 info bigmap-id)) + ) + ) + ) + (if (and (= (status-of-level-and-borrows *level* 'ctywide #f) 'active) + (not (or (= (-> s5-0 name) 'mhcitya) (= (-> s5-0 name) 'mhcityb))) + ) + (set! (-> this bigmap-index) (-> ctyport bigmap-id)) + ) + ) + (cond + ((= (-> this bigmap-index) (bigmap-id temple1)) + (cond + ((task-node-closed? (game-task-node factory-boss-resolution)) + (set! (-> this load-index) (bigmap-id temple4)) + ) + ((task-node-closed? (game-task-node desert-oasis-defense-resolution)) + (set! (-> this load-index) (bigmap-id temple3)) + ) + ((task-node-closed? (game-task-node volcano-darkeco-resolution)) + (set! (-> this load-index) (bigmap-id temple2)) + ) + (else + (set! (-> this load-index) (bigmap-id temple1)) + ) + ) + ) + ((= (-> this bigmap-index) (bigmap-id precursor1)) + (if (task-node-closed? (game-task-node comb-wild-ride-resolution)) + (set! (-> this load-index) (bigmap-id precursor2)) + (set! (-> this load-index) (bigmap-id precursor1)) + ) + ) + ((= (-> this bigmap-index) (bigmap-id nest)) + (if (task-node-closed? (game-task-node nest-eggs-gas)) + (set! (-> this load-index) (bigmap-id nest2)) + (set! (-> this load-index) (bigmap-id nest)) + ) + ) + (else + (set! (-> this load-index) (-> this bigmap-index)) + ) + ) + (none) + ) + +;; WARN: Return type mismatch bigmap-flag vs none. +(defmethod enable-drawing ((this bigmap)) + (set-map-indices! this) + (set! (-> this offset quad) (-> *bigmap-info-array* data (-> this load-index) quad)) + (let ((s4-0 (target-pos 0)) + (s5-0 (-> this offset)) + ) + (cond + ((= (-> this load-index) (bigmap-id sewer-hum-kg)) + (let ((a0-10 (level-get *level* 'sewa))) + (if a0-10 + (set! (-> a0-10 info bigmap-id) (bigmap-id sewer-hum-kg)) + ) + ) + (set! (-> this scroll x) (+ -256.0 (* (- (-> s4-0 y) (-> s5-0 y)) (-> s5-0 w)))) + (set! (-> this scroll y) (- 624.0 (* (- (-> s4-0 x) (-> s5-0 x)) (-> s5-0 w)))) + ) + ((= (-> this load-index) (bigmap-id sewer-kg-met)) + (let ((a0-14 (level-get *level* 'sewa))) + (if a0-14 + (set! (-> a0-14 info bigmap-id) (bigmap-id sewer-kg-met)) + ) + ) + (set! (-> this scroll x) (+ -256.0 (* (- (-> s4-0 x) (-> s5-0 x)) (-> s5-0 w)))) + (set! (-> this scroll y) (+ -208.0 (* (- (-> s4-0 z) (-> s5-0 y)) (-> s5-0 w)))) + ) + ((= (-> this load-index) (bigmap-id sewer-met-hum)) + (let ((a0-18 (level-get *level* 'sewa))) + (if a0-18 + (set! (-> a0-18 info bigmap-id) (bigmap-id sewer-met-hum)) + ) + ) + (set! (-> this scroll x) (+ -256.0 (* (- (-> s4-0 y) (-> s5-0 y)) (-> s5-0 w)))) + (set! (-> this scroll y) (- 624.0 (* (- (-> s4-0 x) (-> s5-0 x)) (-> s5-0 w)))) + ) + (else + (set! (-> this scroll x) (+ -256.0 (* (- (-> s4-0 x) (-> s5-0 x)) (-> s5-0 w)))) + (set! (-> this scroll y) (+ -208.0 (* (- (-> s4-0 z) (-> s5-0 y)) (-> s5-0 w)))) + ) + ) + ) + (set! (-> this drawing-flag) #t) + (set! (-> this loading-flag) #f) + (set! (-> this global-flags) (bigmap-flag)) + (if (= (status-of-level-and-borrows *level* 'ctywide #f) 'active) + (logior! (-> this global-flags) (bigmap-flag ctywide)) + ) + (if (= (status-of-level-and-borrows *level* 'waswide #f) 'active) + (logior! (-> this global-flags) (bigmap-flag wasall)) + ) + (if (= (status-of-level-and-borrows *level* 'wasall #f) 'active) + (logior! (-> this global-flags) (bigmap-flag waswide)) + ) + (if (= (status-of-level-and-borrows *level* 'desert #f) 'active) + (logior! (-> this global-flags) (bigmap-flag desert)) + ) + (none) + ) + +(defmethod disable-drawing ((this bigmap)) + (set-pending-file + (-> this bigmap-image) + (the-as string #f) + (the-as int (-> this bigmap-index)) + (process->handle *dproc*) + 0.0 + ) + (set-pending-file (-> this tpage) (the-as string #f) 0 (process->handle *dproc*) 0.0) + (set-pending-file (-> this tpage2) (the-as string #f) 0 (process->handle *dproc*) 0.0) + (let ((v1-12 #f)) + (while (not v1-12) + (update (-> this bigmap-image)) + (update (-> this tpage)) + (update (-> this tpage2)) + (set! v1-12 (and (= (-> this bigmap-image status) 'inactive) + (= (-> this tpage status) 'inactive) + (= (-> this tpage2 status) 'inactive) + ) + ) + ) + ) + (when (-> this progress-minimap) + (unload-page *texture-pool* (-> this progress-minimap)) + (set! (-> (&-> *level* level-default texture-page 6) 0) (the-as texture-page 0)) + (set! (-> this progress-minimap) #f) + ) + (when (-> this progress-minimap2) + (unload-page *texture-pool* (-> this progress-minimap2)) + (set! (-> (&-> *level* level-default texture-page 3) 0) (the-as texture-page 0)) + (set! (-> this progress-minimap2) #f) + ) + (set! (-> this drawing-flag) #f) + (set! (-> this loading-flag) #f) + 0 + ) + +(kmemopen global "bigmap-struct") ;; og:preserve-this -(define-perm *bigmap* bigmap #f) +(define-perm *bigmap* bigmap (new 'global 'bigmap)) -(kmemclose) \ No newline at end of file +(kmemclose) diff --git a/goal_src/jak3/engine/ui/minimap.gc b/goal_src/jak3/engine/ui/minimap.gc index b9dcdd93bf..6da7ba236c 100644 --- a/goal_src/jak3/engine/ui/minimap.gc +++ b/goal_src/jak3/engine/ui/minimap.gc @@ -1884,8 +1884,7 @@ ) (while s3-0 (let ((s4-0 (-> s3-0 next))) - ;; og:preserve-this not-yet-implemented check - (when (or (and *bigmap* (bigmap-method-11 *bigmap*)) (not (paused?))) + (when (or (loaded? *bigmap*) (not (paused?))) (cond ((logtest? (-> s3-0 flags) (minimap-flag fade-out)) (logclear! (-> s3-0 flags) (minimap-flag fade-in)) diff --git a/goal_src/jak3/engine/ui/progress/progress-draw.gc b/goal_src/jak3/engine/ui/progress/progress-draw.gc index dc91c0aee2..f8bd50930e 100644 --- a/goal_src/jak3/engine/ui/progress/progress-draw.gc +++ b/goal_src/jak3/engine/ui/progress/progress-draw.gc @@ -154,14 +154,14 @@ (if (< (seconds 0.027) (logand (-> pp clock integral-frame-counter) 15)) (set-font-color (the-as font-color gp-0) - (the-as int (the-as uint #x80ffffff)) + (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) ) (set-font-color (the-as font-color gp-0) - (the-as int (the-as uint #x80606060)) + (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) @@ -279,7 +279,8 @@ (defmethod progress-method-41 ((this progress) (arg0 progress-box) (arg1 float)) (with-dma-buffer-add-bucket ((s4-0 (-> *display* frames (-> *display* on-screen) global-buf)) - (bucket-id particles) + ;; og:preserve-this changed from particles bucket + (bucket-id hud-draw-hud-alpha) ) (case (get-aspect-ratio) (('aspect4x3) @@ -317,7 +318,8 @@ (defmethod progress-method-43 ((this progress) (arg0 progress-box) (arg1 float)) (with-dma-buffer-add-bucket ((s4-0 (-> *display* frames (-> *display* on-screen) global-buf)) - (bucket-id bucket6) + ;; og:preserve-this changed from bucket6 + (bucket-id tex-hud-hud-alpha) ) (case (get-aspect-ratio) (('aspect4x3) @@ -1744,7 +1746,8 @@ (set! (-> s1-1 box max y) (+ (-> s1-1 box min y) f30-1)) (set-vector! (-> s1-1 color) 192 192 96 (the int (* 128.0 s3-0))) (with-dma-buffer-add-bucket ((s2-1 (-> *display* frames (-> *display* on-screen) global-buf)) - (bucket-id particles) + ;; og:preserve-this changed from particles bucket + (bucket-id hud-draw-hud-alpha) ) (set! (-> s1-1 box min x) arg2) (set! (-> s1-1 box max x) arg3) @@ -2437,7 +2440,7 @@ (let ((f30-0 (fmax 0.0 (* 2.0 (- 0.5 (-> arg0 menu-transition)))))) (set! (-> arg1 alpha) f30-0) (cond - ((not (bigmap-method-11 *bigmap*)) + ((not (loaded? *bigmap*)) (progress-method-51 arg0 arg1) ) (else @@ -2474,7 +2477,7 @@ (set! (-> a0-2 flags) (font-flags kerning middle large)) ) (cond - ((not (bigmap-method-11 *bigmap*)) + ((not (loaded? *bigmap*)) (progress-method-51 arg0 arg1) ) ((begin @@ -2569,7 +2572,7 @@ (set! (-> arg1 alpha) f30-0) (progress-method-33 arg0 (-> *progress-work* body)) (cond - ((not (bigmap-method-11 *bigmap*)) + ((not (loaded? *bigmap*)) (progress-method-51 arg0 arg1) ) (else @@ -2755,7 +2758,7 @@ (f24-0 (-> *video-params* relative-x-scale)) ) (cond - ((not (bigmap-method-11 *bigmap*)) + ((not (loaded? *bigmap*)) (progress-method-51 arg0 arg1) ) (else @@ -4624,7 +4627,7 @@ (set! sv-24 (the int (-> *game-info* skill))) (set! (-> arg1 alpha) sv-16) (cond - ((not (bigmap-method-11 *bigmap*)) + ((not (loaded? *bigmap*)) (progress-method-51 arg0 arg1) ) (else diff --git a/goal_src/jak3/engine/ui/progress/progress.gc b/goal_src/jak3/engine/ui/progress/progress.gc index c5ccf5dba1..30fbb3bb2d 100644 --- a/goal_src/jak3/engine/ui/progress/progress.gc +++ b/goal_src/jak3/engine/ui/progress/progress.gc @@ -453,9 +453,7 @@ (process-spawn hud-ring-cell 11 (* -1.0 f30-0) 9 :name "hud-ring-cell" :to self) ) (clear *stdcon1*) - (if *bigmap* - (enable-drawing *bigmap*) - ) + (enable-drawing *bigmap*) (set-setting! 'scanlines 'abs 0.0 0) (go-virtual come-in) ) @@ -504,8 +502,7 @@ "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." (set! (-> *progress-work* hero-mode-save) #f) (remove-setting-by-arg0 *setting-control* 'extra-bank) - ;; og:preserve-this not-yet-implemented check - (if *bigmap* (disable-drawing *bigmap*)) + (disable-drawing *bigmap*) (set-menu-mode *blit-displays-work* #f) (set! *progress-process* (the-as (pointer progress) #f)) (enable-level-text-file-loading) @@ -1509,13 +1506,7 @@ (progress-method-33 self (-> *progress-work* full-screen)) (cond ((>= (-> self pos-transition) 0.38) - (let ((t9-15 (method-of-object *bigmap* bigmap-method-12))) - 1792 - 1840 - 2304 - 2256 - (t9-15) - ) + (draw! *bigmap* 1792 1840 2304 2256) ) (else (let ((s4-1 (vector<-cspace! (new 'stack-no-clear 'vector) (-> self node-list data 21))) @@ -1525,15 +1516,9 @@ (set! (-> gp-1 quad) (the-as uint128 0)) (let ((s5-2 (new 'stack-no-clear 'vector4w))) (set! (-> s5-2 quad) (the-as uint128 0)) - (when (and (transform-point-qword! gp-1 s4-1) (transform-point-qword! s5-2 s3-1)) - (let ((t9-20 (method-of-object *bigmap* bigmap-method-12))) - (/ (-> s5-2 x) 16) - (/ (-> s5-2 y) 16) - (/ (-> gp-1 x) 16) - (/ (-> gp-1 y) 16) - (t9-20) + (if (and (transform-point-qword! gp-1 s4-1) (transform-point-qword! s5-2 s3-1)) + (draw! *bigmap* (/ (-> s5-2 x) 16) (/ (-> s5-2 y) 16) (/ (-> gp-1 x) 16) (/ (-> gp-1 y) 16)) ) - ) ) ) ) @@ -1602,64 +1587,64 @@ (let ((t9-0 format) (a0-3 #t) (a1-1 "DONE NOTIFY: ~S ~S~%") - (v1-3 (-> block param 1)) + (v1-3 (the-as mc-status-code (-> block param 1))) ) (t9-0 a0-3 a1-1 (cond - ((= v1-3 15) + ((= v1-3 (mc-status-code bad-version)) "bad-version" ) - ((= v1-3 13) + ((= v1-3 (mc-status-code no-save)) "no-save" ) - ((= v1-3 10) + ((= v1-3 (mc-status-code no-last)) "no-last" ) - ((= v1-3 14) + ((= v1-3 (mc-status-code no-space)) "no-space" ) - ((= v1-3 4) + ((= v1-3 (mc-status-code internal-error)) "internal-error" ) - ((= v1-3 8) + ((= v1-3 (mc-status-code no-memory)) "no-memory" ) - ((= v1-3 2) + ((= v1-3 (mc-status-code bad-handle)) "bad-handle" ) - ((zero? v1-3) + ((= v1-3 (mc-status-code busy)) "busy" ) - ((= v1-3 5) + ((= v1-3 (mc-status-code write-error)) "write-error" ) - ((= v1-3 6) + ((= v1-3 (mc-status-code read-error)) "read-error" ) - ((= v1-3 9) + ((= v1-3 (mc-status-code no-card)) "no-card" ) - ((= v1-3 11) + ((= v1-3 (mc-status-code no-format)) "no-format" ) - ((= v1-3 1) + ((= v1-3 (mc-status-code ok)) "ok" ) - ((= v1-3 16) + ((= v1-3 (mc-status-code no-process)) "no-process" ) - ((= v1-3 17) + ((= v1-3 (mc-status-code no-auto-save)) "no-auto-save" ) - ((= v1-3 12) + ((= v1-3 (mc-status-code no-file)) "no-file" ) - ((= v1-3 3) + ((= v1-3 (mc-status-code format-failed)) "format-failed" ) - ((= v1-3 7) + ((= v1-3 (mc-status-code new-game)) "new-game" ) (else @@ -1669,7 +1654,8 @@ (-> self current) ) ) - (case (-> self current) + ;; og:preserve-this patched to next instead of current because we save synchronously + (case (-> self next) (('saving) (cond ((= (-> self state-array 0) 'title) @@ -1862,8 +1848,7 @@ (defstate gone (progress) :virtual #t :code (behavior () - ;; og:preserve-this not-yet-implemented check - (if *bigmap* (disable-drawing *bigmap*)) + (disable-drawing *bigmap*) (set-menu-mode *blit-displays-work* #f) (while (or (-> *blit-displays-work* screen-copied) (nonzero? (-> *blit-displays-work* count-down))) (suspend) @@ -1882,7 +1867,7 @@ (defmethod respond-progress ((this menu-slider-option) (arg0 progress) (arg1 symbol)) (with-pp - (when (bigmap-method-11 *bigmap*) + (when (loaded? *bigmap*) (let ((s5-0 (&+ (the-as (pointer float) *setting-control*) (-> this setting-offset))) (s3-0 #f) ) @@ -1938,7 +1923,7 @@ ) (defmethod respond-progress ((this menu-stereo-mode-sound-option) (arg0 progress) (arg1 symbol)) - (when (bigmap-method-11 *bigmap*) + (when (loaded? *bigmap*) (let ((a0-2 (-> *setting-control* user-default stereo-mode)) (v1-4 #f) ) @@ -2215,7 +2200,7 @@ (set-next-state arg0 a1-3 0) ) (set! (-> arg0 selected-option) #f) - (when (bigmap-method-11 *bigmap*) + (when (loaded? *bigmap*) (cond ((cpad-pressed? 0 triangle) ) @@ -3009,7 +2994,7 @@ ) (defmethod respond-progress ((this menu-bigmap-option) (arg0 progress) (arg1 symbol)) - ((method-of-object *bigmap* bigmap-method-13)) + (handle-cpad-input *bigmap*) (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons confirm)) (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons confirm)) 0 @@ -4049,10 +4034,7 @@ process (lambda :behavior process ((arg0 int)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 2.5)) - (suspend) - ) + (suspend-for (seconds 2.5) ) (while (or (not (handle-command-list *gui-control* (gui-channel alert) (the-as gui-connection #f))) (= (status-of-level-and-borrows *level* 'title #f) 'active) diff --git a/goal_src/jak3/engine/ui/text-h.gc b/goal_src/jak3/engine/ui/text-h.gc index 8e801887fc..0fd42bdf54 100644 --- a/goal_src/jak3/engine/ui/text-h.gc +++ b/goal_src/jak3/engine/ui/text-h.gc @@ -1383,3 +1383,18 @@ (define *common-text-heap* (new 'global 'kheap)) (define *common-text* (the-as game-text-info #f)) + +;; og:preserve-this +;; NOTE - PC PORT difference +;; Partial translations are a thing that we should support. Parts of translating the game are intentionally made +;; difficult for normal translators due to not wanting to make all the strings public (or in the case of subtitles, +;; we straight up didn't have them yet) +;; +;; So to remedy this, we always load the english text as a fallback so that if there is only a partial translation +;; the UX won't be horrible with everything displaying as UNKNOWN. +;; +;; One of the reasons we didn't do this is because it makes it obvious which strings are remaining, +;; but there are better ways to keep track or check if strings are missing. +(#when PC_PORT + (kheap-alloc (define *fallback-text-heap* (new 'global 'kheap)) (* 80 1024)) + (define *fallback-text* (the game-text-info #f))) \ No newline at end of file diff --git a/goal_src/jak3/engine/ui/text.gc b/goal_src/jak3/engine/ui/text.gc index ef9cdc0464..3486743541 100644 --- a/goal_src/jak3/engine/ui/text.gc +++ b/goal_src/jak3/engine/ui/text.gc @@ -194,8 +194,13 @@ (the-as string #f) ) (else - (format (clear *temp-string*) "UNKNOWN ID ~X" arg0) - *temp-string* + ;; og:preserve-this Added fallback to English if string is not found. + (#if PC_PORT + (if *fallback-text-lookup?* + (aif (lookup-text! *fallback-text* arg0 #t) + it + (string-format "UNKNOWN ID ~D" arg0))) + (string-format "UNKNOWN ID ~D" arg0)) ) ) ) @@ -301,12 +306,14 @@ ) (defun load-level-text-files ((arg0 int)) - (if (or *level-text-file-load-flag* (>= arg0 0)) - (load-game-text-info "common" (&-> '*common-text* value) *common-text-heap*) - ) - 0 - (none) - ) + ;; og:preserve-this Load in English file to use as a fallback + (when (or *level-text-file-load-flag* (>= arg0 0)) + (load-game-text-info "common" (&-> '*common-text* value) *common-text-heap*) + (#when PC_PORT + (protect ((-> *setting-control* user-current language)) + (set! (-> *setting-control* user-current language) (language-enum english)) + (load-game-text-info "common" (&-> '*fallback-text* value) *fallback-text-heap*)))) + (none)) (defun draw-debug-text-box ((arg0 font-context)) (when *cheat-mode* diff --git a/goal_src/jak3/game.gp b/goal_src/jak3/game.gp index 766c047422..419f186bd5 100644 --- a/goal_src/jak3/game.gp +++ b/goal_src/jak3/game.gp @@ -105,10 +105,10 @@ (cgo-file "wasseem.gd" common-dep) (cgo-file "wca.gd" common-dep) (cgo-file "wcb.gd" common-dep) -(cgo-file "wasleapr.gd" common-dep) (cgo-file "wcaseem.gd" common-dep) (cgo-file "wascast.gd" common-dep) (cgo-file "cwi.gd" common-dep) ;; ctywide +(cgo-file "wasleapr.gd" common-dep) (cgo-file "wasall.gd" common-dep) (cgo-file "desresc.gd" common-dep) (cgo-file "wsd.gd" common-dep) ;; wasdoors (garage) @@ -272,7 +272,7 @@ (cgo-file "preca.gd" common-dep) (cgo-file "precb.gd" common-dep) (cgo-file "precc.gd" common-dep) -; (cgo-file "precd.gd" common-dep) +(cgo-file "precd.gd" common-dep) ; ;; title/intro (cgo-file "win.gd" common-dep) ;; wasintro (cgo-file "title.gd" common-dep) @@ -513,7 +513,7 @@ (defstep :in "game/assets/jak3/game_subtitle.gp" :tool 'subtitle-v2 - :out '("$OUT/iso/0SUBTI2.TXT") + :out '("$OUT/iso/0SUBTI3.TXT") ) ;;;;;;;;;;;;;;;;;;;;; @@ -530,7 +530,7 @@ "$OUT/iso/5COMMON.TXT" "$OUT/iso/6COMMON.TXT" "$OUT/iso/7COMMON.TXT" - "$OUT/iso/0SUBTI2.TXT" + "$OUT/iso/0SUBTI3.TXT" "$OUT/iso/VAGDIR.AYB" "$OUT/iso/TWEAKVAL.MUS" ,@(reverse *all-vis*) @@ -549,7 +549,7 @@ "$OUT/iso/5COMMON.TXT" "$OUT/iso/6COMMON.TXT" "$OUT/iso/7COMMON.TXT" - "$OUT/iso/0SUBTI2.TXT" + "$OUT/iso/0SUBTI3.TXT" ) ) @@ -560,7 +560,7 @@ (group "engine" "$OUT/iso/0COMMON.TXT" - "$OUT/iso/0SUBTI2.TXT" + "$OUT/iso/0SUBTI3.TXT" "$OUT/iso/KERNEL.CGO" "$OUT/iso/GAME.CGO" "$OUT/iso/VAGDIR.AYB" diff --git a/goal_src/jak3/kernel-defs.gc b/goal_src/jak3/kernel-defs.gc index 3b9e958ef8..abdd19e082 100644 --- a/goal_src/jak3/kernel-defs.gc +++ b/goal_src/jak3/kernel-defs.gc @@ -210,8 +210,8 @@ (define-extern pc-get-display-id (function int)) (define-extern pc-set-display-id! (function int none)) (define-extern pc-set-display-mode! (function symbol none)) -(define-extern pc-get-num-resolutions (function int)) -(define-extern pc-get-resolution (function int (pointer int64) (pointer int64) none)) +(define-extern pc-get-num-resolutions (function symbol int)) +(define-extern pc-get-resolution (function int symbol (pointer int64) (pointer int64) none)) (define-extern pc-is-supported-resolution? (function int int symbol)) (define-extern pc-set-frame-rate (function int none)) @@ -226,6 +226,17 @@ (declare-type discord-info structure) (define-extern pc-discord-rpc-update (function discord-info none)) (define-extern pc-discord-rpc-set (function int none)) + +;;main music start +(define-extern play-main-music (function string int none)) +(define-extern pause-main-music (function none)) +(define-extern stop-main-music (function none)) +(define-extern resume-main-music (function none)) +(define-extern main-music-volume (function int none)) +;;main music end +(define-extern play-sound-file (function string int symbol)) +(define-extern stop-sound-file (function string none)) +(define-extern stop-all-sounds (function none)) (define-extern pc-init-autosplitter-struct (function none)) (define-extern pc-filepath-exists? (function string symbol)) (define-extern pc-mkdir-file-path (function string none)) @@ -249,6 +260,7 @@ ;; Jak 3 Specific Kernel Definitions (define *pc-waiting-on-rpc?* symbol) (define *pc-rpc-error?* symbol) + (define-extern pc-get-last-rpc-error (function string none)) (define-extern pc-fetch-external-race-times (function string none)) (define-extern pc-fetch-external-speedrun-times (function string none)) @@ -260,6 +272,27 @@ (define-extern pc-get-num-external-speedrun-times (function string int)) (define-extern pc-get-num-external-highscores (function string int)) +;; Speedrunner Mode Stuff +(define-extern pc-sr-mode-get-practice-entries-amount (function int)) +(define-extern pc-sr-mode-get-practice-entry-name (function int string none)) +(define-extern pc-sr-mode-get-practice-entry-continue-point (function int string none)) +(define-extern pc-sr-mode-get-practice-entry-history-success (function int int)) +(define-extern pc-sr-mode-get-practice-entry-history-attempts (function int int)) +(define-extern pc-sr-mode-get-practice-entry-session-success (function int int)) +(define-extern pc-sr-mode-get-practice-entry-session-attempts (function int int)) +(define-extern pc-sr-mode-get-practice-entry-avg-time (function int string none)) +(define-extern pc-sr-mode-get-practice-entry-fastest-time (function int string none)) +(define-extern pc-sr-mode-record-practice-entry-attempt! (function int symbol (pointer float) symbol)) +(declare-type speedrun-practice-objective structure) +(define-extern pc-sr-mode-init-practice-info! (function int speedrun-practice-objective none)) +;; TODO - a menu to dump out the 3 numbers with a pre-generated name to the file +(define-extern pc-sr-mode-get-custom-category-amount (function int)) +(define-extern pc-sr-mode-get-custom-category-name (function int string none)) +(define-extern pc-sr-mode-get-custom-category-continue-point (function int string none)) +(declare-type speedrun-custom-category structure) +(define-extern pc-sr-mode-init-custom-category-info! (function int speedrun-custom-category none)) +(define-extern pc-sr-mode-dump-new-custom-category (function speedrun-custom-category none)) + (define-extern file-stream-open (function file-stream string symbol file-stream)) (define-extern file-stream-close (function file-stream file-stream)) (define-extern file-stream-length (function file-stream int)) diff --git a/goal_src/jak3/kernel/gkernel-h.gc b/goal_src/jak3/kernel/gkernel-h.gc index b097fa93bb..45e2f85ec1 100644 --- a/goal_src/jak3/kernel/gkernel-h.gc +++ b/goal_src/jak3/kernel/gkernel-h.gc @@ -688,4 +688,7 @@ (defmacro time-elapsed? (time duration) `(>= (- (current-time) ,time) ,duration) - ) \ No newline at end of file + ) + +(defmacro suspend-for (time &rest body) + `(let ((time (current-time))) (until (time-elapsed? time ,time) ,@body (suspend)))) \ No newline at end of file diff --git a/goal_src/jak3/kernel/gkernel.gc b/goal_src/jak3/kernel/gkernel.gc index 9b0b23985d..54ddcbf62c 100644 --- a/goal_src/jak3/kernel/gkernel.gc +++ b/goal_src/jak3/kernel/gkernel.gc @@ -2370,6 +2370,11 @@ (change-parent (define *display-pool* (new 'global 'process-tree "display-pool")) *active-pool*) +;; og:preserve-this added pc pool +(#when PC_PORT +(change-parent (define *pc-pool* (new 'global 'process-tree "pc-pool")) *active-pool*) +(set! (-> *pc-pool* mask) (process-mask freeze pause menu progress process-tree))) + (change-parent (define *camera-pool* (new 'global 'process-tree "camera-pool")) *active-pool*) (set! (-> *camera-pool* mask) (process-mask freeze pause menu progress process-tree camera)) diff --git a/goal_src/jak3/kernel/gstate.gc b/goal_src/jak3/kernel/gstate.gc index 8c1feaa580..50d5ec6e55 100644 --- a/goal_src/jak3/kernel/gstate.gc +++ b/goal_src/jak3/kernel/gstate.gc @@ -41,11 +41,10 @@ &rest args) "Start a new process and run an init function on it. Returns a pointer to the new process, or #f (or is it 0?) if something goes wrong." - (with-gensyms (new-proc) `(let ((,new-proc (the-as ,(if runtime 'process proc-type) (get-process ,from ,proc-type ,stack-size ,unk)))) (when ,new-proc - ((method-of-type ,(if runtime 'process proc-type) activate) ,new-proc ,to ,(if name name `(symbol->string ,proc-type)) ,stack) + ((method-of-type ,(if runtime 'process proc-type) activate) ,new-proc ,to ,(if name name `(symbol->string ',proc-type)) ,stack) (run-now-in-process ,new-proc ,(if init init (string->symbol (fmt #f "{}-init-by-other" proc-type))) ,@args) (the (pointer ,(if runtime 'process proc-type)) (-> ,new-proc ppointer)) ) @@ -235,6 +234,12 @@ ) ) +(defmacro call-parent-state-handler (handler &key (type (function none)) &rest args) + "Call the parent handler for this state." + `(let ((handler (-> (find-parent-state) ,handler))) + (if handler ((the ,type handler) ,@args)) + ) + ) (defmacro behavior (bindings &rest body) "Define an anonymous behavior for a process state. This may only be used inside a defstate!" diff --git a/goal_src/jak3/kernel/gstring.gc b/goal_src/jak3/kernel/gstring.gc index af70c6fba2..bf352582fe 100644 --- a/goal_src/jak3/kernel/gstring.gc +++ b/goal_src/jak3/kernel/gstring.gc @@ -815,8 +815,18 @@ (define *temp-string* (new 'global 'string 2048 (the-as string #f))) +;; og:preserve-this +(define *temp-string2* (new 'global 'string 2048 (the string #f))) + +(defconstant EMPTY_STRING "") + (#when PC_PORT (define *pc-encoded-temp-string* (new 'global 'string 2048 (the-as string #f)))) +(#when PC_PORT + (define *pc-cpp-temp-string* + "A convenient place to retrieve a string from C++" + (new 'global 'string 2048 (the string #f)))) + (kmemclose) (defmacro string-format (&rest args) diff --git a/goal_src/jak3/levels/city/blow-tower/blow-tower-obs.gc b/goal_src/jak3/levels/city/blow-tower/blow-tower-obs.gc index 194eeb87d2..f96c9260c1 100644 --- a/goal_src/jak3/levels/city/blow-tower/blow-tower-obs.gc +++ b/goal_src/jak3/levels/city/blow-tower/blow-tower-obs.gc @@ -1514,11 +1514,7 @@ (part-tracker-spawn part-tracker :to *entity-pool* :group (-> *part-group-id-table* 1460)) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) (let ((v1-46 (-> self root root-prim))) (set! (-> v1-46 prim-core collide-as) (collide-spec)) (set! (-> v1-46 prim-core collide-with) (collide-spec)) @@ -1879,11 +1875,7 @@ :code (behavior () (until #f (attempt-barrel-spawn) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.3)) - (suspend) - ) - ) + (suspend-for (seconds 0.3)) ) #f ) diff --git a/goal_src/jak3/levels/city/blow-tower/blow-tower-obs2.gc b/goal_src/jak3/levels/city/blow-tower/blow-tower-obs2.gc index c72446819d..c6032d6111 100644 --- a/goal_src/jak3/levels/city/blow-tower/blow-tower-obs2.gc +++ b/goal_src/jak3/levels/city/blow-tower/blow-tower-obs2.gc @@ -366,11 +366,7 @@ (defbehavior bt-roboguard-turret-code bt-roboguard () (ja-channel-push! 1 (seconds 0.2)) (ja-no-eval :group! bt-roboguard-idle-shoot0-loop-ja :num! zero) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (let ((gp-1 (lambda ((arg0 bt-roboguard) (arg1 symbol)) (quaternion-rotate-y! (-> arg0 root quat) (-> arg0 root quat) (* 20480.0 (seconds-per-frame) (if arg1 @@ -385,11 +381,7 @@ ) (until #f (when (< (fabs (-> self me-to-focus-angle)) f30-0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (while (< (fabs (-> self me-to-focus-angle)) f30-0) (suspend) ) @@ -410,11 +402,7 @@ ) ) (when (< (fabs (-> self me-to-focus-angle)) f30-0) - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (while (< (fabs (-> self me-to-focus-angle)) f30-0) (suspend) ) @@ -783,11 +771,7 @@ (defstate hovering (bt-mh-flyer) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (bt-mh-flyer-method-51 self) ) :code (behavior () @@ -818,11 +802,7 @@ (bt-mh-flyer-flight-code) ) :post (behavior () - (let ((t9-1 (-> (find-parent-state) post))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler post) (bt-mh-flyer-method-52 self) ) ) @@ -831,11 +811,7 @@ :virtual #t :trans (behavior () (sound-play "charge-loop" :id (-> self charge-sound) :position (-> self root trans)) - (let ((t9-2 (-> (find-parent-state) trans))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler trans) ) ) @@ -843,20 +819,12 @@ :virtual #t :trans (behavior () (sound-play "charge-loop" :id (-> self charge-sound) :position (-> self root trans)) - (let ((t9-2 (-> (find-parent-state) trans))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler trans) (bt-mh-flyer-method-51 self) ) :code bt-mh-flyer-flight-code :post (behavior () - (let ((t9-1 (-> (find-parent-state) post))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler post) (bt-mh-flyer-method-52 self) ) ) @@ -864,20 +832,12 @@ (defstate fleeing (bt-mh-flyer) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (bt-mh-flyer-method-51 self) ) :code bt-mh-flyer-flight-code :post (behavior () - (let ((t9-1 (-> (find-parent-state) post))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler post) (bt-mh-flyer-method-52 self) ) ) @@ -885,11 +845,7 @@ (defstate firing (bt-mh-flyer) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (bt-mh-flyer-method-51 self) ) :code (behavior () @@ -903,11 +859,7 @@ (bt-mh-flyer-flight-code) ) :post (behavior () - (let ((t9-1 (-> (find-parent-state) post))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler post) (bt-mh-flyer-method-52 self) ) ) @@ -916,11 +868,7 @@ :virtual #t :enter (behavior () (sound-play "charge-fire") - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) ) @@ -2194,11 +2142,7 @@ (defstate dormant (bt-grunt) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self root trans quad) (-> self start-pos quad)) (set! (-> self entity extra vis-dist) 819200.0) ) @@ -2234,11 +2178,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.3)) - (suspend) - ) - ) + (suspend-for (seconds 0.3)) (until #f (suspend) (when (ragdoll-settled? self) @@ -2246,17 +2186,9 @@ (logior! (-> self skel effect flags) (effect-control-flag ecf1)) ) (do-effect (-> self skel effect) "death-default" 0.0 -1) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.3)) - (suspend) - ) - ) + (suspend-for (seconds 0.3)) (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.8)) - (suspend) - ) - ) + (suspend-for (seconds 0.8)) (go-virtual dormant) ) ) @@ -3042,11 +2974,7 @@ :virtual #t :enter (behavior () (set! (-> self hit-points) 10.0) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) ) diff --git a/goal_src/jak3/levels/city/blow-tower/cty-blow-tower.gc b/goal_src/jak3/levels/city/blow-tower/cty-blow-tower.gc index 9ea4cca237..e494f2fa97 100644 --- a/goal_src/jak3/levels/city/blow-tower/cty-blow-tower.gc +++ b/goal_src/jak3/levels/city/blow-tower/cty-blow-tower.gc @@ -4588,11 +4588,7 @@ (defstate die (bt-pickup) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (dotimes (gp-0 2) (send-event (handle->process (-> self pickup-barrels gp-0)) 'die) ) diff --git a/goal_src/jak3/levels/city/common/mh-squad-member.gc b/goal_src/jak3/levels/city/common/mh-squad-member.gc index 4428e34d96..18d894ccb0 100644 --- a/goal_src/jak3/levels/city/common/mh-squad-member.gc +++ b/goal_src/jak3/levels/city/common/mh-squad-member.gc @@ -280,10 +280,6 @@ ) ) ) - (let ((t9-3 (-> (find-parent-state) trans))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler trans) ) ) diff --git a/goal_src/jak3/levels/city/ctywide-obs.gc b/goal_src/jak3/levels/city/ctywide-obs.gc index ab331cec3c..8e335bebf2 100644 --- a/goal_src/jak3/levels/city/ctywide-obs.gc +++ b/goal_src/jak3/levels/city/ctywide-obs.gc @@ -2456,11 +2456,9 @@ ) (send-event *camera* 'teleport-to-transformq s4-0) ) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 3)) - (set! (-> *camera* slave 0 fov) (-> *city-burning-bush-get-on-info* (-> self info index) fov)) - (suspend) - ) + (suspend-for + (seconds 3) + (set! (-> *camera* slave 0 fov) (-> *city-burning-bush-get-on-info* (-> self info index) fov)) ) (set! (-> *camera-combiner* trans quad) (-> s5-0 quad)) (let ((a2-15 (-> *camera-combiner* inv-camera-rot)) diff --git a/goal_src/jak3/levels/city/ctywide-tasks.gc b/goal_src/jak3/levels/city/ctywide-tasks.gc index 135da9d8b3..a6b9f22fa9 100644 --- a/goal_src/jak3/levels/city/ctywide-tasks.gc +++ b/goal_src/jak3/levels/city/ctywide-tasks.gc @@ -50,11 +50,7 @@ (talker-spawn-func (-> *talker-speech* 26) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self speech-id)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while (or (not *target*) (focus-test? *target* dead teleporting)) (suspend) ) @@ -62,11 +58,7 @@ (talker-spawn-func (-> *talker-speech* 27) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self speech-id)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while (or (not *target*) (focus-test? *target* dead teleporting)) (suspend) ) @@ -87,17 +79,9 @@ ) (wait-for-speech-end (-> self speech-id)) (set! (-> self player-vehicle) (the-as handle #f)) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event self 'complete) - (let ((t9-14 (-> (find-parent-state) code))) - (if t9-14 - ((the-as (function none) t9-14)) - ) - ) + (call-parent-state-handler code) ) ) @@ -106,11 +90,7 @@ :code (behavior ((arg0 resetter-params)) (task-node-close! (game-task-node city-vehicle-training-hover-zone-1) 'event) (sleep-code) - (let ((t9-3 (-> (find-parent-state) code))) - (if t9-3 - ((the-as (function none) t9-3)) - ) - ) + (call-parent-state-handler code) ) ) @@ -118,11 +98,7 @@ :virtual #t :code (behavior () (task-node-close! (game-task-node city-vehicle-training-hover-zone-2) 'event) - (let ((t9-2 (-> (find-parent-state) code))) - (if t9-2 - ((the-as (function none) t9-2)) - ) - ) + (call-parent-state-handler code) ) ) @@ -168,11 +144,7 @@ (talker-spawn-func (-> *talker-speech* 27) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self speech-id)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (set! (-> self speech-id) (talker-spawn-func (-> *talker-speech* 28) *entity-pool* (target-pos 0) (the-as region #f)) ) @@ -191,11 +163,7 @@ (talker-spawn-func (-> *talker-speech* 29) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self speech-id)) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) (go-virtual complete) ) ) @@ -211,11 +179,7 @@ ((-> (method-of-object self wait) trans)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 5)) - (suspend) - ) - ) + (suspend-for (seconds 5)) (until (< 327680.0 (vector-vector-xz-distance (target-pos 0) (new 'static 'vector :x -285696.0 :y 36044.8 :z 5443625.0 :w 1.0)) ) @@ -223,11 +187,7 @@ ) (set-setting! 'airlock-command '(("hip-door-a-6" close)) 0.0 0) (talker-spawn-func (-> *talker-speech* 162) *entity-pool* (target-pos 0) (the-as region #f)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 5)) - (suspend) - ) - ) + (suspend-for (seconds 5)) (until (handle-command-list *gui-control* (gui-channel voicebox) (the-as gui-connection #f)) (suspend) ) diff --git a/goal_src/jak3/levels/city/destroy-grid/cty-destroy-grid.gc b/goal_src/jak3/levels/city/destroy-grid/cty-destroy-grid.gc index 6fbfb41c86..53d078c39a 100644 --- a/goal_src/jak3/levels/city/destroy-grid/cty-destroy-grid.gc +++ b/goal_src/jak3/levels/city/destroy-grid/cty-destroy-grid.gc @@ -392,11 +392,7 @@ ) ) ) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) :exit #f :trans (behavior () @@ -465,11 +461,7 @@ (put-rider-in-seat gp-0 (-> self seat) self) ) ) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () (let ((gp-0 (new 'stack-no-clear 'vector))) @@ -1618,11 +1610,7 @@ :virtual #t :enter (behavior () (logior! (-> self jinx-flags) (jinx-flag j0)) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) :code (behavior () (until (process-grab? *target* #f) @@ -1657,11 +1645,7 @@ ) :post (behavior () (move-cam-to-jinx self) - (let ((t9-2 (-> (find-parent-state) post))) - (if t9-2 - ((the-as (function none) t9-2)) - ) - ) + (call-parent-state-handler post) ) ) @@ -1910,11 +1894,7 @@ ) (suspend) ) - (let ((t9-4 (-> (find-parent-state) code))) - (if t9-4 - ((the-as (function none) t9-4)) - ) - ) + (call-parent-state-handler code) ) ) @@ -2141,11 +2121,7 @@ (process-entity-status! self (entity-perm-status dead) #t) (sound-play "bomb-set") (set! (-> self sound-id) (sound-play "time-tick-loop")) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 5)) - (suspend) - ) - ) + (suspend-for (seconds 5)) (sound-stop (-> self sound-id)) (sound-play "bomb-explode") (setup-masks (-> self draw) 0 -1) diff --git a/goal_src/jak3/levels/city/hijack/cty-hijack.gc b/goal_src/jak3/levels/city/hijack/cty-hijack.gc index 0829b26b14..a89210c00f 100644 --- a/goal_src/jak3/levels/city/hijack/cty-hijack.gc +++ b/goal_src/jak3/levels/city/hijack/cty-hijack.gc @@ -1360,11 +1360,7 @@ :virtual #t :enter (behavior () (set! (-> self vehicle-is-visible?) #f) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (task-node-close! (game-task-node city-vehicle-training-hover-zone-1) 'event) (set-setting! 'kg-difficulty #f 1.5 0) (set-setting! 'exclusive-load '((ignore lctyhijk)) 0.0 0) @@ -1485,11 +1481,7 @@ (task-node-close! (game-task-node city-hijack-vehicle-infiltrate) 'event) (go-virtual show-missile-launch) ) - (let ((t9-18 (-> (find-parent-state) trans))) - (if t9-18 - (t9-18) - ) - ) + (call-parent-state-handler trans) ) ) @@ -1689,11 +1681,7 @@ (until (process-grab? *target* #f) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.5)) - (suspend) - ) - ) + (suspend-for (seconds 1.5)) (send-event (handle->process (-> self hpickup)) 'flight-up) (let ((gp-1 (-> self missiles allocated-length)) (s5-0 0) @@ -1741,11 +1729,7 @@ ) ) (sound-play "hj-missile" :id (-> self missile-sound)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (dotimes (gp-3 (-> self missiles length)) (send-event (handle->process (-> self missiles gp-3)) 'begin-moving) ) @@ -1754,17 +1738,9 @@ (send-event (handle->process (-> self missiles gp-4)) 'begin-moving) ) (cty-hijack-manager-method-39 self 1) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (remove-setting! 'entity-name) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (until (process-release? *target*) (suspend) ) diff --git a/goal_src/jak3/levels/city/port/attack/ctyport-attack-bbush.gc b/goal_src/jak3/levels/city/port/attack/ctyport-attack-bbush.gc index 55ebec0b10..4869d38288 100644 --- a/goal_src/jak3/levels/city/port/attack/ctyport-attack-bbush.gc +++ b/goal_src/jak3/levels/city/port/attack/ctyport-attack-bbush.gc @@ -496,19 +496,11 @@ (defstate pickup-nukes (ctyport-attack-manager-bbush) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self countdown-timer) (the-as handle (current-time))) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (if (< (vector-vector-xz-distance (target-pos 0) *port-attack-bbush-fail-sphere*) *port-attack-bbush-fail-radius*) (send-event self 'fail) ) diff --git a/goal_src/jak3/levels/city/port/attack/ctyport-attack.gc b/goal_src/jak3/levels/city/port/attack/ctyport-attack.gc index e1335da4e1..9e47281360 100644 --- a/goal_src/jak3/levels/city/port/attack/ctyport-attack.gc +++ b/goal_src/jak3/levels/city/port/attack/ctyport-attack.gc @@ -1837,11 +1837,7 @@ process (lambda :behavior process () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.75)) - (suspend) - ) - ) + (suspend-for (seconds 0.75)) (let ((a0-0 (ppointer->process (-> self parent)))) (if a0-0 (play-speech (the-as ctyport-attack-manager a0-0) 13) @@ -1991,11 +1987,7 @@ :virtual #t :code (behavior () (sound-stop (-> self hum-sound)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (disable *screen-filter*) (deactivate self) ) @@ -2181,11 +2173,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (let ((gp-1 (new 'stack-no-clear 'event-message-block))) (set! (-> gp-1 from) (process->ppointer self)) (set! (-> gp-1 num-params) 0) diff --git a/goal_src/jak3/levels/city/port/attack/h-torpedo.gc b/goal_src/jak3/levels/city/port/attack/h-torpedo.gc index f4a8ea0a87..d5a92e95ef 100644 --- a/goal_src/jak3/levels/city/port/attack/h-torpedo.gc +++ b/goal_src/jak3/levels/city/port/attack/h-torpedo.gc @@ -1052,22 +1052,14 @@ ) ) :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self speed) 0.0) (set! (-> self jump-state) (the-as uint 2)) (set! (-> self jump-time) 0.0) (set! (-> *target* pilot jumping?) #f) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) ) :post (behavior () (control-hook-player self) diff --git a/goal_src/jak3/levels/city/protect/assault-enemies.gc b/goal_src/jak3/levels/city/protect/assault-enemies.gc index 8b5020cec4..53a8fa7aaa 100644 --- a/goal_src/jak3/levels/city/protect/assault-enemies.gc +++ b/goal_src/jak3/levels/city/protect/assault-enemies.gc @@ -188,11 +188,7 @@ (defstate knocked-recover (assault-citizen-norm) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (logclear! (-> self enemy-flags) (enemy-flag vulnerable)) (if (< (vector-vector-xz-distance (-> self root trans) (-> self center-pos)) 16384.0) (go-virtual cower-ground) @@ -356,11 +352,7 @@ (defstate cower-ground (assault-citizen-norm) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (if (enemy-method-109 self) (go-virtual die) ) @@ -754,11 +746,7 @@ (defstate tracking (assault-cleanup) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 5)) - (suspend) - ) - ) + (suspend-for (seconds 5)) (set-time! (-> self offscreen-time)) (until #f (suspend) @@ -1337,11 +1325,7 @@ ) ) ) - (let ((t9-11 (-> (find-parent-state) enter))) - (if t9-11 - (t9-11) - ) - ) + (call-parent-state-handler enter) ) ) @@ -1836,11 +1820,7 @@ (defstate drop-bombs (assault-bombbot) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self drop-num) (the-as uint 3)) ) ) @@ -1868,11 +1848,7 @@ (set! (-> self next-node) (the-as int (-> self current-node))) (set-time! (-> self state-time)) (set-time! (-> self stop-shoot)) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (remove-attacker *cty-attack-controller* (-> self attacker-info)) diff --git a/goal_src/jak3/levels/city/protect/assault-task.gc b/goal_src/jak3/levels/city/protect/assault-task.gc index 8b27286ee4..aa89205bed 100644 --- a/goal_src/jak3/levels/city/protect/assault-task.gc +++ b/goal_src/jak3/levels/city/protect/assault-task.gc @@ -283,11 +283,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (send-event self 'ammo-special 15 29) (sleep-code) ) @@ -430,11 +426,7 @@ (set! (-> v1-4 notify-proc) (process->handle self)) (send-event (handle->process (-> self h-player-controller)) 'set-params v1-4) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) (if *target* (logclear! (-> *target* focus-status) (focus-status teleporting)) ) @@ -729,11 +721,7 @@ ) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (spawn-enemies *assault-squad* self) ) :code (behavior () @@ -1380,11 +1368,7 @@ process (lambda :behavior process () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (dotimes (gp-1 (-> *assault-squad* spawn-records 1 records length)) (send-event (handle->process (-> *assault-squad* spawn-records 1 records data gp-1 proc)) 'traffic-off-force) ) @@ -1486,11 +1470,7 @@ (defstate clip-to-nav-mesh (assault-player-controller) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (assault-player-controller-method-36 self) ) ) diff --git a/goal_src/jak3/levels/city/protect/cty-protect.gc b/goal_src/jak3/levels/city/protect/cty-protect.gc index b36cf6bde6..6c2ca2030e 100644 --- a/goal_src/jak3/levels/city/protect/cty-protect.gc +++ b/goal_src/jak3/levels/city/protect/cty-protect.gc @@ -144,11 +144,7 @@ :virtual #t :enter (behavior () (set-blackout-frames (seconds 10)) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) ) @@ -315,17 +311,9 @@ ((-> (method-of-type task-manager active) trans)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (talker-spawn-func (-> *talker-speech* 337) *entity-pool* (target-pos 0) (the-as region #f)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2.5)) - (suspend) - ) - ) + (suspend-for (seconds 2.5)) (talker-spawn-func (-> *talker-speech* 336) *entity-pool* (target-pos 0) (the-as region #f)) (send-event self 'complete) (sleep-code) @@ -367,11 +355,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (talker-spawn-func (-> *talker-speech* 334) *entity-pool* (target-pos 0) (the-as region #f)) (sleep-code) ) diff --git a/goal_src/jak3/levels/city/protect/flying-turret.gc b/goal_src/jak3/levels/city/protect/flying-turret.gc index ca7bc7e83b..24336d4815 100644 --- a/goal_src/jak3/levels/city/protect/flying-turret.gc +++ b/goal_src/jak3/levels/city/protect/flying-turret.gc @@ -649,11 +649,7 @@ :enter (behavior () (set! (-> self chase-mode) (the-as uint 3)) (flying-turret-method-230 self (the-as uint 0)) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () (when (handle->process (-> self current-enemy)) diff --git a/goal_src/jak3/levels/city/protect/protect-gunship.gc b/goal_src/jak3/levels/city/protect/protect-gunship.gc index c86f93589a..76617f3da5 100644 --- a/goal_src/jak3/levels/city/protect/protect-gunship.gc +++ b/goal_src/jak3/levels/city/protect/protect-gunship.gc @@ -1616,11 +1616,7 @@ (set! (-> gp-1 pickup-amount) 2.0) (drop-pickup gp-1 #t *entity-pool* gp-1 0 #t) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 5)) - (suspend) - ) - ) + (suspend-for (seconds 5)) ) ) diff --git a/goal_src/jak3/levels/city/protect/roboguard-city.gc b/goal_src/jak3/levels/city/protect/roboguard-city.gc index 18f049d485..b419386711 100644 --- a/goal_src/jak3/levels/city/protect/roboguard-city.gc +++ b/goal_src/jak3/levels/city/protect/roboguard-city.gc @@ -439,11 +439,7 @@ (defbehavior roboguard-city-turret-code roboguard-city () (ja-channel-push! 1 (seconds 0.2)) (ja-no-eval :group! roboguard-city-idle-shoot0-loop-ja :num! zero) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (let ((gp-1 (lambda :behavior process ((arg0 roboguard-city) (arg1 symbol)) @@ -459,11 +455,7 @@ ) (until #f (when (< (fabs (-> self me-to-focus-angle)) f30-0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (while (< (fabs (-> self me-to-focus-angle)) f30-0) (suspend) ) @@ -484,11 +476,7 @@ ) ) (when (< (fabs (-> self me-to-focus-angle)) f30-0) - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (while (< (fabs (-> self me-to-focus-angle)) f30-0) (suspend) ) @@ -578,11 +566,7 @@ :virtual #t :trans (behavior () (nav-enemy-method-181 self) - (let ((t9-2 (-> (find-parent-state) trans))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler trans) (let ((gp-0 (get-current-enemy self))) (when gp-0 (let* ((s5-0 self) @@ -1643,11 +1627,7 @@ (defstate knocked-recover (roboguard-city) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () (let ((t9-0 (-> (method-of-type kg-squad-member knocked-recover) trans))) diff --git a/goal_src/jak3/levels/city/sniper/cty-sniper-battery.gc b/goal_src/jak3/levels/city/sniper/cty-sniper-battery.gc index b59746e4d2..360641ed88 100644 --- a/goal_src/jak3/levels/city/sniper/cty-sniper-battery.gc +++ b/goal_src/jak3/levels/city/sniper/cty-sniper-battery.gc @@ -304,11 +304,7 @@ (ja-channel-set! 1) (ja :group! cty-sniper-button-pushdown-ja :num! (identity (the float (ja-num-frames 0)))) (ja-post) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (-> self stay-down-time)) - (suspend) - ) - ) + (suspend-for (-> self stay-down-time)) (send-event (handle->process (-> self lid)) 'up #x3e800000) (ja-no-eval :group! cty-sniper-button-popup-ja :num! (seek! max 0.25) :frame-num 0.0) (until (ja-done? 0) diff --git a/goal_src/jak3/levels/city/sniper/cty-sniper-turret.gc b/goal_src/jak3/levels/city/sniper/cty-sniper-turret.gc index 12794ed25a..63841c0674 100644 --- a/goal_src/jak3/levels/city/sniper/cty-sniper-turret.gc +++ b/goal_src/jak3/levels/city/sniper/cty-sniper-turret.gc @@ -2627,11 +2627,7 @@ ) :code (behavior () (logior! (-> self flags) (cty-sniper-turret-flag cst3)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.49)) - (suspend) - ) - ) + (suspend-for (seconds 0.49)) (let ((gp-1 (rand-vu-int-range 3 6))) (dotimes (s5-0 gp-1) (fire-shot self) @@ -2763,29 +2759,27 @@ (when (and (< f30-0 0.0) (not (-> *setting-control* user-current freeze-screen))) (set-setting! 'mode-name 'cam-no-trans 0.0 0) (suspend) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.5)) - (let ((s3-0 (new 'stack-no-clear 'vector))) - (set! (-> s3-0 quad) (the-as uint128 0)) - (cond - ((< (* (-> s5-2 x) (-> gp-1 z)) (* (-> s5-2 z) (-> gp-1 x))) - (set! (-> s3-0 z) (- (-> s5-2 x))) - (set! (-> s3-0 x) (-> s5-2 z)) - ) - (else - (set! (-> s3-0 z) (-> s5-2 x)) - (set! (-> s3-0 x) (- (-> s5-2 z))) - ) + (suspend-for + (seconds 0.5) + (let ((s3-0 (new 'stack-no-clear 'vector))) + (set! (-> s3-0 quad) (the-as uint128 0)) + (cond + ((< (* (-> s5-2 x) (-> gp-1 z)) (* (-> s5-2 z) (-> gp-1 x))) + (set! (-> s3-0 z) (- (-> s5-2 x))) + (set! (-> s3-0 x) (-> s5-2 z)) + ) + (else + (set! (-> s3-0 z) (-> s5-2 x)) + (set! (-> s3-0 x) (- (-> s5-2 z))) ) - (vector+! s3-0 s3-0 (target-pos 0)) - (+! (-> s3-0 y) 20480.0) - (set! (-> *camera* slave 0 trans quad) (-> s3-0 quad)) ) - (vector-! gp-1 (-> self root trans) (target-pos 0)) - (vector-! s5-2 (camera-pos) (target-pos 0)) - (set-setting! 'interp-time 'abs 300.0 0) - (suspend) + (vector+! s3-0 s3-0 (target-pos 0)) + (+! (-> s3-0 y) 20480.0) + (set! (-> *camera* slave 0 trans quad) (-> s3-0 quad)) ) + (vector-! gp-1 (-> self root trans) (target-pos 0)) + (vector-! s5-2 (camera-pos) (target-pos 0)) + (set-setting! 'interp-time 'abs 300.0 0) ) ) (set-setting! 'mode-name 'cam-pov-track 0.0 0) @@ -2823,11 +2817,7 @@ #t ) (logior! (-> *target* focus-status) (focus-status ignore)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.08)) - (suspend) - ) - ) + (suspend-for (seconds 0.08)) (send-event self 'pov-cam-on) (send-event (handle->process (-> self reticle)) 'on) (setup @@ -2840,11 +2830,7 @@ #x33001 #t ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.08)) - (suspend) - ) - ) + (suspend-for (seconds 0.08)) (disable *screen-filter*) ) (else @@ -2885,16 +2871,12 @@ ) ) ) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 1.5)) - (when (focus-test? *target* grabbed) - (logclear! (-> self flags) (cty-sniper-turret-flag cst11)) - (send-event (handle->process (-> self reticle)) 'unlock) - (goto cfg-44) - ) - (suspend) - ) - ) + (suspend-for (seconds 1.5) (when (focus-test? *target* grabbed) + (logclear! (-> self flags) (cty-sniper-turret-flag cst11)) + (send-event (handle->process (-> self reticle)) 'unlock) + (goto cfg-44) + ) + ) (if (and (logtest? (-> self flags) (cty-sniper-turret-flag cst7)) (not (cty-sniper-turret-method-39 self))) (go-virtual locked-on) ) @@ -2947,11 +2929,7 @@ (suspend) (set-setting! 'interp-time 'abs 600.0 0) (remove-setting! 'mode-name) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (send-event (handle->process (-> self reticle)) 'die) (let ((v1-71 (-> self root root-prim))) (set! (-> v1-71 prim-core collide-as) (collide-spec)) diff --git a/goal_src/jak3/levels/city/traffic/citizen/civilian.gc b/goal_src/jak3/levels/city/traffic/citizen/civilian.gc index 69c475d667..24b25a4330 100644 --- a/goal_src/jak3/levels/city/traffic/citizen/civilian.gc +++ b/goal_src/jak3/levels/city/traffic/citizen/civilian.gc @@ -1178,11 +1178,7 @@ (defstate knocked-recover (civilian) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (let ((v1-2 self)) (set! (-> v1-2 enemy-flags) (the-as enemy-flag (logclear (-> v1-2 enemy-flags) (enemy-flag ef38)))) ) diff --git a/goal_src/jak3/levels/city/traffic/citizen/metalhead-flitter.gc b/goal_src/jak3/levels/city/traffic/citizen/metalhead-flitter.gc index c5a7e37a84..caf7d0abc9 100644 --- a/goal_src/jak3/levels/city/traffic/citizen/metalhead-flitter.gc +++ b/goal_src/jak3/levels/city/traffic/citizen/metalhead-flitter.gc @@ -337,18 +337,10 @@ ) ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.6)) - (suspend) - ) - ) + (suspend-for (seconds 0.6)) (+! (-> self root trans y) -8192.0) (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) (logclear! (-> self draw status) (draw-control-status no-draw)) (go-virtual ambush-jumping) ) diff --git a/goal_src/jak3/levels/comb/comb-obs.gc b/goal_src/jak3/levels/comb/comb-obs.gc index 2679bdcf03..9320e25dc6 100644 --- a/goal_src/jak3/levels/comb/comb-obs.gc +++ b/goal_src/jak3/levels/comb/comb-obs.gc @@ -355,11 +355,7 @@ :unk 0 ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (cleanup-for-death self) ) :post #f @@ -676,11 +672,7 @@ :unk 0 ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (cleanup-for-death self) ) :post #f @@ -1145,12 +1137,7 @@ (print-text self (text-id text-05f8)) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 6)) - (print-text self (text-id light-jak-shield-how-to)) - (suspend) - ) - ) + (suspend-for (seconds 6) (print-text self (text-id light-jak-shield-how-to))) (send-event *target* 'end-mode 'lightjak) (go-virtual complete) ) diff --git a/goal_src/jak3/levels/comb/comb-sentry.gc b/goal_src/jak3/levels/comb/comb-sentry.gc index 8ad096ee02..c98ea8d07d 100644 --- a/goal_src/jak3/levels/comb/comb-sentry.gc +++ b/goal_src/jak3/levels/comb/comb-sentry.gc @@ -727,11 +727,7 @@ :unk 0 ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (cleanup-for-death self) ) :post #f diff --git a/goal_src/jak3/levels/comb/comb-travel.gc b/goal_src/jak3/levels/comb/comb-travel.gc index 7f657723b7..3f29de29b1 100644 --- a/goal_src/jak3/levels/comb/comb-travel.gc +++ b/goal_src/jak3/levels/comb/comb-travel.gc @@ -232,11 +232,7 @@ (suspend) ) #f - (let ((t9-29 (-> (find-parent-state) code))) - (if t9-29 - ((the-as (function none) t9-29)) - ) - ) + (call-parent-state-handler code) ) ) @@ -245,11 +241,7 @@ :code (behavior () (remove-setting! 'pilot-exit) (set-setting! 'pilot #f 0.0 0) - (let ((t9-3 (-> (find-parent-state) code))) - (if t9-3 - ((the-as (function none) t9-3)) - ) - ) + (call-parent-state-handler code) ) ) @@ -291,16 +283,8 @@ :code (behavior () (send-event *target* 'end-mode 'pilot) (send-event (handle->process (-> self player-vehicle)) 'sled-disable) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) - ) - (let ((t9-3 (-> (find-parent-state) code))) - (if t9-3 - ((the-as (function none) t9-3)) - ) - ) + (suspend-for (seconds 2)) + (call-parent-state-handler code) ) ) diff --git a/goal_src/jak3/levels/comb/h-sled.gc b/goal_src/jak3/levels/comb/h-sled.gc index 0cd543fe69..9896d10477 100644 --- a/goal_src/jak3/levels/comb/h-sled.gc +++ b/goal_src/jak3/levels/comb/h-sled.gc @@ -1116,8 +1116,8 @@ (defmethod vehicle-method-88 ((this h-sled) (arg0 vehicle-controls)) (set! (-> arg0 steering) (analog-input (the-as int (-> *cpad-list* cpads 0 leftx)) 128.0 48.0 110.0 -1.0)) (set! (-> arg0 lean-z) (analog-input (the-as int (-> *cpad-list* cpads 0 lefty)) 128.0 48.0 110.0 -1.0)) - (set! (-> arg0 throttle) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton 6))))) - (set! (-> arg0 brake) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton 7))))) + (set! (-> arg0 throttle) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton (abutton-idx x)))))) ;; og:preserve-this abutton indexing + (set! (-> arg0 brake) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton (abutton-idx square)))))) ;; og:preserve-this abutton indexing (if (cpad-pressed? 0 r1) (logior! (-> arg0 flags) (vehicle-controls-flag vcf1)) ) @@ -1842,11 +1842,7 @@ :virtual #t :enter (behavior () (set! (-> self health-hud) (process->handle (hud-sled-health-spawn self))) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (let ((t9-1 (-> (find-parent-state) exit))) diff --git a/goal_src/jak3/levels/common/elec-gate.gc b/goal_src/jak3/levels/common/elec-gate.gc index db416c1488..89fab2c02c 100644 --- a/goal_src/jak3/levels/common/elec-gate.gc +++ b/goal_src/jak3/levels/common/elec-gate.gc @@ -643,11 +643,7 @@ (defstate shutdown-camera (elec-gate) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (format 0 "~s~%" (-> self name)) (if (res-lump-struct (-> self entity) 'camera-name structure) (process-spawn @@ -659,11 +655,7 @@ :to *entity-pool* ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (go-virtual shutdown) ) :post (behavior () diff --git a/goal_src/jak3/levels/common/enemy/darkprec/neo-wasp.gc b/goal_src/jak3/levels/common/enemy/darkprec/neo-wasp.gc index 05d5703fd5..2a943e80ce 100644 --- a/goal_src/jak3/levels/common/enemy/darkprec/neo-wasp.gc +++ b/goal_src/jak3/levels/common/enemy/darkprec/neo-wasp.gc @@ -657,11 +657,7 @@ 0 (set! (-> self hit-points) 0.0) (do-effect (-> self skel effect) "death-default" 0.0 -1) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event self 'death-end) (cleanup-for-death self) ) diff --git a/goal_src/jak3/levels/common/enemy/flitter.gc b/goal_src/jak3/levels/common/enemy/flitter.gc index 539700132f..414c5cf6c6 100644 --- a/goal_src/jak3/levels/common/enemy/flitter.gc +++ b/goal_src/jak3/levels/common/enemy/flitter.gc @@ -699,11 +699,7 @@ (part-tracker-spawn part-tracker :to *entity-pool* :group (-> *part-group-id-table* 1412)) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.6)) - (suspend) - ) - ) + (suspend-for (seconds 0.6)) (+! (-> self root trans y) -8192.0) (update-focus self) (let ((a0-14 (handle->process (-> self focus handle)))) @@ -721,11 +717,7 @@ ) ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) (logclear! (-> self draw status) (draw-control-status no-draw)) (go-virtual ambush-jumping) ) diff --git a/goal_src/jak3/levels/common/enemy/grunt.gc b/goal_src/jak3/levels/common/enemy/grunt.gc index 3880431288..91977d8355 100644 --- a/goal_src/jak3/levels/common/enemy/grunt.gc +++ b/goal_src/jak3/levels/common/enemy/grunt.gc @@ -985,11 +985,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (let ((v1-6 (-> self root root-prim))) (set! (-> v1-6 prim-core collide-as) (-> self root backup-collide-as)) (set! (-> v1-6 prim-core collide-with) (-> self root backup-collide-with)) diff --git a/goal_src/jak3/levels/common/enemy/hover/robo-hover.gc b/goal_src/jak3/levels/common/enemy/hover/robo-hover.gc index 56dca2bbf3..fc1369c57d 100644 --- a/goal_src/jak3/levels/common/enemy/hover/robo-hover.gc +++ b/goal_src/jak3/levels/common/enemy/hover/robo-hover.gc @@ -995,11 +995,7 @@ ) ) :post (behavior () - (let ((t9-1 (-> (find-parent-state) post))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler post) (seek! (-> self gun-blend) 0.0 (* 5.0 (seconds-per-frame))) ) ) diff --git a/goal_src/jak3/levels/common/enemy/kg-grunt.gc b/goal_src/jak3/levels/common/enemy/kg-grunt.gc index 41e0146b17..5a58a4f840 100644 --- a/goal_src/jak3/levels/common/enemy/kg-grunt.gc +++ b/goal_src/jak3/levels/common/enemy/kg-grunt.gc @@ -832,11 +832,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (let ((v1-6 (-> self root root-prim))) (set! (-> v1-6 prim-core collide-as) (-> self root backup-collide-as)) (set! (-> v1-6 prim-core collide-with) (-> self root backup-collide-with)) diff --git a/goal_src/jak3/levels/common/enemy/mantis.gc b/goal_src/jak3/levels/common/enemy/mantis.gc index fc8c26195e..d56fb3add5 100644 --- a/goal_src/jak3/levels/common/enemy/mantis.gc +++ b/goal_src/jak3/levels/common/enemy/mantis.gc @@ -669,11 +669,7 @@ (defstate active (mantis) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (if (logtest? (-> self flags) (mantis-flag tracked)) (mantis-method-199 self) ) @@ -762,17 +758,9 @@ ) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.3)) - (suspend) - ) - ) + (suspend-for (seconds 0.3)) (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) (logclear! (-> self draw status) (draw-control-status no-draw)) (let* ((v1-45 (-> self nav)) (a1-7 (-> self root trans)) @@ -904,14 +892,10 @@ (suspend) (ja :num! (seek! max 1.2)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (if (logtest? (-> self root status) (collide-status on-ground)) - (goto cfg-35) - ) - (suspend) - ) - ) + (suspend-for (seconds 1) (if (logtest? (-> self root status) (collide-status on-ground)) + (goto cfg-35) + ) + ) (label cfg-35) (go-virtual hostile) ) diff --git a/goal_src/jak3/levels/common/enemy/roboguard.gc b/goal_src/jak3/levels/common/enemy/roboguard.gc index 3501e78f61..3d3bf9a9fb 100644 --- a/goal_src/jak3/levels/common/enemy/roboguard.gc +++ b/goal_src/jak3/levels/common/enemy/roboguard.gc @@ -521,11 +521,7 @@ (defbehavior roboguard-turret-code roboguard () (ja-channel-push! 1 (seconds 0.2)) (ja-no-eval :group! roboguard-idle-shoot0-loop-ja :num! zero) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (let ((gp-1 (lambda ((arg0 roboguard) (arg1 symbol)) (quaternion-rotate-y! (-> arg0 root quat) (-> arg0 root quat) (* 20480.0 (seconds-per-frame) (if arg1 @@ -540,11 +536,7 @@ ) (until #f (when (< (fabs (-> self me-to-focus-angle)) f30-0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (while (< (fabs (-> self me-to-focus-angle)) f30-0) (suspend) ) @@ -565,11 +557,7 @@ ) ) (when (< (fabs (-> self me-to-focus-angle)) f30-0) - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (while (< (fabs (-> self me-to-focus-angle)) f30-0) (suspend) ) diff --git a/goal_src/jak3/levels/common/enemy/spyder.gc b/goal_src/jak3/levels/common/enemy/spyder.gc index 19d6795e2c..c7efca2945 100644 --- a/goal_src/jak3/levels/common/enemy/spyder.gc +++ b/goal_src/jak3/levels/common/enemy/spyder.gc @@ -1068,13 +1068,11 @@ (set! (-> self fire-info 0 quad) (-> s3-0 quad)) (set! (-> self fire-info 1 quad) (-> s2-1 quad)) ) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 0.2)) - (set! f30-0 (seek f30-0 (lerp-scale 0.0 1.0 (the float s4-0) 0.0 8.0) (seconds-per-frame))) - (ja :num! (loop!)) - (ja :chan 1 :num! (chan 0) :frame-interp0 f30-0 :frame-interp1 f30-0) - (suspend) - ) + (suspend-for + (seconds 0.2) + (set! f30-0 (seek f30-0 (lerp-scale 0.0 1.0 (the float s4-0) 0.0 8.0) (seconds-per-frame))) + (ja :num! (loop!)) + (ja :chan 1 :num! (chan 0) :frame-interp0 f30-0 :frame-interp1 f30-0) ) (let ((f28-1 (+ 12288.0 f28-0))) (set! (-> gp-0 quad) (-> s5-0 quad)) diff --git a/goal_src/jak3/levels/common/enemy/spydroid-orig.gc b/goal_src/jak3/levels/common/enemy/spydroid-orig.gc index 556d2b5893..d353525ca9 100644 --- a/goal_src/jak3/levels/common/enemy/spydroid-orig.gc +++ b/goal_src/jak3/levels/common/enemy/spydroid-orig.gc @@ -1123,11 +1123,7 @@ ) (suspend) (ja-channel-set! 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event self 'death-end) (let ((gp-1 (-> self child))) (while gp-1 diff --git a/goal_src/jak3/levels/common/enemy/spydroid.gc b/goal_src/jak3/levels/common/enemy/spydroid.gc index 8c8fb23de7..3cb59b5d70 100644 --- a/goal_src/jak3/levels/common/enemy/spydroid.gc +++ b/goal_src/jak3/levels/common/enemy/spydroid.gc @@ -1423,21 +1423,13 @@ ) ) :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (spydroid-method-231 self (the-as uint 0)) (set-time! (-> self state-time)) (logior! (-> self flags) (citizen-flag neck-no-auto-look-at)) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (when (or (!= (-> self faction-mode) 0) (logtest? (-> self flags) (citizen-flag in-mission))) (spydroid-method-236 self) (go-virtual hostile) diff --git a/goal_src/jak3/levels/desert/artifact-race/artifact-race.gc b/goal_src/jak3/levels/desert/artifact-race/artifact-race.gc index 7dcbe11bc3..ff7d007ca3 100644 --- a/goal_src/jak3/levels/desert/artifact-race/artifact-race.gc +++ b/goal_src/jak3/levels/desert/artifact-race/artifact-race.gc @@ -357,7 +357,7 @@ ) -(define *artifact-race-speech-list* (new 'static 'inline-array talker-speech-class 16 +(define *artifact-race-speech-list* (new 'static 'inline-array talker-speech-class 32 (new 'static 'talker-speech-class :name "none") (new 'static 'talker-speech-class :name "dax128" @@ -508,6 +508,166 @@ :on-close #f :camera #f ) + (new 'static 'talker-speech-class + :name "dax177" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x10 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax178" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x11 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax179" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x12 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax180" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x13 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax181" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x14 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax182" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x15 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax183" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x16 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax184" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x17 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax185" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x18 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax186" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x19 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax187" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x1a + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax188" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x1b + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax189" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x1c + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax190" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x1d + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax191" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x1e + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax192" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x1f + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) ) ) @@ -904,22 +1064,10 @@ 0 (when (= (-> self node-info task) (game-task desert-artifact-race-1)) (send-event *target* 'end-mode 'pilot) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) - ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) - ) - (let ((t9-3 (-> (find-parent-state) code))) - (if t9-3 - ((the-as (function none) t9-3)) - ) + (suspend-for (seconds 0.5)) ) + (suspend-for (seconds 0.5)) + (call-parent-state-handler code) ) ) diff --git a/goal_src/jak3/levels/desert/boss/terraformer-head.gc b/goal_src/jak3/levels/desert/boss/terraformer-head.gc index cbefa1bd82..c1cf64726e 100644 --- a/goal_src/jak3/levels/desert/boss/terraformer-head.gc +++ b/goal_src/jak3/levels/desert/boss/terraformer-head.gc @@ -2603,6 +2603,9 @@ :trans (behavior () (cond ((= (-> self hit-points) 0.0) + ;; og:preserve-this + (#when PC_PORT + (set! (-> *autosplit-info-jak3* errol-dead?) 1)) (let ((a1-0 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-0 from) (process->ppointer self)) (set! (-> a1-0 num-params) 0) diff --git a/goal_src/jak3/levels/desert/chase/desert-chase.gc b/goal_src/jak3/levels/desert/chase/desert-chase.gc index df69feffd6..228039e857 100644 --- a/goal_src/jak3/levels/desert/chase/desert-chase.gc +++ b/goal_src/jak3/levels/desert/chase/desert-chase.gc @@ -122,17 +122,13 @@ ) :code (behavior () (suspend) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (let ((a1-0 (new 'stack-no-clear 'overlaps-others-params))) - (set! (-> a1-0 options) (overlaps-others-options)) - (set! (-> a1-0 collide-with-filter) (the-as collide-spec -1)) - (set! (-> a1-0 tlist) *touching-list*) - (find-overlapping-shapes (-> self root) a1-0) - ) - (suspend) - ) - ) + (suspend-for (seconds 3) (let ((a1-0 (new 'stack-no-clear 'overlaps-others-params))) + (set! (-> a1-0 options) (overlaps-others-options)) + (set! (-> a1-0 collide-with-filter) (the-as collide-spec -1)) + (set! (-> a1-0 tlist) *touching-list*) + (find-overlapping-shapes (-> self root) a1-0) + ) + ) (let ((v1-10 (-> self root root-prim))) (set! (-> v1-10 prim-core collide-as) (collide-spec)) (set! (-> v1-10 prim-core collide-with) (collide-spec)) @@ -507,17 +503,9 @@ (let ((v1-137 (-> self vehicle 3 handle process))) (set-setting! 'sound-ear v1-137 0.0 (-> v1-137 0 pid)) ) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 1.5)) - (suspend) - ) - ) + (suspend-for (seconds 1.5)) (desert-chase-ambush-manager-method-35 self 3) - (let ((gp-10 (current-time))) - (until (time-elapsed? gp-10 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (persist-with-delay *setting-control* 'blur-a (seconds 1.5) 'blur-a 'abs 0.5 0) (set! (-> *display* force-sync) (the-as uint 240)) (sound-play "camera-pan-3" :position #f) @@ -525,17 +513,9 @@ (set-setting! 'sound-ear v1-157 0.0 (-> v1-157 0 pid)) ) (set-setting! 'entity-name "camera-400" 0.0 0) - (let ((gp-12 (current-time))) - (until (time-elapsed? gp-12 (seconds 1.5)) - (suspend) - ) - ) + (suspend-for (seconds 1.5)) (desert-chase-ambush-manager-method-35 self 2) - (let ((gp-13 (current-time))) - (until (time-elapsed? gp-13 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (desert-chase-ambush-manager-method-35 self 1) (persist-with-delay *setting-control* 'blur-a (seconds 1.5) 'blur-a 'abs 0.5 0) (set! (-> *display* force-sync) (the-as uint 240)) @@ -544,17 +524,9 @@ (set-setting! 'sound-ear v1-181 0.0 (-> v1-181 0 pid)) ) (set-setting! 'entity-name "camera-402" 0.0 0) - (let ((gp-15 (current-time))) - (until (time-elapsed? gp-15 (seconds 1.5)) - (suspend) - ) - ) + (suspend-for (seconds 1.5)) (desert-chase-ambush-manager-method-35 self 0) - (let ((gp-16 (current-time))) - (until (time-elapsed? gp-16 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (remove-setting! 'sound-ear) (persist-with-delay *setting-control* 'blur-a (seconds 1.5) 'blur-a 'abs 0.5 0) (set! (-> *display* force-sync) (the-as uint 240)) @@ -593,11 +565,7 @@ (if *target* (logclear! (-> *target* focus-status) (focus-status teleporting)) ) - (let ((gp-19 (current-time))) - (until (time-elapsed? gp-19 (seconds 2.5)) - (suspend) - ) - ) + (suspend-for (seconds 2.5)) (remove-setting! 'entity-name) (dotimes (gp-20 4) (let ((s5-7 (-> self vehicle gp-20)) @@ -704,11 +672,7 @@ (ppointer->handle (process-spawn hud-marauder :init hud-init-by-other :name "hud-marauder" :to self)) ) (set! (-> *game-info* counter) (the float (- (+ (-> self marauder-count) 60) (-> self total-spawned)))) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) (until (and (>= (-> self total-spawned) (the-as uint 60)) (zero? (-> self marauder-count))) (when (>= (+ (current-time) (seconds -0.5)) (-> self check-timer)) (let* ((gp-5 (length *stronghold-marauder-start*)) @@ -1650,11 +1614,7 @@ 0 ) ) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (let ((gp-7 (new 'stack-no-clear 'event-message-block))) (set! (-> gp-7 from) (process->ppointer self)) (set! (-> gp-7 num-params) 0) @@ -1677,11 +1637,7 @@ (set! (-> gp-8 i-node) 48) ) ) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (let ((gp-10 (-> self control-array 2))) (when (not (handle->process (-> gp-10 vehicle))) (spawn-chase-vehicle self (the-as deschase-vehicle gp-10) (-> *stronghold-vehicle-start* 0)) @@ -1690,11 +1646,7 @@ 0 ) ) - (let ((gp-11 (current-time))) - (until (time-elapsed? gp-11 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (let ((gp-12 (new 'stack-no-clear 'event-message-block))) (set! (-> gp-12 from) (process->ppointer self)) (set! (-> gp-12 num-params) 0) @@ -1717,11 +1669,7 @@ (set! (-> gp-13 i-node) 48) ) ) - (let ((gp-14 (current-time))) - (until (time-elapsed? gp-14 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (let ((gp-15 (new 'stack-no-clear 'event-message-block))) (set! (-> gp-15 from) (process->ppointer self)) (set! (-> gp-15 num-params) 0) @@ -1737,16 +1685,8 @@ ) ) ) - (let ((gp-16 (current-time))) - (until (time-elapsed? gp-16 (seconds 1)) - (suspend) - ) - ) - (let ((gp-17 (current-time))) - (until (time-elapsed? gp-17 (seconds 4)) - (suspend) - ) - ) + (suspend-for (seconds 1)) + (suspend-for (seconds 4)) (send-event (handle->process (-> self h-player-controller)) 'change-mode 'idle) (dotimes (gp-18 4) (let ((s5-7 (-> self control-array gp-18))) @@ -1839,11 +1779,7 @@ ) ) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (was-squad-manager-start self) (let ((v1-66 *was-squad-control*)) (set! (-> v1-66 target-count) 2) @@ -1982,11 +1918,7 @@ (if (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) ) - (let ((s5-5 (current-time))) - (until (time-elapsed? s5-5 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (+! gp-6 -1) (if (= gp-6 -1) (goto cfg-176) @@ -2029,15 +1961,7 @@ (defstate complete (desert-chase-chase-manager) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 4)) - (suspend) - ) - ) - (let ((t9-1 (-> (find-parent-state) code))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (suspend-for (seconds 4)) + (call-parent-state-handler code) ) ) diff --git a/goal_src/jak3/levels/desert/chase/desert-jump.gc b/goal_src/jak3/levels/desert/chase/desert-jump.gc index d60ac10808..8ad1389c65 100644 --- a/goal_src/jak3/levels/desert/chase/desert-jump.gc +++ b/goal_src/jak3/levels/desert/chase/desert-jump.gc @@ -870,11 +870,7 @@ ) ) ) - (let ((gp-7 (current-time))) - (until (time-elapsed? gp-7 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (send-event self 'complete) ) :post (behavior () diff --git a/goal_src/jak3/levels/desert/chase/wcar-marauder-b.gc b/goal_src/jak3/levels/desert/chase/wcar-marauder-b.gc index a883190b4f..4305cf42bd 100644 --- a/goal_src/jak3/levels/desert/chase/wcar-marauder-b.gc +++ b/goal_src/jak3/levels/desert/chase/wcar-marauder-b.gc @@ -347,10 +347,6 @@ (if (and *target* (focus-test? *target* pilot-riding) (not (logtest? (vehicle-flag vf55) (-> self v-flags)))) (turbo-pickup-spawn (-> self root trans)) ) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) ) diff --git a/goal_src/jak3/levels/desert/des-bbush-tasks.gc b/goal_src/jak3/levels/desert/des-bbush-tasks.gc index 73cc7aba84..5ce1efb559 100644 --- a/goal_src/jak3/levels/desert/des-bbush-tasks.gc +++ b/goal_src/jak3/levels/desert/des-bbush-tasks.gc @@ -538,11 +538,7 @@ (script-eval gp-0) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (while (not (-> *setting-control* user-current speech-control)) (suspend) ) diff --git a/goal_src/jak3/levels/desert/des-burning-bush.gc b/goal_src/jak3/levels/desert/des-burning-bush.gc index 5073f2521c..b49b511da4 100644 --- a/goal_src/jak3/levels/desert/des-burning-bush.gc +++ b/goal_src/jak3/levels/desert/des-burning-bush.gc @@ -932,11 +932,7 @@ ) ) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (set-time! (-> self state-time)) (while (and (nonzero? (get-status *gui-control* (the-as sound-id (-> self message-id)))) (not (time-elapsed? (-> self state-time) (seconds 60))) @@ -1494,11 +1490,9 @@ (send-event *camera* 'teleport-to-transformq s4-0) ) (set! (-> self update-fov?) #t) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 3)) - (set! (-> *camera* slave 0 fov) (-> *burning-bush-get-on-info* (-> self info index) fov)) - (suspend) - ) + (suspend-for + (seconds 3) + (set! (-> *camera* slave 0 fov) (-> *burning-bush-get-on-info* (-> self info index) fov)) ) (set! (-> self update-fov?) #f) (set! (-> *camera-combiner* trans quad) (-> s5-0 quad)) diff --git a/goal_src/jak3/levels/desert/des-bush.gc b/goal_src/jak3/levels/desert/des-bush.gc index 2ce7cfad50..a270ab95ba 100644 --- a/goal_src/jak3/levels/desert/des-bush.gc +++ b/goal_src/jak3/levels/desert/des-bush.gc @@ -782,11 +782,7 @@ 0 ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (hud-timer-handler self) ) :code (behavior () @@ -1518,8 +1514,10 @@ ) ) ) - (set! (-> *game-info* score) (the float v1-7)) - (if (= v1-7 (-> self goal-score)) + ;; og:preserve-this fix hud kill counter + (set! (-> *game-info* score) (the float (the int v1-7))) + ;; og:preserve-this fix original game bug + (if (>= v1-7 (-> self goal-score)) (send-event self 'complete) ) ) diff --git a/goal_src/jak3/levels/desert/des-cactus.gc b/goal_src/jak3/levels/desert/des-cactus.gc index c2b70c525b..851fda2bf8 100644 --- a/goal_src/jak3/levels/desert/des-cactus.gc +++ b/goal_src/jak3/levels/desert/des-cactus.gc @@ -361,11 +361,7 @@ ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (cleanup-for-death self) ) :post #f diff --git a/goal_src/jak3/levels/desert/desert-dust-storm.gc b/goal_src/jak3/levels/desert/desert-dust-storm.gc index cc409ca030..1a0840f4df 100644 --- a/goal_src/jak3/levels/desert/desert-dust-storm.gc +++ b/goal_src/jak3/levels/desert/desert-dust-storm.gc @@ -718,7 +718,15 @@ (set! (-> a2-8 quad) (-> *time-of-day-context* current-fog fog-color quad)) (set! (-> a2-8 w) (* 128.0 f0-48)) (set! (-> this enabled-screen-filter?) #t) - (setup *screen-filter* a2-8 a2-8 10000.0 (bucket-id generic-sprite-1) #x20000 #x30003 #t) + (setup *screen-filter* a2-8 a2-8 10000.0 + ;;(bucket-id generic-sprite-1) + ;; og:preserve-this + ;; Modified to put this into a nearby bucket with same settings + ;; that uses DirectRenderer in the C++ renderer. + ;; otherwise, it goes to the Generic renderer, which doesn't know how to + ;; handle drawing through Direct. + (bucket-id tex-hud-pris2) + #x20000 #x30003 #t) ) ) ) diff --git a/goal_src/jak3/levels/desert/hover/des-beast-2.gc b/goal_src/jak3/levels/desert/hover/des-beast-2.gc index 66bcb9bb9e..8f8c1cdd5c 100644 --- a/goal_src/jak3/levels/desert/hover/des-beast-2.gc +++ b/goal_src/jak3/levels/desert/hover/des-beast-2.gc @@ -267,11 +267,7 @@ (defstate impact (beast-grenade-2) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) @@ -336,11 +332,7 @@ (defstate dissipate (beast-grenade-2) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) @@ -466,7 +458,7 @@ (set! (-> s5-1 track-immediately?) #t) (let* ((v1-28 (estimate-light-trail-mem-usage (the-as uint (-> s5-1 max-num-crumbs)) - (the-as uint (= (-> s5-1 appearance lie-mode) 3)) + (the-as uint (= (-> s5-1 appearance lie-mode) (lie-mode use-two-strips))) ) ) (s4-1 (get-process *default-dead-pool* light-trail-tracker-projectile (+ v1-28 8192) 1)) @@ -826,21 +818,13 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) (until (ja-done? 0) (suspend) ) (logior! (-> self skel effect flags) (effect-control-flag ecf1)) (do-effect (-> self skel effect) "death-default" 0.0 -1) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) (go-virtual die) ) :post (behavior () diff --git a/goal_src/jak3/levels/desert/hover/mh-flyer.gc b/goal_src/jak3/levels/desert/hover/mh-flyer.gc index 07b0f3b810..0f0a1d2e71 100644 --- a/goal_src/jak3/levels/desert/hover/mh-flyer.gc +++ b/goal_src/jak3/levels/desert/hover/mh-flyer.gc @@ -166,11 +166,7 @@ ) ) :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) @@ -213,11 +209,7 @@ (defstate dissipate (mh-flyer-shot) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) @@ -1229,11 +1221,7 @@ (if (-> self skel effect) (do-effect (-> self skel effect) "death-default" 0.0 -1) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (cleanup-for-death self) ) ) diff --git a/goal_src/jak3/levels/desert/hover/scorpion-gun.gc b/goal_src/jak3/levels/desert/hover/scorpion-gun.gc index 0e43e01b82..e0e368147d 100644 --- a/goal_src/jak3/levels/desert/hover/scorpion-gun.gc +++ b/goal_src/jak3/levels/desert/hover/scorpion-gun.gc @@ -1939,17 +1939,9 @@ (send-event self 'use-camera #f) (send-event (handle->process (-> self gun)) 'shutdown) (send-event *camera* 'change-target (handle->process (-> self last-beast))) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (send-event (handle->process (-> self scorp)) 'set-control-hook-player) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 4)) - (suspend) - ) - ) + (suspend-for (seconds 4)) (until (process-release? *target*) (suspend) ) @@ -1988,11 +1980,7 @@ (send-event *camera* 'change-target (handle->process (-> self scorp))) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (let* ((v1-7 (-> *game-info* sub-task-list (game-task-node desert-beast-battle-kill-last-beast))) (v1-9 (if (-> v1-7 manager) (-> v1-7 manager manager) diff --git a/goal_src/jak3/levels/desert/lizard/desert-lizard-task.gc b/goal_src/jak3/levels/desert/lizard/desert-lizard-task.gc index cd96d29606..26815951f2 100644 --- a/goal_src/jak3/levels/desert/lizard/desert-lizard-task.gc +++ b/goal_src/jak3/levels/desert/lizard/desert-lizard-task.gc @@ -234,13 +234,11 @@ ) ) (when (time-elapsed? (-> self state-time) (seconds 5)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (set! (-> self sound-id) - (add-process *gui-control* self (gui-channel background) (gui-action queue) "hudchime" -99.0 0) - ) - (suspend) - ) + (suspend-for + (seconds 1) + (set! (-> self sound-id) + (add-process *gui-control* self (gui-channel background) (gui-action queue) "hudchime" -99.0 0) + ) ) (sound-params-set! *gui-control* (-> self sound-id) #f -1 -1 -1 1.0) (set-action! @@ -572,11 +570,7 @@ :virtual #t :code (behavior () (send-event (handle->process (-> self vehicle-handle)) 'go-die) - (let ((t9-2 (-> (find-parent-state) code))) - (if t9-2 - ((the-as (function none) t9-2)) - ) - ) + (call-parent-state-handler code) ) ) diff --git a/goal_src/jak3/levels/desert/race/course-race.gc b/goal_src/jak3/levels/desert/race/course-race.gc index 596beabfc8..11111548e4 100644 --- a/goal_src/jak3/levels/desert/race/course-race.gc +++ b/goal_src/jak3/levels/desert/race/course-race.gc @@ -266,26 +266,14 @@ ) (suspend) (speech-control-method-12 *speech-control* *target* (speech-type race-errol-start)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (set! (-> self race-started?) #t) (task-manager-race-method-38 self) (remove-setting! 'allow-progress) (send-event (ppointer->process *race-manager*) 'force-start) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (send-event (handle->process (-> self player-vehicle)) 'set-control-hook-player) - (let ((t9-20 (-> (find-parent-state) code))) - (if t9-20 - ((the-as (function none) t9-20)) - ) - ) + (call-parent-state-handler code) ) ) @@ -310,11 +298,7 @@ :virtual #t :code (behavior () (task-manager-race-method-36 self) - (let ((t9-2 (-> (find-parent-state) code))) - (if t9-2 - ((the-as (function none) t9-2)) - ) - ) + (call-parent-state-handler code) ) ) @@ -607,11 +591,7 @@ ) #f (label cfg-123) - (let ((gp-7 (current-time))) - (until (time-elapsed? gp-7 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event (handle->process (-> self player-vehicle)) 'go-die) (remove-setting! 'entity-name) (send-event *target* 'continue (get-continue-by-name *game-info* "desertb-race-start")) @@ -670,11 +650,7 @@ (set-setting! 'vehicles 'set (shr t1-0 32) t1-0) ) (set! (-> self start-continue) (the-as continue-point "desertb-race-start")) - (let ((t9-2 (-> (find-parent-state) code))) - (if t9-2 - ((the-as (function none) t9-2)) - ) - ) + (call-parent-state-handler code) ) ) @@ -689,20 +665,12 @@ ) (task-node-close! (game-task-node desert-course-race-win) 'event) (send-event (ppointer->process *race-manager*) 'kill-npc-racers) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while (handle->process (-> self scene-player)) (suspend) ) ) - (let ((t9-6 (-> (find-parent-state) code))) - (if t9-6 - ((the-as (function none) t9-6)) - ) - ) + (call-parent-state-handler code) ) ) @@ -828,11 +796,7 @@ (process-spawn hud-wasbbv-goal-time :init hud-init-by-other :name "hud-wasbbv-goal-time" :to self) ) ) - (let ((t9-7 (-> (find-parent-state) code))) - (if t9-7 - ((the-as (function none) t9-7)) - ) - ) + (call-parent-state-handler code) ) ) @@ -978,10 +942,6 @@ (process-spawn hud-wasbbv-goal-time :init hud-init-by-other :name "hud-wasbbv-goal-time" :to self) ) ) - (let ((t9-6 (-> (find-parent-state) code))) - (if t9-6 - ((the-as (function none) t9-6)) - ) - ) + (call-parent-state-handler code) ) ) diff --git a/goal_src/jak3/levels/desert/race/turtle-training.gc b/goal_src/jak3/levels/desert/race/turtle-training.gc index e5d120cf56..53359bf023 100644 --- a/goal_src/jak3/levels/desert/race/turtle-training.gc +++ b/goal_src/jak3/levels/desert/race/turtle-training.gc @@ -289,17 +289,8 @@ (set! (-> gp-0 map-icon) (the-as uint 12)) (set! (-> self arrow) (process->handle (task-arrow-spawn gp-0 self))) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 4)) - (print-training-text self (text-id text-05e6)) - (suspend) - ) - ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 4) (print-training-text self (text-id text-05e6))) + (suspend-for (seconds 0.25)) (set! (-> self time-limit) (seconds 30)) (set-time! (-> self start-time)) (until #f @@ -324,11 +315,7 @@ (set! (-> self arrow) (the-as handle #f)) (send-event (handle->process (-> self hud-timer)) 'hide-and-die) (set! (-> self start-time) 0) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (set! (-> self show-message?) #f) (set! (-> self goal-pos quad) (-> self goal-array 1 pos quad)) (let ((gp-5 (new 'stack-no-clear 'task-arrow-params))) @@ -359,11 +346,7 @@ (set! (-> self arrow) (the-as handle #f)) (send-event (handle->process (-> self hud-timer)) 'hide-and-die) (set! (-> self start-time) 0) - (let ((gp-7 (current-time))) - (until (time-elapsed? gp-7 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (set! (-> self time-limit) (seconds 28)) (set-time! (-> self start-time)) (set-time! (-> self test-time)) @@ -382,11 +365,7 @@ (sound-play "special-pickup") (send-event (handle->process (-> self hud-timer)) 'hide-and-die) (set! (-> self start-time) 0) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (set! (-> self show-message?) #f) (set! (-> self goal-pos quad) (-> self goal-array 2 pos quad)) (let ((gp-10 (new 'stack-no-clear 'task-arrow-params))) @@ -434,11 +413,7 @@ (set! (-> self arrow) (the-as handle #f)) (send-event (handle->process (-> self hud-timer)) 'hide-and-die) (set! (-> self start-time) 0) - (let ((gp-12 (current-time))) - (until (time-elapsed? gp-12 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (set! (-> self goal-pos quad) (-> self goal-array 3 pos quad)) (let ((gp-13 (new 'stack-no-clear 'task-arrow-params))) (set! (-> gp-13 pos quad) (-> self goal-pos quad)) @@ -467,11 +442,7 @@ (set! (-> self arrow) (the-as handle #f)) (send-event (handle->process (-> self hud-timer)) 'hide-and-die) (set! (-> self start-time) 0) - (let ((gp-15 (current-time))) - (until (time-elapsed? gp-15 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (set! (-> self goal-pos quad) (-> self goal-array 4 pos quad)) (let ((gp-16 (new 'stack-no-clear 'task-arrow-params))) (set! (-> gp-16 pos quad) (-> self goal-pos quad)) @@ -504,11 +475,7 @@ (set! (-> self arrow) (the-as handle #f)) (send-event (handle->process (-> self hud-timer)) 'hide-and-die) (set! (-> self start-time) 0) - (let ((gp-18 (current-time))) - (until (time-elapsed? gp-18 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (set! (-> self goal-pos quad) (-> self goal-array 5 pos quad)) (let ((gp-19 (new 'stack-no-clear 'task-arrow-params))) (set! (-> gp-19 pos quad) (-> self goal-pos quad)) diff --git a/goal_src/jak3/levels/desert/rescue/desert-rescue.gc b/goal_src/jak3/levels/desert/rescue/desert-rescue.gc index 1765dbb0d7..114d01d13c 100644 --- a/goal_src/jak3/levels/desert/rescue/desert-rescue.gc +++ b/goal_src/jak3/levels/desert/rescue/desert-rescue.gc @@ -1795,11 +1795,7 @@ :virtual #t :event task-manager-event-handler :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self entity) #f) (dotimes (v1-2 (-> self passenger-pos length)) (if (-> self passenger-pos v1-2 is-final?) @@ -2566,11 +2562,7 @@ ((-> (method-of-type task-manager active) trans)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event self 'fail) (sleep-code) ) diff --git a/goal_src/jak3/levels/desert/rescue/neo-satellite.gc b/goal_src/jak3/levels/desert/rescue/neo-satellite.gc index 19fd7610df..4bb6d1b4e4 100644 --- a/goal_src/jak3/levels/desert/rescue/neo-satellite.gc +++ b/goal_src/jak3/levels/desert/rescue/neo-satellite.gc @@ -2183,7 +2183,10 @@ ) (set! (-> s3-0 quad) (-> this node-list data gp-0 bone transform fvec quad)) (let ((gp-1 (-> this ropes (-> *neo-sat-laser-array* arg0 rope-index)))) - (set! (-> gp-1 knots data 0 mass) (the-as float #x7f800000)) + ;; og:preserve-this made infinite mass slightly less infinite. + ;; PS2 does math on this float, and it behaves like an extremely large float rather than + ;; IEEE754 inf. + (set! (-> gp-1 knots data 0 mass) (the-as float #x7f700000)) (if (and (-> this next-state) (= (-> this next-state name) 'neo-sat-sit-and-spin)) (set! (-> gp-1 gravity-dir quad) (-> s3-0 quad)) ) diff --git a/goal_src/jak3/levels/desert/wvehicle/w-parking-spot.gc b/goal_src/jak3/levels/desert/wvehicle/w-parking-spot.gc index 0f11c6562f..e062438ebd 100644 --- a/goal_src/jak3/levels/desert/wvehicle/w-parking-spot.gc +++ b/goal_src/jak3/levels/desert/wvehicle/w-parking-spot.gc @@ -244,11 +244,7 @@ (w-parking-spot-method-23 self) ) (until #f - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.25)) - (suspend) - ) - ) + (suspend-for (seconds 0.25)) (w-parking-spot-method-21 self) (when (-> self should-spawn?) (let ((f0-0 (vector-vector-distance-squared (camera-pos) (-> self test-sphere))) diff --git a/goal_src/jak3/levels/desert/wvehicle/was-squad-control.gc b/goal_src/jak3/levels/desert/wvehicle/was-squad-control.gc index d246a25557..1c492e0290 100644 --- a/goal_src/jak3/levels/desert/wvehicle/was-squad-control.gc +++ b/goal_src/jak3/levels/desert/wvehicle/was-squad-control.gc @@ -183,7 +183,7 @@ ) ) (when s4-0 - (let ((s5-1 (new 'stack-no-clear 'inline-array 'matrix 2))) + (let ((s5-1 (new 'stack-no-clear 'inline-array 'matrix 4))) (let* ((s3-0 (-> s5-1 0)) (a2-0 (camera-matrix)) (v1-4 (-> a2-0 rvec quad)) diff --git a/goal_src/jak3/levels/desert/wvehicle/wcar-marauder.gc b/goal_src/jak3/levels/desert/wvehicle/wcar-marauder.gc index eb8bafc667..4b52e79288 100644 --- a/goal_src/jak3/levels/desert/wvehicle/wcar-marauder.gc +++ b/goal_src/jak3/levels/desert/wvehicle/wcar-marauder.gc @@ -491,10 +491,6 @@ (if (and *target* (focus-test? *target* pilot-riding)) (turbo-pickup-spawn (-> self root trans)) ) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) ) diff --git a/goal_src/jak3/levels/desert/wvehicle/wvehicle-states.gc b/goal_src/jak3/levels/desert/wvehicle/wvehicle-states.gc index d9bbe553bf..f2fff7a603 100644 --- a/goal_src/jak3/levels/desert/wvehicle/wvehicle-states.gc +++ b/goal_src/jak3/levels/desert/wvehicle/wvehicle-states.gc @@ -229,11 +229,7 @@ (defstate waiting (wvehicle) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (when (-> self minimap) diff --git a/goal_src/jak3/levels/desert/wvehicle/wvehicle.gc b/goal_src/jak3/levels/desert/wvehicle/wvehicle.gc index ff3a5f746f..b358c1b5a1 100644 --- a/goal_src/jak3/levels/desert/wvehicle/wvehicle.gc +++ b/goal_src/jak3/levels/desert/wvehicle/wvehicle.gc @@ -600,9 +600,9 @@ (defmethod vehicle-method-88 ((this wvehicle) (arg0 vehicle-controls)) (set! (-> arg0 steering) (analog-input (the-as int (-> *cpad-list* cpads 0 leftx)) 128.0 48.0 110.0 -1.0)) (set! (-> arg0 lean-z) (analog-input (the-as int (-> *cpad-list* cpads 0 lefty)) 128.0 48.0 110.0 -1.0)) - (set! (-> arg0 throttle) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton 6))))) - (set! (-> arg0 brake) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton 7))))) - (set! (-> arg0 handbrake) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton 5))))) + (set! (-> arg0 throttle) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton (abutton-idx x)))))) ;; og:preserve-this abutton indexing + (set! (-> arg0 brake) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton (abutton-idx square)))))) ;; og:preserve-this abutton indexing + (set! (-> arg0 handbrake) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton (abutton-idx circle)))))) ;; og:preserve-this abutton indexing (cond ((-> *setting-control* user-current jump) (if (cpad-hold? 0 l1) diff --git a/goal_src/jak3/levels/factory/car/hvehicle.gc b/goal_src/jak3/levels/factory/car/hvehicle.gc index 9b8229bc09..6913fca869 100644 --- a/goal_src/jak3/levels/factory/car/hvehicle.gc +++ b/goal_src/jak3/levels/factory/car/hvehicle.gc @@ -473,8 +473,8 @@ ) (set! (-> arg0 steering) (analog-input (the-as int (-> *cpad-list* cpads 0 leftx)) 128.0 48.0 110.0 -1.0)) (set! (-> arg0 lean-z) (analog-input (the-as int (-> *cpad-list* cpads 0 lefty)) 128.0 48.0 110.0 -1.0)) - (set! (-> arg0 throttle) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton 6))))) - (set! (-> arg0 brake) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton 7))))) + (set! (-> arg0 throttle) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton (abutton-idx x)))))) ;; og:preserve-this abutton indexing + (set! (-> arg0 brake) (fmin 1.0 (* 0.023529412 (the float (-> *cpad-list* cpads 0 abutton (abutton-idx square)))))) ;; og:preserve-this abutton indexing (when (or (cpad-hold? 0 l1) (and (logtest? (-> this info flags) 2048) (cpad-hold? 0 r1))) (if (logtest? (-> this info flags) 16) (logior! (-> arg0 flags) (vehicle-controls-flag vcf0)) @@ -1208,11 +1208,7 @@ :enter (behavior () (rlet ((vf0 :class vf)) (init-vf0-vector) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (let ((gp-0 (-> self child))) (while gp-0 (send-event (ppointer->process gp-0) 'traffic-off) diff --git a/goal_src/jak3/levels/factory/car/wcar-faccar.gc b/goal_src/jak3/levels/factory/car/wcar-faccar.gc index 71953fc443..f30f980cb8 100644 --- a/goal_src/jak3/levels/factory/car/wcar-faccar.gc +++ b/goal_src/jak3/levels/factory/car/wcar-faccar.gc @@ -158,35 +158,31 @@ process (lambda :behavior process ((arg0 handle)) - (let ((s5-0 (current-time)) - (s4-0 (current-time)) - ) - (until (time-elapsed? s4-0 (seconds 0.65)) - (when (time-elapsed? s5-0 (seconds 0.06)) - (set! s5-0 (current-time)) - (let ((s3-0 (handle->process arg0))) - (process-drawable-shock-effect - (the-as process-drawable s3-0) - (-> *lightning-spec-id-table* 1) - lightning-probe-callback - (-> *part-id-table* 160) - 0 - 0 - 40960.0 - ) - (process-drawable-shock-effect - (the-as process-drawable s3-0) - (-> *lightning-spec-id-table* 1) - lightning-probe-callback - (-> *part-id-table* 160) - 0 - 0 - 40960.0 - ) - ) - ) - (suspend) - ) + (let ((s5-0 (current-time))) + (suspend-for (seconds 0.65) (when (time-elapsed? s5-0 (seconds 0.06)) + (set! s5-0 (current-time)) + (let ((s3-0 (handle->process arg0))) + (process-drawable-shock-effect + (the-as process-drawable s3-0) + (-> *lightning-spec-id-table* 1) + lightning-probe-callback + (-> *part-id-table* 160) + 0 + 0 + 40960.0 + ) + (process-drawable-shock-effect + (the-as process-drawable s3-0) + (-> *lightning-spec-id-table* 1) + lightning-probe-callback + (-> *part-id-table* 160) + 0 + 0 + 40960.0 + ) + ) + ) + ) ) #f ) diff --git a/goal_src/jak3/levels/factory/fac-gunturret.gc b/goal_src/jak3/levels/factory/fac-gunturret.gc index e56f0b95a0..f63af294ff 100644 --- a/goal_src/jak3/levels/factory/fac-gunturret.gc +++ b/goal_src/jak3/levels/factory/fac-gunturret.gc @@ -626,28 +626,26 @@ (sound-group) (-> self root trans) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.75)) - (let ((s5-2 (new 'stack-no-clear 'vector))) - (set! (-> s5-2 quad) (-> self aim-pos quad)) - (track-target self #t) - (vector-! s5-2 (-> self aim-pos) s5-2) - (when (time-elapsed? (-> self snd-cmd-time) (seconds 0.12)) - 0.0 - (vector-length s5-2) - (sound-play-by-name - (static-sound-name "smallturret-rot") - (-> self rotate-sound) - 1024 - (the int (* 1524.0 (* 0.5 (doppler-pitch-shift (-> self root trans) (-> self root transv))))) - 0 - (sound-group) - (-> self root trans) - ) - (set-time! (-> self snd-cmd-time)) + (suspend-for + (seconds 0.75) + (let ((s5-2 (new 'stack-no-clear 'vector))) + (set! (-> s5-2 quad) (-> self aim-pos quad)) + (track-target self #t) + (vector-! s5-2 (-> self aim-pos) s5-2) + (when (time-elapsed? (-> self snd-cmd-time) (seconds 0.12)) + 0.0 + (vector-length s5-2) + (sound-play-by-name + (static-sound-name "smallturret-rot") + (-> self rotate-sound) + 1024 + (the int (* 1524.0 (* 0.5 (doppler-pitch-shift (-> self root trans) (-> self root transv))))) + 0 + (sound-group) + (-> self root trans) ) + (set-time! (-> self snd-cmd-time)) ) - (suspend) ) ) (when (-> self rotate-sound-playing) @@ -830,18 +828,9 @@ (let ((gp-1 (new 'stack-no-clear 'vector))) (set! (-> gp-1 quad) (-> self root trans quad)) (+! (-> gp-1 y) 12288.0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 2)) - (spawn (-> self part) gp-1) - (suspend) - ) - ) - ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 2) (spawn (-> self part) gp-1)) ) + (suspend-for (seconds 1)) (send-event self 'death-end) (while (-> self child) (suspend) diff --git a/goal_src/jak3/levels/factory/fac-robotank-turret.gc b/goal_src/jak3/levels/factory/fac-robotank-turret.gc index 58fe1b4af3..f97b970f94 100644 --- a/goal_src/jak3/levels/factory/fac-robotank-turret.gc +++ b/goal_src/jak3/levels/factory/fac-robotank-turret.gc @@ -714,11 +714,7 @@ ) (logior! (-> self flags) (fac-robotank-turret-flag frt3)) (set! (-> self firing-sight-pos quad) (-> self sight-pos quad)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (let ((gp-2 (max 2 (min 3 (rand-vu-int-range 0 3))))) 0 (dotimes (s5-2 gp-2) @@ -744,12 +740,8 @@ ) ) ) - (let ((f30-0 (rand-vu-float-range 0.05 0.43)) - (s4-2 (current-time)) - ) - (until (time-elapsed? s4-2 (the int (* 300.0 f30-0))) - (suspend) - ) + (let ((f30-0 (rand-vu-float-range 0.05 0.43))) + (suspend-for (the int (* 300.0 f30-0))) ) ) ) @@ -766,11 +758,8 @@ 2.11 ) ) - (gp-3 (current-time)) ) - (until (time-elapsed? gp-3 (the int (* 300.0 f30-1))) - (suspend) - ) + (suspend-for (the int (* 300.0 f30-1))) ) ) #f @@ -787,11 +776,7 @@ ) 0 (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while (-> self child) (suspend) ) diff --git a/goal_src/jak3/levels/factory/fac-robotank.gc b/goal_src/jak3/levels/factory/fac-robotank.gc index 47f7acc43d..5c1948eebc 100644 --- a/goal_src/jak3/levels/factory/fac-robotank.gc +++ b/goal_src/jak3/levels/factory/fac-robotank.gc @@ -492,11 +492,7 @@ ) :code (behavior () (logclear! (-> self flags) (robotank-flag r2)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) (logior! (-> self flags) (robotank-flag r2)) (sleep-code) ) @@ -660,11 +656,7 @@ ) 0 (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (while (-> self child) (suspend) ) diff --git a/goal_src/jak3/levels/factory/fac-tower.gc b/goal_src/jak3/levels/factory/fac-tower.gc index ef82ac1a65..caefb816b0 100644 --- a/goal_src/jak3/levels/factory/fac-tower.gc +++ b/goal_src/jak3/levels/factory/fac-tower.gc @@ -263,11 +263,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) ) :post ja-post ) diff --git a/goal_src/jak3/levels/factory/factory-manager.gc b/goal_src/jak3/levels/factory/factory-manager.gc index 30233164f4..ff38a23a21 100644 --- a/goal_src/jak3/levels/factory/factory-manager.gc +++ b/goal_src/jak3/levels/factory/factory-manager.gc @@ -1782,11 +1782,7 @@ :virtual #t :enter (behavior () (send-event (handle->process (-> self hud-damage)) 'hide-and-die) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) ) diff --git a/goal_src/jak3/levels/factory/factoryc-obs.gc b/goal_src/jak3/levels/factory/factoryc-obs.gc index 17a2cf18a5..e7f618dcc6 100644 --- a/goal_src/jak3/levels/factory/factoryc-obs.gc +++ b/goal_src/jak3/levels/factory/factoryc-obs.gc @@ -1062,78 +1062,75 @@ (defstate flickering (factory-elec-gate) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (let ((s5-0 (the-as int (rand-uint31-gen *random-generator*)))) - (let ((s4-0 0) - (s3-0 3) - ) - (while (>= s3-0 s4-0) - (cond - ((logtest? s5-0 1) - (when (not (-> self beams-on s4-0)) - (let ((v1-8 (-> self beams s4-0)) - (a0-1 1) - ) - (let ((a1-1 (!= a0-1 (-> v1-8 state mode)))) - (case a0-1 - ((3) - (if a1-1 - (set! (-> v1-8 state counter) 0.0) - ) - ) - ((1) - (set! (-> v1-8 state start-color) (-> v1-8 spec start-color)) - (set! (-> v1-8 state end-color) (-> v1-8 spec end-color)) - ) - ) + (suspend-for + (seconds 3) + (let ((s5-0 (the-as int (rand-uint31-gen *random-generator*)))) + (let ((s4-0 0) + (s3-0 3) + ) + (while (>= s3-0 s4-0) + (cond + ((logtest? s5-0 1) + (when (not (-> self beams-on s4-0)) + (let ((v1-8 (-> self beams s4-0)) + (a0-1 1) + ) + (let ((a1-1 (!= a0-1 (-> v1-8 state mode)))) + (case a0-1 + ((3) + (if a1-1 + (set! (-> v1-8 state counter) 0.0) + ) + ) + ((1) + (set! (-> v1-8 state start-color) (-> v1-8 spec start-color)) + (set! (-> v1-8 state end-color) (-> v1-8 spec end-color)) + ) ) - (set! (-> v1-8 state mode) (the-as uint a0-1)) ) - (set! (-> self beams-on s4-0) #t) - (set-factoryc-light! 1.0 1) + (set! (-> v1-8 state mode) (the-as uint a0-1)) ) + (set! (-> self beams-on s4-0) #t) + (set-factoryc-light! 1.0 1) ) - (else - (when (-> self beams-on s4-0) - (let ((v1-17 (-> self beams s4-0)) - (a0-5 3) - ) - (let ((a1-12 (!= a0-5 (-> v1-17 state mode)))) - (case a0-5 - ((3) - (if a1-12 - (set! (-> v1-17 state counter) 0.0) - ) - ) - ((1) - (set! (-> v1-17 state start-color) (-> v1-17 spec start-color)) - (set! (-> v1-17 state end-color) (-> v1-17 spec end-color)) - ) - ) + ) + (else + (when (-> self beams-on s4-0) + (let ((v1-17 (-> self beams s4-0)) + (a0-5 3) + ) + (let ((a1-12 (!= a0-5 (-> v1-17 state mode)))) + (case a0-5 + ((3) + (if a1-12 + (set! (-> v1-17 state counter) 0.0) + ) + ) + ((1) + (set! (-> v1-17 state start-color) (-> v1-17 spec start-color)) + (set! (-> v1-17 state end-color) (-> v1-17 spec end-color)) + ) ) - (set! (-> v1-17 state mode) (the-as uint a0-5)) ) - (set! (-> self beams-on s4-0) #f) - (set-factoryc-light! 0.0 1) + (set! (-> v1-17 state mode) (the-as uint a0-5)) ) + (set! (-> self beams-on s4-0) #f) + (set-factoryc-light! 0.0 1) ) ) - (set! s5-0 (/ s5-0 2)) - (+! s4-0 1) ) + (set! s5-0 (/ s5-0 2)) + (+! s4-0 1) ) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.1)) - (if (logand s5-0 1) - (sound-play "laser-loop" :id (-> self bzzt-sound) :position (-> self entity trans)) - ) - (suspend) + ) + (suspend-for + (seconds 0.1) + (if (logand s5-0 1) + (sound-play "laser-loop" :id (-> self bzzt-sound) :position (-> self entity trans)) ) - ) ) - (suspend) ) + (empty-form) ) (process-entity-status! self (entity-perm-status subtask-complete) #t) (process-entity-status! self (entity-perm-status dead) #t) diff --git a/goal_src/jak3/levels/factory/factoryc-obs2.gc b/goal_src/jak3/levels/factory/factoryc-obs2.gc index d150f2594b..43f24c7559 100644 --- a/goal_src/jak3/levels/factory/factoryc-obs2.gc +++ b/goal_src/jak3/levels/factory/factoryc-obs2.gc @@ -836,15 +836,13 @@ (process-entity-status! self (entity-perm-status subtask-complete) #t) (cond ((not arg0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.3)) - (let* ((f28-0 (lerp-clamp 0.0 3640.889 (* 0.011111111 (the float (- (current-time) (-> self state-time)))))) - (f30-0 (cos f28-0)) - (f0-2 (sin f28-0)) - ) - (quaternion-set! (-> self lever-jmod rotation) f0-2 0.0 0.0 f30-0) - ) - (suspend) + (suspend-for + (seconds 0.3) + (let* ((f28-0 (lerp-clamp 0.0 3640.889 (* 0.011111111 (the float (- (current-time) (-> self state-time)))))) + (f30-0 (cos f28-0)) + (f0-2 (sin f28-0)) + ) + (quaternion-set! (-> self lever-jmod rotation) f0-2 0.0 0.0 f30-0) ) ) (let ((gp-2 (res-lump-struct (-> self entity) 'cutaway-camera structure))) @@ -853,12 +851,7 @@ (suspend) ) (set-setting! 'entity-name gp-2 0.0 0) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 3)) - '() - (suspend) - ) - ) + (suspend-for (seconds 3) '()) (remove-setting! 'entity-name) (while (not (process-release? *target*)) (suspend) @@ -1027,18 +1020,10 @@ :virtual #t :event plat-event :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) ) :code (behavior () - (let ((t9-1 (-> (find-parent-state) code))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler code) ) ) @@ -1094,14 +1079,12 @@ :trans plat-trans :code (behavior () (let ((f30-0 (-> self dead-set-time))) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (set! (-> self path-pos) - (lerp-clamp (get-norm! (-> self sync) 0) f30-0 (* 0.0011111111 (the float (- (current-time) gp-0)))) - ) - (get-point-at-percent-along-path! (-> self path) (-> self basetrans) (-> self path-pos) 'interp) - (suspend) - ) + (suspend-for + (seconds 3) + (set! (-> self path-pos) + (lerp-clamp (get-norm! (-> self sync) 0) f30-0 (* 0.0011111111 (the float (- (current-time) time)))) + ) + (get-point-at-percent-along-path! (-> self path) (-> self basetrans) (-> self path-pos) 'interp) ) (suspend) (set! (-> self path-pos) f30-0) @@ -1183,18 +1166,10 @@ ) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) ) :code (behavior () - (let ((t9-1 (-> (find-parent-state) code))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler code) ) ) diff --git a/goal_src/jak3/levels/factory/lfacrm2-mood.gc b/goal_src/jak3/levels/factory/lfacrm2-mood.gc index 481bdbc1b1..848e7fceb4 100644 --- a/goal_src/jak3/levels/factory/lfacrm2-mood.gc +++ b/goal_src/jak3/levels/factory/lfacrm2-mood.gc @@ -22,11 +22,7 @@ :virtual #t :enter (behavior () (set! (-> self mysound) (sound-play "elevator-a")) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (sound-stop (-> self mysound)) @@ -57,11 +53,7 @@ (-> gp-0 id) ) ) - (let ((t9-5 (-> (find-parent-state) trans))) - (if t9-5 - (t9-5) - ) - ) + (call-parent-state-handler trans) ) :code (behavior () (when (not (nonzero? (res-lump-value (-> self entity) 'start-gate-up uint128 :time -1000000000.0))) @@ -71,11 +63,7 @@ (ja :num! (seek! max 1.333)) ) ) - (let ((t9-5 (-> (find-parent-state) code))) - (if t9-5 - ((the-as (function none) t9-5)) - ) - ) + (call-parent-state-handler code) ) ) @@ -101,12 +89,7 @@ (defstate dormant (fac-elevator-a) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.5)) - '() - (suspend) - ) - ) + (suspend-for (seconds 1.5) '()) (ja-no-eval :group! fac-elevator-a-gate_down-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) (suspend) diff --git a/goal_src/jak3/levels/factory/warf-projectile.gc b/goal_src/jak3/levels/factory/warf-projectile.gc index 0c21658eda..97f3945447 100644 --- a/goal_src/jak3/levels/factory/warf-projectile.gc +++ b/goal_src/jak3/levels/factory/warf-projectile.gc @@ -627,11 +627,7 @@ ) (process-spawn warf-explosion-sphere gp-0 :name "warf-explosion-sphere" :to self) ) - (let ((t9-8 (-> (find-parent-state) enter))) - (if t9-8 - (t9-8) - ) - ) + (call-parent-state-handler enter) ) :code (behavior () (while (< (-> self hit-pos w) 245760.0) diff --git a/goal_src/jak3/levels/forest/forest-ring-chase.gc b/goal_src/jak3/levels/forest/forest-ring-chase.gc index 76e73f549b..5d8856fdac 100644 --- a/goal_src/jak3/levels/forest/forest-ring-chase.gc +++ b/goal_src/jak3/levels/forest/forest-ring-chase.gc @@ -525,11 +525,7 @@ (if (nonzero? (-> self sound-id)) (sound-stop (-> self sound-id)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 8)) - (suspend) - ) - ) + (suspend-for (seconds 8)) ) ) @@ -1037,14 +1033,10 @@ (part-tracker-spawn part-tracker :to self :group (-> *part-group-id-table* 584) :duration (seconds 1)) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (if (nonzero? (-> self sound-id)) - (sound-play "statue-expl-bu" :id (-> self sound-id)) - ) - (suspend) - ) - ) + (suspend-for (seconds 1) (if (nonzero? (-> self sound-id)) + (sound-play "statue-expl-bu" :id (-> self sound-id)) + ) + ) (if (nonzero? (-> self sound-id)) (sound-stop (-> self sound-id)) ) @@ -1079,11 +1071,7 @@ (transform-post) (sound-play "statue-explode") (for-statue-method-28 self) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) (cleanup-for-death self) (let ((a1-15 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-15 from) (process->ppointer self)) @@ -2304,12 +2292,7 @@ ) (suspend) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 3)) - (format *stdebug* "task-manager-forest-ring-chase: done!~%") - (suspend) - ) - ) + (suspend-for (seconds 3) (format *stdebug* "task-manager-forest-ring-chase: done!~%")) (while (-> self use-camera?) (suspend) ) diff --git a/goal_src/jak3/levels/forest/forest-tasks.gc b/goal_src/jak3/levels/forest/forest-tasks.gc index 1f079ebbd5..726e4be2c6 100644 --- a/goal_src/jak3/levels/forest/forest-tasks.gc +++ b/goal_src/jak3/levels/forest/forest-tasks.gc @@ -67,11 +67,7 @@ :virtual #t :code (behavior () (local-vars (a1-12 event-message-block) (gp-3 symbol)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (until (and (-> self manager-entity) (= (-> *game-info* counter) 0.0)) (suspend) (if (not (-> self manager-entity)) @@ -147,11 +143,7 @@ (until (process-grab? *target* #f) (suspend) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) (let ((a1-14 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-14 from) (process->ppointer self)) (set! (-> a1-14 num-params) 0) @@ -281,11 +273,7 @@ (suspend) (set! (-> self manager-entity) (entity-by-name "for-machine-manager-1")) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (let ((gp-1 (-> self entity extra perm))) (logior! (-> gp-1 status) (entity-perm-status bit-5)) (when (zero? (-> gp-1 user-object 0)) @@ -303,11 +291,7 @@ ) (set! (-> gp-1 user-object 0) (+ (the-as int (-> gp-1 user-object 0)) 1)) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (set! sv-16 (new 'static 'res-tag)) (let ((v1-33 (res-lump-data (-> self manager-entity) 'actor-groups pointer :tag-ptr (& sv-16)))) (cond diff --git a/goal_src/jak3/levels/gungame/gun-dummy.gc b/goal_src/jak3/levels/gungame/gun-dummy.gc index 714921cda8..2db67101b0 100644 --- a/goal_src/jak3/levels/gungame/gun-dummy.gc +++ b/goal_src/jak3/levels/gungame/gun-dummy.gc @@ -1058,11 +1058,7 @@ ((time-elapsed? (-> self arm-start-time) (seconds 2)) ) ) - (let ((t9-5 (-> (find-parent-state) trans))) - (if t9-5 - (t9-5) - ) - ) + (call-parent-state-handler trans) ) ) diff --git a/goal_src/jak3/levels/gungame/gungame-manager.gc b/goal_src/jak3/levels/gungame/gungame-manager.gc index 74777eeccc..5602ca0f23 100644 --- a/goal_src/jak3/levels/gungame/gungame-manager.gc +++ b/goal_src/jak3/levels/gungame/gungame-manager.gc @@ -1476,11 +1476,7 @@ '() ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (if (search-process-tree *active-pool* (lambda ((arg0 process)) (type? arg0 gungame-manager))) (return 0) ) @@ -1614,22 +1610,10 @@ ) (set-setting! 'features 'clear (shr t1-0 32) t1-0) ) - (cond - ((>= 1 (-> self course-list length)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) - ) - (else - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) - ) + (if (>= 1 (-> self course-list length)) + (suspend-for (seconds 1)) + (suspend-for (seconds 0.5)) ) - ) (let ((gp-2 (get-process *default-dead-pool* (-> self activated-course etype) #x4000 1))) (when gp-2 (let ((t9-3 (method-of-type process activate))) diff --git a/goal_src/jak3/levels/gungame/gungame-obs.gc b/goal_src/jak3/levels/gungame/gungame-obs.gc index 84f30bd37d..59f9056009 100644 --- a/goal_src/jak3/levels/gungame/gungame-obs.gc +++ b/goal_src/jak3/levels/gungame/gungame-obs.gc @@ -135,12 +135,7 @@ :event gungame-door-handler :code (behavior () (sound-play "gungame-door") - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.2)) - (suspend) - (suspend) - ) - ) + (suspend-for (seconds 0.2) (suspend)) (ja-no-eval :group! fort-entry-gate-idle-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) (suspend) diff --git a/goal_src/jak3/levels/intro/intro-scenes.gc b/goal_src/jak3/levels/intro/intro-scenes.gc index 59d88f73c8..c3eb9731f8 100644 --- a/goal_src/jak3/levels/intro/intro-scenes.gc +++ b/goal_src/jak3/levels/intro/intro-scenes.gc @@ -225,9 +225,9 @@ ) (set! (-> gp-0 scale-x) 1.0) (set! (-> gp-0 scale-y) 1.0) - (when (and s5-0 (-> gp-0 tid)) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 (seconds 3)) + (if (and s5-0 (-> gp-0 tid)) + (suspend-for + (seconds 3) (let ((f0-2 1.0)) (cond ((< f30-0 1.0) @@ -247,10 +247,8 @@ (if (not (paused?)) (+! f30-0 (seconds-per-frame)) ) - (suspend) ) ) - ) ) (none) ) @@ -301,9 +299,9 @@ (set-vector! (-> gp-0 pos) 256 188 #xffffff 0) (set! (-> gp-0 tid) (the-as texture-id (get-texture JakIII inttitle-minimap))) (set! (-> s5-0 tid) (the-as texture-id #f)) - (when (and s4-0 (-> gp-0 tid)) - (let ((s3-0 (current-time))) - (until (time-elapsed? s3-0 (seconds 4.33)) + (if (and s4-0 (-> gp-0 tid)) + (suspend-for + (seconds 4.33) (let ((f0-2 1.0)) (cond ((< f30-0 0.5) @@ -327,10 +325,8 @@ (if (not (paused?)) (+! f30-0 (seconds-per-frame)) ) - (suspend) ) ) - ) ) (none) ) @@ -349,14 +345,10 @@ (lambda :behavior scene-player () (talker-spawn-func (-> *talker-speech* 61) self (target-pos 0) (the-as region #f)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 5)) - (if (cpad-pressed? 0 square) - (return #f) - ) - (suspend) - ) - ) + (suspend-for (seconds 5) (if (cpad-pressed? 0 square) + (return #f) + ) + ) (none) ) :to self diff --git a/goal_src/jak3/levels/mhcity/destroy-dark-eco.gc b/goal_src/jak3/levels/mhcity/destroy-dark-eco.gc index 15b986e7fa..9c7991e8f7 100644 --- a/goal_src/jak3/levels/mhcity/destroy-dark-eco.gc +++ b/goal_src/jak3/levels/mhcity/destroy-dark-eco.gc @@ -237,11 +237,7 @@ ) 0 (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while *scene-player* (suspend) ) @@ -278,11 +274,7 @@ (part-tracker-spawn part-tracker :to *entity-pool* :group (-> *part-group-id-table* 325) :mat-joint gp-1) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) (logior! (-> self draw status) (draw-control-status no-draw)) (let ((t0-2 (res-lump-struct (-> self entity) 'camera-name structure))) (if t0-2 @@ -1215,11 +1207,7 @@ ) (send-event *target* 'change-mode 'darkjak #f (darkjak-stage force-on active)) ) - (let ((t9-3 (-> (find-parent-state) trans))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler trans) ) ) diff --git a/goal_src/jak3/levels/mhcity/mhcity-obs.gc b/goal_src/jak3/levels/mhcity/mhcity-obs.gc index ed882605f0..10269b2ad9 100644 --- a/goal_src/jak3/levels/mhcity/mhcity-obs.gc +++ b/goal_src/jak3/levels/mhcity/mhcity-obs.gc @@ -862,11 +862,7 @@ (ja :num! (seek!)) ) (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (task-node-close! (game-task-node city-destroy-darkeco-resolution) 'event) (sleep-code) ) @@ -919,11 +915,7 @@ (label cfg-9) (ja-channel-push! 1 (seconds 0.5)) (ja :group! mhcity-dark-eco-door-idle-ja :num! (seek! 15.0) :frame-num 15.0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (go-virtual cracked) ) #f @@ -1093,11 +1085,7 @@ (part-tracker-spawn part-tracker :to *entity-pool* :group (-> *part-group-id-table* 326)) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) (process-entity-status! self (entity-perm-status dead) #t) ) :post ja-post diff --git a/goal_src/jak3/levels/mhcity/mhcity-obs2.gc b/goal_src/jak3/levels/mhcity/mhcity-obs2.gc index 401db8bdc0..2fa10c25b0 100644 --- a/goal_src/jak3/levels/mhcity/mhcity-obs2.gc +++ b/goal_src/jak3/levels/mhcity/mhcity-obs2.gc @@ -374,11 +374,7 @@ :virtual #t :parent (mhcity-puffer-large puffer-active-base-state) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) ) :code (behavior () (ja-channel-push! 1 (seconds 0.1)) @@ -397,11 +393,7 @@ :virtual #t :parent (mhcity-puffer-large puffer-active-base-state) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) ) :code (behavior () (ja-channel-push! 1 (seconds 0.1)) diff --git a/goal_src/jak3/levels/mine/gekko.gc b/goal_src/jak3/levels/mine/gekko.gc index ce7400ec98..5da6f47688 100644 --- a/goal_src/jak3/levels/mine/gekko.gc +++ b/goal_src/jak3/levels/mine/gekko.gc @@ -1948,11 +1948,7 @@ (ja-channel-push! 1 (seconds 0.4)) (ja-no-eval :group! gekko-run0-a-ja :num! (seek!) :frame-num 0.0) (enable-ragdoll! (-> (the-as ragdoll-proc (handle->process (-> self ragdoll-proc))) ragdoll) self) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.4)) - (suspend) - ) - ) + (suspend-for (seconds 0.4)) (if (enemy-method-109 self) (go-die self) (go-hostile self) diff --git a/goal_src/jak3/levels/mine/mine-obs.gc b/goal_src/jak3/levels/mine/mine-obs.gc index a967ad9a83..89bfeef6ec 100644 --- a/goal_src/jak3/levels/mine/mine-obs.gc +++ b/goal_src/jak3/levels/mine/mine-obs.gc @@ -569,11 +569,7 @@ (suspend) (ja :num! (seek! max 0.03)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (go-virtual inactive) ) :post (behavior () @@ -1322,11 +1318,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (let ((a1-0 (new 'stack-no-clear 'array 'symbol 3))) (set! (-> a1-0 2) 'mine6) (set! (-> a1-0 1) 'mine5) @@ -1642,11 +1634,7 @@ :virtual #t :code (behavior () (sound-play "floor-switch") - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (when (not (task-node-closed? (game-task-node mine-blow-introduction))) (let ((a1-1 (new 'stack-no-clear 'array 'symbol 3))) (set! (-> a1-1 2) 'mine6) diff --git a/goal_src/jak3/levels/mine/mine-platforms.gc b/goal_src/jak3/levels/mine/mine-platforms.gc index e20f5509f2..fe008cb64c 100644 --- a/goal_src/jak3/levels/mine/mine-platforms.gc +++ b/goal_src/jak3/levels/mine/mine-platforms.gc @@ -437,11 +437,7 @@ ) :code (behavior () (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (let ((gp-1 (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> self root quat))) (s5-0 (vector-x-quaternion! (new 'stack-no-clear 'vector) (-> self root quat))) (s4-0 #t) @@ -614,11 +610,7 @@ :trans plat-trans :code (behavior () (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (ja-channel-push! 1 0) (ja-no-eval :group! min-rotating-plat-idle-ja :num! min) (sync-now! (-> self sync) 0.0) @@ -1233,11 +1225,7 @@ ) :trans rider-trans :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.5)) - (suspend) - ) - ) + (suspend-for (seconds 1.5)) (when (-> self stop-sound) (set! (-> self stop-sound) #f) (sound-params-set! *gui-control* (-> self sound-id) #t -1 -1 -1 -1.0) @@ -1432,11 +1420,7 @@ ) :code (behavior () (when (-> self play-ramp-sound?) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) (until (= (get-status *gui-control* (-> self ramp-sound)) (gui-status ready)) (suspend) ) @@ -1598,11 +1582,7 @@ :trans rider-trans :code (behavior () (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.5)) - (suspend) - ) - ) + (suspend-for (seconds 1.5)) (when (-> self stop-bridge-sound) (set! (-> self stop-bridge-sound) #f) (sound-params-set! *gui-control* (-> self bridge-sound) #t -1 150 2 -1.0) diff --git a/goal_src/jak3/levels/mine/mine-train.gc b/goal_src/jak3/levels/mine/mine-train.gc index e3404eb0b1..222832304d 100644 --- a/goal_src/jak3/levels/mine/mine-train.gc +++ b/goal_src/jak3/levels/mine/mine-train.gc @@ -483,11 +483,7 @@ (quaternion-normalize! (-> self root quat)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (when (type? (-> self root) collide-shape) (let ((v1-7 (-> self root root-prim))) (set! (-> v1-7 prim-core collide-as) (collide-spec)) diff --git a/goal_src/jak3/levels/mine/rat.gc b/goal_src/jak3/levels/mine/rat.gc index 7c4a954c9b..259301b9d4 100644 --- a/goal_src/jak3/levels/mine/rat.gc +++ b/goal_src/jak3/levels/mine/rat.gc @@ -737,11 +737,7 @@ (if (enemy-method-109 self) (go-virtual die) ) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) ) @@ -2000,11 +1996,7 @@ (logior! (-> self entity extra perm status) (entity-perm-status subtask-complete)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (while (-> self child) (suspend) ) diff --git a/goal_src/jak3/levels/nest/egg-spider.gc b/goal_src/jak3/levels/nest/egg-spider.gc index 0f5e8fd4d7..bacb680b75 100644 --- a/goal_src/jak3/levels/nest/egg-spider.gc +++ b/goal_src/jak3/levels/nest/egg-spider.gc @@ -1330,11 +1330,7 @@ (part-tracker-spawn part-tracker :to *entity-pool* :group (-> *part-group-id-table* 639)) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.6)) - (suspend) - ) - ) + (suspend-for (seconds 0.6)) (let ((v1-38 (-> self root root-prim))) (set! (-> v1-38 prim-core collide-as) (-> self root backup-collide-as)) (set! (-> v1-38 prim-core collide-with) (-> self root backup-collide-with)) @@ -1357,11 +1353,7 @@ ) ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) (ja-channel-push! 1 0) (ja-no-eval :group! egg-spider-crawl-from-ground-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) diff --git a/goal_src/jak3/levels/nest/mh-bat.gc b/goal_src/jak3/levels/nest/mh-bat.gc index c9278b55a7..3aa7442cd8 100644 --- a/goal_src/jak3/levels/nest/mh-bat.gc +++ b/goal_src/jak3/levels/nest/mh-bat.gc @@ -1172,11 +1172,7 @@ (defstate ambush (mh-bat) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set-time! (-> self state-time)) (set! (-> self start-pos quad) (-> self root trans quad)) (set-vector! (-> self root transv) 0.0 -81920.0 0.0 0.0) @@ -1298,11 +1294,7 @@ (defstate hostile (mh-bat) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self bank-angle) 0.0) (set! (-> self pitch-angle) 0.0) (set! (-> self orbit-distance) (* 4096.0 (rnd-float-range self 17.0 30.0))) diff --git a/goal_src/jak3/levels/nest/nst-obs.gc b/goal_src/jak3/levels/nest/nst-obs.gc index 4830f53e52..be735a089c 100644 --- a/goal_src/jak3/levels/nest/nst-obs.gc +++ b/goal_src/jak3/levels/nest/nst-obs.gc @@ -140,11 +140,7 @@ ) ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (cleanup-for-death self) ) ) @@ -713,11 +709,7 @@ (when (-> self actor-group) (let ((f30-0 (* 0.0005 (the float (-> self actor-group length))))) (dotimes (gp-8 (-> self actor-group length)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (the int (* 300.0 f30-0))) - (suspend) - ) - ) + (suspend-for (the int (* 300.0 f30-0))) (let ((a1-24 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-24 from) (process->ppointer self)) (set! (-> a1-24 num-params) 0) @@ -1190,11 +1182,7 @@ ) :code (behavior () (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) (when (-> self anim) (-> self draw bounds w) (set! (-> self draw bounds w) 737280.0) @@ -1727,19 +1715,9 @@ (set! (-> self cycling?) #t) (spawn (-> self charge-up-part) (-> self node-list data 12 bone transform trans)) (set! (-> self cycle-rot) -1820.4445) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (ja :num! (loop!)) - (suspend) - ) - ) + (suspend-for (seconds 0.5) (ja :num! (loop!))) (set! (-> self cycle-rot) 1820.4445) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (ja :num! (loop!)) - (suspend) - ) - ) + (suspend-for (seconds 0.5) (ja :num! (loop!))) (set! (-> self cycling?) #f) (set! (-> self shots-left) (the-as uint 4)) (set! (-> self can-shoot?) #f) @@ -1918,19 +1896,11 @@ (if (>= (-> self palette-id) 0) (set-nstb-lights! (-> self palette-id) 4.0 8.0 #f) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (if (>= (-> self palette-id) 0) (set-nstb-lights! (-> self palette-id) 0.0 6.0 #f) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 0.35)) - (suspend) - ) - ) + (suspend-for (seconds 0.35)) (let ((gp-6 (-> self child))) (while gp-6 (send-event (ppointer->process gp-6) 'notice 'die) diff --git a/goal_src/jak3/levels/precursor/precura-obs.gc b/goal_src/jak3/levels/precursor/precura-obs.gc index 738a3f1256..90f344dfa2 100644 --- a/goal_src/jak3/levels/precursor/precura-obs.gc +++ b/goal_src/jak3/levels/precursor/precura-obs.gc @@ -22,24 +22,20 @@ process (lambda :behavior process () - (let ((gp-0 (current-time)) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 (seconds 1)) - (when (time-elapsed? gp-0 (seconds 0.03)) - (set! gp-0 (current-time)) - (process-drawable-shock-effect - *target* - (-> *lightning-spec-id-table* 1) - lightning-probe-callback - (-> *part-id-table* 160) - 0 - 0 - 40960.0 - ) - ) - (suspend) - ) + (let ((gp-0 (current-time))) + (suspend-for (seconds 1) (when (time-elapsed? gp-0 (seconds 0.03)) + (set! gp-0 (current-time)) + (process-drawable-shock-effect + *target* + (-> *lightning-spec-id-table* 1) + lightning-probe-callback + (-> *part-id-table* 160) + 0 + 0 + 40960.0 + ) + ) + ) ) #f ) @@ -1046,27 +1042,15 @@ ) (logior! (-> self draw status) (draw-control-status no-draw)) (transform-post) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1.2)) - (suspend) - ) - ) + (suspend-for (seconds 1.2)) (when (res-lump-struct (-> self entity) 'art-name structure) (logclear! (-> self mask) (process-mask actor-pause)) (process-grab? *target* #f) (set-setting! 'entity-name "camera-359" 0.0 0) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (task-close! "precursor-tour-generator-trigger") (send-event (process-by-name "precur-door-b-4" *active-pool*) 'open) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (set-setting! 'interp-time 'abs 450.0 0) (remove-setting! 'entity-name) (process-release? *target*) @@ -2510,11 +2494,7 @@ (not (and (-> self entity) (logtest? (-> self entity extra perm status) (entity-perm-status subtask-complete))) ) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.5)) - (suspend) - ) - ) + (suspend-for (seconds 1.5)) (set-setting! 'entity-name "camera-420" 0.0 0) (process-grab? *target* #f) (process-entity-status! self (entity-perm-status subtask-complete) #t) @@ -2588,11 +2568,7 @@ ) :code (behavior () (when (-> self precur-tour?) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2.5)) - (suspend) - ) - ) + (suspend-for (seconds 2.5)) (remove-setting! 'entity-name) (process-release? *target*) ) diff --git a/goal_src/jak3/levels/precursor/precura-obs2.gc b/goal_src/jak3/levels/precursor/precura-obs2.gc index cca8cd359d..adfe87a2e2 100644 --- a/goal_src/jak3/levels/precursor/precura-obs2.gc +++ b/goal_src/jak3/levels/precursor/precura-obs2.gc @@ -1658,11 +1658,7 @@ (let ((gp-0 (res-lump-data (-> self entity) 'actor-groups pointer :tag-ptr (& sv-16)))) (cond ((and gp-0 (nonzero? (-> sv-16 elt-count))) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (set! (-> self actor-group-count) (the-as int (-> sv-16 elt-count))) (set! (-> self actor-group) (the-as (pointer actor-group) gp-0)) (dotimes (gp-1 (length (-> self actor-group 0))) diff --git a/goal_src/jak3/levels/sewer/mh-wasp.gc b/goal_src/jak3/levels/sewer/mh-wasp.gc index 8d0ed61432..4f7cde4335 100644 --- a/goal_src/jak3/levels/sewer/mh-wasp.gc +++ b/goal_src/jak3/levels/sewer/mh-wasp.gc @@ -830,11 +830,7 @@ 0 (set! (-> self hit-points) 0.0) (do-effect (-> self skel effect) (the-as string 'death-default) 0.0 -1) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event self 'death-end) (cleanup-for-death self) ) diff --git a/goal_src/jak3/levels/sewer/neo-juicer.gc b/goal_src/jak3/levels/sewer/neo-juicer.gc index adf9776699..a088860bab 100644 --- a/goal_src/jak3/levels/sewer/neo-juicer.gc +++ b/goal_src/jak3/levels/sewer/neo-juicer.gc @@ -1219,57 +1219,56 @@ (s5-0 (+ (-> v1-29 attack-id) 1)) ) (set! (-> v1-29 attack-id) s5-0) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 (seconds 0.25)) - (ja-no-eval :group! neo-juicer-attack0-ja :num! (seek!) :frame-num 0.0) - (until (ja-done? 0) - (let ((s3-0 (handle->process (-> self focus handle)))) - (when s3-0 - (when (< 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable s3-0) 0))) - (spawn-proj! self (the-as process-focusable s3-0) s5-0) - (current-time) - (if (not gp-0) - (set! gp-0 #t) - ) - ) - ) - ) - (if (and (logtest? (-> self enemy-flags) (enemy-flag victory)) (-> self enemy-info use-victory)) - (go-virtual victory) + (suspend-for + (seconds 0.25) + (ja-no-eval :group! neo-juicer-attack0-ja :num! (seek!) :frame-num 0.0) + (until (ja-done? 0) + (let ((s3-0 (handle->process (-> self focus handle)))) + (when s3-0 + (when (< 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable s3-0) 0))) + (spawn-proj! self (the-as process-focusable s3-0) s5-0) + (current-time) + (if (not gp-0) + (set! gp-0 #t) + ) ) - (b! - (not (and (-> self using-turn-anim) (let ((v1-73 (ja-group))) - (not (and v1-73 (= v1-73 neo-juicer-attack-turn-ja))) - ) - ) - ) - cfg-31 - :delay (empty-form) - ) - (ja-channel-push! 1 (seconds 0.05)) - (ja :group! neo-juicer-attack-turn-ja) - (b! #t cfg-42 :delay (nop!)) - (label cfg-31) - (when (and (not (-> self using-turn-anim)) (let ((v1-84 (ja-group))) - (not (and v1-84 (= v1-84 neo-juicer-attack0-ja))) - ) - ) - (ja-channel-push! 1 (seconds 0.05)) - (ja :group! neo-juicer-attack0-ja) ) - (label cfg-42) - (suspend) - (ja :num! (seek!)) ) - (send-event (handle->process (-> self current-projectile)) 'die) - (let ((a0-37 (handle->process (-> self focus handle)))) - (when a0-37 - (if (>= 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable a0-37) 0))) - (go-virtual circling) - ) + (if (and (logtest? (-> self enemy-flags) (enemy-flag victory)) (-> self enemy-info use-victory)) + (go-virtual victory) ) + (b! + (not (and (-> self using-turn-anim) (let ((v1-73 (ja-group))) + (not (and v1-73 (= v1-73 neo-juicer-attack-turn-ja))) + ) + ) + ) + cfg-31 + :delay (empty-form) ) + (ja-channel-push! 1 (seconds 0.05)) + (ja :group! neo-juicer-attack-turn-ja) + (b! #t cfg-42 :delay (nop!)) + (label cfg-31) + (when (and (not (-> self using-turn-anim)) (let ((v1-84 (ja-group))) + (not (and v1-84 (= v1-84 neo-juicer-attack0-ja))) + ) + ) + (ja-channel-push! 1 (seconds 0.05)) + (ja :group! neo-juicer-attack0-ja) + ) + (label cfg-42) (suspend) + (ja :num! (seek!)) + ) + (empty-form) + (send-event (handle->process (-> self current-projectile)) 'die) + (let ((a0-37 (handle->process (-> self focus handle)))) + (when a0-37 + (if (>= 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable a0-37) 0))) + (go-virtual circling) + ) + ) ) ) ) diff --git a/goal_src/jak3/levels/sewer/saberfish.gc b/goal_src/jak3/levels/sewer/saberfish.gc index c875528628..40018d8bb2 100644 --- a/goal_src/jak3/levels/sewer/saberfish.gc +++ b/goal_src/jak3/levels/sewer/saberfish.gc @@ -1010,11 +1010,7 @@ :virtual #t :enter (behavior () (sound-play "sabfish-gethit") - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) ) @@ -1024,11 +1020,7 @@ (if (saberfish-method-243 self) (go-virtual swimming-hostile) ) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () (let ((a0-1 (handle->process (-> self focus handle)))) @@ -1041,11 +1033,7 @@ (handle-cmd self a1-2) ) ) - (let ((t9-4 (-> (find-parent-state) trans))) - (if t9-4 - (t9-4) - ) - ) + (call-parent-state-handler trans) ) :post saberfish-chase-post ) @@ -2954,11 +2942,7 @@ (set! (-> self swim-travel-anim) 0) 0 ) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (set! (-> self scare-time) 0) @@ -2997,13 +2981,9 @@ ) ) (saberfish-swim-travel-trans) - (when (>= (the-as int (-> self focus aware)) 2) - (let ((t9-9 (-> (find-parent-state) trans))) - (if t9-9 - (t9-9) - ) + (if (>= (the-as int (-> self focus aware)) 2) + (call-parent-state-handler trans) ) - ) ) :code (behavior () (saberfish-swim-code) @@ -3135,18 +3115,10 @@ :enter (behavior () (set! (-> self knocked-under-water?) #f) (set! (-> self move-to-ground?) #f) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) ) ) @@ -3186,11 +3158,7 @@ (if (saberfish-method-243 self) (go-virtual knocked-recover-water) ) - (let ((t9-4 (-> (find-parent-state) enter))) - (if t9-4 - (t9-4) - ) - ) + (call-parent-state-handler enter) ) :code (behavior () (if (handle->process (-> self ragdoll-proc)) @@ -3198,11 +3166,7 @@ ) (ja-channel-push! 1 0) (ja-no-eval :group! saberfish-flip-up-start-ja :num! (seek!) :frame-num 0.0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.4)) - (suspend) - ) - ) + (suspend-for (seconds 0.4)) (ja-channel-push! 1 0) (ja-no-eval :group! saberfish-flip-up-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) diff --git a/goal_src/jak3/levels/sewer/sew-laser-guard.gc b/goal_src/jak3/levels/sewer/sew-laser-guard.gc index 607e2eaf8f..9a632bd393 100644 --- a/goal_src/jak3/levels/sewer/sew-laser-guard.gc +++ b/goal_src/jak3/levels/sewer/sew-laser-guard.gc @@ -578,18 +578,9 @@ (let ((gp-1 (new 'stack-no-clear 'vector))) (set! (-> gp-1 quad) (-> self root trans quad)) (+! (-> gp-1 y) 10240.0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 2)) - (spawn (-> self part) gp-1) - (suspend) - ) - ) - ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 2) (spawn (-> self part) gp-1)) ) + (suspend-for (seconds 1)) (send-event self 'death-end) (while (-> self child) (suspend) diff --git a/goal_src/jak3/levels/sewer/sew-laser-turret.gc b/goal_src/jak3/levels/sewer/sew-laser-turret.gc index 6f47ac3be7..9d7dbdcc0a 100644 --- a/goal_src/jak3/levels/sewer/sew-laser-turret.gc +++ b/goal_src/jak3/levels/sewer/sew-laser-turret.gc @@ -640,7 +640,7 @@ (let ((dist (-> turret target-distance))) (and (-> turret target-on-ground) (>= dist (+ radius (meters -0.1))) - (>= dist (+ radius (meters 0.1))) + (>= (+ radius (meters 0.1)) dist) ) ) ) @@ -1054,18 +1054,9 @@ (let ((gp-1 (new 'stack-no-clear 'vector))) (set! (-> gp-1 quad) (-> self root trans quad)) (+! (-> gp-1 y) 10240.0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 2)) - (spawn (-> self part) gp-1) - (suspend) - ) - ) - ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 2) (spawn (-> self part) gp-1)) ) + (suspend-for (seconds 1)) (send-event self 'death-end) (while (-> self child) (suspend) diff --git a/goal_src/jak3/levels/sewer/sew-platforms.gc b/goal_src/jak3/levels/sewer/sew-platforms.gc index 9873ec4afd..698f1c00eb 100644 --- a/goal_src/jak3/levels/sewer/sew-platforms.gc +++ b/goal_src/jak3/levels/sewer/sew-platforms.gc @@ -131,18 +131,10 @@ :virtual #t :enter (behavior () (set! (-> self last-played-start?) #f) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (cond ((and (-> self last-played-start?) (< 0.9 (-> self path-pos))) (sound-play "moving-step-out") @@ -207,19 +199,11 @@ :virtual #t :enter (behavior () (set! (-> self last-played-start?) #f) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self last-val) -1.0) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (when (< (-> self path-pos) 0.5) (new 'stack-no-clear 'vector) (let ((gp-0 (new 'stack-no-clear 'matrix))) diff --git a/goal_src/jak3/levels/sewer/sewer-obs.gc b/goal_src/jak3/levels/sewer/sewer-obs.gc index 24bf17519c..f0ca75067f 100644 --- a/goal_src/jak3/levels/sewer/sewer-obs.gc +++ b/goal_src/jak3/levels/sewer/sewer-obs.gc @@ -203,11 +203,7 @@ (defstate active (sew-cam-sequencer) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (until (process-grab? *target* #f) (suspend) ) @@ -216,21 +212,13 @@ (sew-cam-eval-script a0-1) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (-> self timeout)) - (suspend) - ) - ) + (suspend-for (-> self timeout)) (let ((a0-3 (-> self activate-script))) (if a0-3 (sew-cam-eval-script a0-3) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (the-as time-frame (-> self offset))) - (suspend) - ) - ) + (suspend-for (the-as time-frame (-> self offset))) (let ((a0-5 (-> self exit-script))) (if a0-5 (sew-cam-eval-script a0-5) @@ -1304,20 +1292,12 @@ ) (let ((v1-25 (res-lump-value (-> self entity) 'extra-id uint128 :time -1000000000.0))) (when (= (the-as uint v1-25) 1) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (set-setting! 'mode-name 'cam-fixed 0.0 0) (set-setting! 'interp-time 'abs 0.0 0) (set-setting! 'entity-name "camera-300" 0.0 0) (process-grab? *target* #f) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (let ((gp-2 (-> self actor-group 1))) (dotimes (s5-0 (-> gp-2 length)) (let ((a1-7 (new 'stack-no-clear 'event-message-block))) @@ -1337,19 +1317,11 @@ ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (remove-setting! 'mode-name) (remove-setting! 'interp-time) (remove-setting! 'entity-name) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (process-release? *target*) (go-virtual opened) ) @@ -1756,11 +1728,7 @@ (set-setting! 'entity-name "camera-224" 0.0 0) (set-setting! 'allow-progress #f 0.0 0) (process-grab? *target* #f) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (task-node-close! (game-task-node sewer-hum-kg-switch-off) 'event) (script-eval '(send-event "ctyinda-vingate-1" 'shutdown)) (set-action! @@ -1774,11 +1742,7 @@ (the-as process #f) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 2.4)) - (suspend) - ) - ) + (suspend-for (seconds 2.4)) (set-setting! 'string-startup-vector 'abs (new 'static 'vector :x 1.0) 0) (remove-setting! 'entity-name) (set! (-> *ACTOR-bank* birth-max) 1000) diff --git a/goal_src/jak3/levels/sewer/sewer-obs2.gc b/goal_src/jak3/levels/sewer/sewer-obs2.gc index 08db43d3bd..977985896c 100644 --- a/goal_src/jak3/levels/sewer/sewer-obs2.gc +++ b/goal_src/jak3/levels/sewer/sewer-obs2.gc @@ -217,20 +217,12 @@ :virtual #t :code (behavior () (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (set-setting! 'mode-name 'cam-fixed 0.0 0) (set-setting! 'interp-time 'abs 0.0 0) (set-setting! 'entity-name "camera-353" 0.0 0) (process-grab? *target* #f) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (sound-play "gate-open") (ja-no-eval :group! sew-m-gate-gate-open-ja :num! (seek! max 0.1) :frame-num 0.0) (until (ja-done? 0) @@ -241,11 +233,7 @@ (remove-setting! 'mode-name) (remove-setting! 'interp-time) (remove-setting! 'entity-name) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (process-release? *target*) (go-virtual raised) ) @@ -369,20 +357,12 @@ :virtual #t :code (behavior () (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (set-setting! 'mode-name 'cam-fixed 0.0 0) (set-setting! 'interp-time 'abs 0.0 0) (set-setting! 'entity-name "camera-352" 0.0 0) (process-grab? *target* #f) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (sound-play "pipe-lower") (set-time! (-> self state-time)) (ja-no-eval :group! sew-pipe-down-ja :num! (seek! max 0.1) :frame-num 0.0) @@ -397,11 +377,7 @@ (remove-setting! 'mode-name) (remove-setting! 'interp-time) (remove-setting! 'entity-name) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (process-release? *target*) (go-virtual down) ) diff --git a/goal_src/jak3/levels/stadium/dm-mine-spider.gc b/goal_src/jak3/levels/stadium/dm-mine-spider.gc index fcb83fad16..8504fa710b 100644 --- a/goal_src/jak3/levels/stadium/dm-mine-spider.gc +++ b/goal_src/jak3/levels/stadium/dm-mine-spider.gc @@ -1055,22 +1055,14 @@ (set-time! (-> self state-time)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.6)) - (suspend) - ) - ) + (suspend-for (seconds 0.6)) (let ((v1-6 (-> self root root-prim))) (set! (-> v1-6 prim-core collide-as) (-> self root backup-collide-as)) (set! (-> v1-6 prim-core collide-with) (-> self root backup-collide-with)) ) (logclear! (-> self draw status) (draw-control-status no-draw)) (update-focus self) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) (ja-channel-push! 1 0) (ja-no-eval :group! dm-mine-spider-climb-start-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) diff --git a/goal_src/jak3/levels/temple/hover-training.gc b/goal_src/jak3/levels/temple/hover-training.gc index 861af18549..d74565290e 100644 --- a/goal_src/jak3/levels/temple/hover-training.gc +++ b/goal_src/jak3/levels/temple/hover-training.gc @@ -827,18 +827,10 @@ (until (process-grab? *target* #f) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (persist-with-delay *setting-control* 'interp-time (seconds 4) 'interp-time 'abs 0.0 0) (set-setting! 'entity-name "camera-354" 0.0 0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) (task-node-close! (game-task-node temple-tests-hover-training) 'event) (until (process-release? *target*) (suspend) diff --git a/goal_src/jak3/levels/temple/temple-obs.gc b/goal_src/jak3/levels/temple/temple-obs.gc index 805b2640ed..4ac33ae7d8 100644 --- a/goal_src/jak3/levels/temple/temple-obs.gc +++ b/goal_src/jak3/levels/temple/temple-obs.gc @@ -392,18 +392,10 @@ (set! (-> gp-0 map-icon) (the-as uint 13)) (set! (-> self arrow-h) (process->handle (task-arrow-spawn gp-0 self))) ) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (when (-> self arrow-h) (let ((gp-0 (-> self arrow-h process 0))) (when (and (< (vector-vector-distance (-> (the-as process-drawable gp-0) root trans) (target-pos 0)) 20480.0) @@ -471,11 +463,7 @@ (if (and *target* (focus-test? *target* light)) (send-event self 'complete) ) - (let ((t9-3 (-> (find-parent-state) trans))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler trans) ) ) @@ -933,11 +921,7 @@ (until (process-grab? *target* #f) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) ) ) (set-time! (-> self state-time)) @@ -958,11 +942,7 @@ (set! (-> self root scale z) (-> self root scale x)) (when (= (-> self root scale x) 0.0) (send-event (handle->process (-> self perm-part)) 'die) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (until (process-release? *target*) (suspend) ) @@ -1753,44 +1733,27 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (the int (-> self cycle-offset))) - (suspend) - ) - ) + (suspend-for (the int (-> self cycle-offset))) (until #f - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (the int (-> self cycle-time))) - (suspend) - ) - ) + (suspend-for (the int (-> self cycle-time))) (sound-play "fan-shake" :position (-> self root trans)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.01)) - (let ((f0-5 (* 36408.89 (the float (- (current-time) gp-3)))) - (f1-3 (* 0.33333334 (- 3.0 (the float (- (current-time) gp-3))))) - ) - (set! (-> self shudder-angle) (* 0.0018204444 f1-3 (sin f0-5))) - ) - (suspend) - ) - ) + (suspend-for (seconds 0.01) (let ((f0-5 (* 36408.89 (the float (- (current-time) time)))) + (f1-3 (* 0.33333334 (- 3.0 (the float (- (current-time) time))))) + ) + (set! (-> self shudder-angle) (* 0.0018204444 f1-3 (sin f0-5))) + ) + ) (set! (-> self shudder-angle) 0.0) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.04)) - (suspend) - ) - ) + (suspend-for (seconds 0.04)) (sound-play "fan-turn" :position (-> self root trans)) (let* ((f0-9 100.0) (f30-1 (* 16384.0 f0-9)) - (gp-6 (current-time)) ) - (until (time-elapsed? gp-6 (seconds 0.01)) + (suspend-for + (seconds 0.01) (set! (-> self rot-angle) (the float (sar (shl (the int (+ (-> self rot-angle) (* f30-1 (seconds-per-frame)))) 48) 48)) ) - (suspend) ) ) (let ((v1-47 #x4000)) @@ -2159,11 +2122,7 @@ (script-eval (the-as pair gp-0)) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (cleanup-for-death self) (deactivate self) ) @@ -2324,11 +2283,7 @@ (script-eval (the-as pair gp-0)) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (cleanup-for-death self) (deactivate self) ) diff --git a/goal_src/jak3/levels/temple/temple-obs2.gc b/goal_src/jak3/levels/temple/temple-obs2.gc index 0a2cbaeb60..f54a99ceca 100644 --- a/goal_src/jak3/levels/temple/temple-obs2.gc +++ b/goal_src/jak3/levels/temple/temple-obs2.gc @@ -99,10 +99,7 @@ (suspend) ) (set-setting! 'entity-name "camera-356" 0.0 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) ) (sound-play "gate-raise") @@ -112,10 +109,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (let ((a1-6 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-6 from) (process->ppointer self)) @@ -133,16 +127,10 @@ ) ) (when (= (-> self extra-id) 1) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (remove-setting! 'entity-name) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 2.5)) - (suspend) - ) + (suspend-for (seconds 2.5) ) (until (process-release? *target*) (suspend) @@ -267,9 +255,9 @@ (within-outer-ring symbol) (within-inner-ring symbol) (ouched symbol) - (bound-cam basic) + (bound-cam string) (trans vector :inline) - (state-time uint64) + (state-time time-frame) (jak-in-hint-region symbol) (watchers-vulnerable symbol) ) @@ -376,7 +364,7 @@ (logior! (-> v1-8 status) (entity-perm-status bit-14)) ) ) - (set! (-> self bound-cam) (the-as basic (-> arg3 param 0))) + (set! (-> self bound-cam) (the-as string (-> arg3 param 0))) (set! (-> self ouched) #t) (go-virtual until-watchers-dead) ) @@ -421,10 +409,7 @@ :event tpl-watcher-manager-ehandler :trans watcher-man-trans :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (and *target* (focus-test? *target* dead)) (suspend) @@ -437,7 +422,7 @@ :virtual #t :event tpl-watcher-manager-ehandler :enter (behavior () - (set! (-> self state-time) (the-as uint (current-time))) + (set-time! (-> self state-time)) ) :trans watcher-man-trans :code (behavior () @@ -448,10 +433,7 @@ (suspend) ) (process-entity-status! self (entity-perm-status no-kill) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2.5)) - (suspend) - ) + (suspend-for (seconds 2.5) ) (while (not (process-release? *target*)) (suspend) @@ -481,7 +463,7 @@ ) ) ) - (until (time-elapsed? (the-as int (-> self state-time)) (seconds 1)) + (until (time-elapsed? (-> self state-time) (seconds 1)) (suspend) ) (task-close! "temple-oracle-watchers-complete") @@ -581,7 +563,7 @@ standing-down ) (:methods - (tpl-watcher-method-32 (_type_) none) + (init-collision! (_type_) none) ) ) @@ -865,6 +847,8 @@ ) ) (suspend) + ;; og:preserve-this fix vf0 clobbering after suspend + (init-vf0-vector) (set! v1-32 (- (current-time) s4-0)) (let ((a0-14 (-> self manager))) (set! a1-12 (if a0-14 @@ -934,11 +918,8 @@ ) ) (sound-play "wtcher-fire") - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - '() - (suspend) - ) + (suspend-for (seconds 1) + '() ) ) ) @@ -1007,10 +988,7 @@ ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 4)) - (suspend) - ) + (suspend-for (seconds 4) ) (while (-> self child) (suspend) @@ -1045,16 +1023,14 @@ :code (behavior () (let ((gp-0 (-> self root quat)) (s5-0 (-> self entity quat)) - (s4-0 (current-time)) ) - (until (time-elapsed? s4-0 (seconds 1.5)) + (suspend-for (seconds 1.5) (quaternion-slerp! (-> self root quat) gp-0 s5-0 (* 0.0022222223 (the float (- (current-time) (-> self state-time)))) ) - (suspend) ) ) (go-virtual idle) @@ -1063,7 +1039,7 @@ ) ;; WARN: Return type mismatch collide-shape-moving vs none. -(defmethod tpl-watcher-method-32 ((this tpl-watcher)) +(defmethod init-collision! ((this tpl-watcher)) (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player)))) (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process)) (set! (-> s5-0 reaction) cshape-reaction-default) @@ -1118,7 +1094,7 @@ (defmethod init-from-entity! ((this tpl-watcher) (arg0 entity-actor)) (local-vars (sv-16 res-tag)) (stack-size-set! (-> this main-thread) 384) - (tpl-watcher-method-32 this) + (init-collision! this) (process-drawable-from-entity! this arg0) (logior! (-> this mask) (process-mask enemy)) (initialize-skeleton @@ -1665,10 +1641,8 @@ ) (quaternion-normalize! s5-2) (set-time! (-> self state-time)) - (let ((f30-1 (lerp-scale 45.0 9.0 (-> self clock clock-ratio) 1.0 0.05)) - (s4-2 (current-time)) - ) - (until (time-elapsed? s4-2 (the int f30-1)) + (let ((f30-1 (lerp-scale 45.0 9.0 (-> self clock clock-ratio) 1.0 0.05))) + (suspend-for (the int f30-1) (quaternion-slerp! (-> self root quat) gp-3 @@ -1676,7 +1650,6 @@ (/ (the float (- (current-time) (-> self state-time))) f30-1) ) (quaternion-normalize! (-> self root quat)) - (suspend) ) ) (quaternion-copy! (-> self root quat) s5-2) @@ -1694,12 +1667,9 @@ :virtual #t :trans rider-trans :code (behavior () - (let ((f30-0 (res-lump-float (-> self entity) 'tpl-platform-predelay)) - (gp-0 (current-time)) - ) - (until (time-elapsed? gp-0 (the int (* 300.0 f30-0))) + (let ((f30-0 (res-lump-float (-> self entity) 'tpl-platform-predelay))) + (suspend-for (the int (* 300.0 f30-0)) '() - (suspend) ) ) (go-virtual flip) @@ -1754,11 +1724,8 @@ :code (behavior () (set-time! (-> self state-time)) (set! (-> self state-time) (-> *display* real-clock frame-counter)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.25)) - '() - (suspend) - ) + (suspend-for (seconds 0.25) + '() ) (while (< (+ (-> *display* real-clock frame-counter) (seconds -1)) (-> self last-ridden)) (suspend) @@ -1920,11 +1887,7 @@ :virtual #t :enter (behavior () (setup-masks (-> self draw) 3 0) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (setup-masks (-> self draw) 1 2) diff --git a/goal_src/jak3/levels/title/title-obs.gc b/goal_src/jak3/levels/title/title-obs.gc index 95ce2230b4..0ba5d872e5 100644 --- a/goal_src/jak3/levels/title/title-obs.gc +++ b/goal_src/jak3/levels/title/title-obs.gc @@ -192,10 +192,7 @@ (cond ((and (kiosk?) (or (cpad-pressed? 0 square) (time-elapsed? s5-1 (seconds 60)))) (initialize! *game-info* 'game (the-as game-save #f) (the-as string #f) (the-as resetter-spec #f)) - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) (set! s5-1 (current-time)) ) @@ -256,10 +253,7 @@ #x33001 #t ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.4)) - (suspend) - ) + (suspend-for (seconds 0.4) ) (send-event (ppointer->process (-> *setting-control* user-current movie)) 'abort) (set! (-> *setting-control* user-current bg-a) 0.0) @@ -549,7 +543,7 @@ (set! (-> t0-2 y) 1.0) (set! (-> t0-2 z) 0.0) (set! (-> t0-2 w) 1.0) - (t9-6 (the-as bucket-id a0-31) (the-as art-group a1-15) (the-as int a2-5) a3-7 t0-2 (-> self level) 8) + (t9-6 a0-31 (the-as bucket-id a1-15) a2-5 a3-7 t0-2 (-> self level) 8) ) (set! (-> self active) #t) ) @@ -568,10 +562,7 @@ :code (behavior () (remove-setting! 'allow-timeout) (remove-setting! 'dialog-volume) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event (ppointer->process (-> self logo)) @@ -601,10 +592,7 @@ ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (remove-setting! 'dust-storm-fog-scalar) (if (zero? (title-menu)) @@ -628,10 +616,7 @@ ) ) (until (= (-> *game-info* current-continue level) 'title) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) ) (go-virtual wait) @@ -972,10 +957,7 @@ ) ) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.6)) - (suspend) - ) + (suspend-for (seconds 0.6) ) (process-spawn-function process @@ -1306,8 +1288,8 @@ (set! (-> self zoom) (fmax (fmin (-> self zoom) (-> self char zoom-max)) (-> self char zoom-min))) ) ) - (let ((f1-11 (the float (-> v1-7 abutton 9))) - (f0-18 (the float (-> v1-7 abutton 8))) + (let ((f1-11 (the float (-> v1-7 abutton (abutton-idx r1)))) ;; og:preserve-this abutton indexing + (f0-18 (the float (-> v1-7 abutton (abutton-idx l1)))) ;; og:preserve-this abutton indexing ) (+! (-> self updown) (* 50.0 (seconds-per-frame) f1-11)) (set! (-> self updown) (- (-> self updown) (* 50.0 (seconds-per-frame) f0-18))) diff --git a/goal_src/jak3/levels/tower/tower-obs.gc b/goal_src/jak3/levels/tower/tower-obs.gc index 97fc52c7bf..1b02b9b18c 100644 --- a/goal_src/jak3/levels/tower/tower-obs.gc +++ b/goal_src/jak3/levels/tower/tower-obs.gc @@ -347,11 +347,7 @@ :virtual #t :code (behavior () (logclear! (-> self draw status) (draw-control-status force-fade)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (process-spawn scene-player :init scene-player-init @@ -524,11 +520,7 @@ (set-time! (-> self state-time)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.75)) - (suspend) - ) - ) + (suspend-for (seconds 0.75)) (let ((v1-6 (-> self root root-prim))) (set! (-> v1-6 prim-core collide-as) (-> self root backup-collide-as)) (set! (-> v1-6 prim-core collide-with) (-> self root backup-collide-with)) @@ -537,15 +529,13 @@ (logclear! (-> self draw status) (draw-control-status no-draw)) (let ((f30-0 1.0)) 0.0 - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (the int (* 300.0 f30-0))) - (let ((f0-2 (fmax 0.0 (fmin 1.0 (/ (the float (- (current-time) gp-2)) (* 300.0 f30-0)))))) - (set-vector! (-> self draw color-mult) f0-2 f0-2 f0-2 1.0) - ) - (spawn-from-cspace (-> self part) (joint-node tow-energy-bridge-lod0-jg main)) - (ja-post) - (suspend) + (suspend-for + (the int (* 300.0 f30-0)) + (let ((f0-2 (fmax 0.0 (fmin 1.0 (/ (the float (- (current-time) time)) (* 300.0 f30-0)))))) + (set-vector! (-> self draw color-mult) f0-2 f0-2 f0-2 1.0) ) + (spawn-from-cspace (-> self part) (joint-node tow-energy-bridge-lod0-jg main)) + (ja-post) ) ) (process-entity-status! self (entity-perm-status subtask-complete) #t) diff --git a/goal_src/jak3/levels/volcano/spiky-frog.gc b/goal_src/jak3/levels/volcano/spiky-frog.gc index 3dd82d20ea..9beedb79f0 100644 --- a/goal_src/jak3/levels/volcano/spiky-frog.gc +++ b/goal_src/jak3/levels/volcano/spiky-frog.gc @@ -919,13 +919,11 @@ :num! (identity (the float (+ (-> (the-as art-joint-anim spiky-frog-ball0-end-ja) frames num-frames) -1))) ) (enable-ragdoll! (-> (the-as ragdoll-proc (handle->process (-> self ragdoll-proc))) ragdoll) self) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.411)) - (if (!= (-> self root gspot-pos y) -40959590.0) - (seek! (-> self root trans y) (-> self root gspot-pos y) (* 409600.0 (seconds-per-frame))) - ) - (suspend) - ) + (suspend-for + (seconds 0.411) + (if (!= (-> self root gspot-pos y) -40959590.0) + (seek! (-> self root trans y) (-> self root gspot-pos y) (* 409600.0 (seconds-per-frame))) + ) ) ) (else diff --git a/goal_src/jak3/levels/volcano/volcano-obs.gc b/goal_src/jak3/levels/volcano/volcano-obs.gc index 5e2fb36691..dc76babc0f 100644 --- a/goal_src/jak3/levels/volcano/volcano-obs.gc +++ b/goal_src/jak3/levels/volcano/volcano-obs.gc @@ -925,11 +925,7 @@ (set! (-> self stopped-up-by) (the-as handle #f)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (let ((a1-0 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-0 from) (process->ppointer self)) (set! (-> a1-0 num-params) 0) diff --git a/goal_src/jak3/levels/volcano/volcano-obs2.gc b/goal_src/jak3/levels/volcano/volcano-obs2.gc index 039763985a..597b85dae1 100644 --- a/goal_src/jak3/levels/volcano/volcano-obs2.gc +++ b/goal_src/jak3/levels/volcano/volcano-obs2.gc @@ -59,11 +59,7 @@ :virtual #t :event rigid-body-object-event-handler :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (get-point-at-percent-along-path! (-> self path) (-> self rbody position) (-> self path-u) 'interp) (ja-no-eval :group! vol-lava-plat-idle-ja :num! zero) (logclear! (-> self mask) (process-mask actor-pause)) diff --git a/goal_src/jak3/levels/volcano/volcanox-obs.gc b/goal_src/jak3/levels/volcano/volcanox-obs.gc index 52dba41f2d..2679466204 100644 --- a/goal_src/jak3/levels/volcano/volcanox-obs.gc +++ b/goal_src/jak3/levels/volcano/volcanox-obs.gc @@ -360,11 +360,7 @@ (until (process-grab? *target* #f) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) ) ) (set-time! (-> self state-time)) @@ -385,11 +381,7 @@ (set! (-> self root scale z) (-> self root scale x)) (when (= (-> self root scale x) 0.0) (send-event (handle->process (-> self perm-part)) 'die) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (until (process-release? *target*) (suspend) ) diff --git a/goal_src/jak3/levels/wascity/defend/was-pre-game.gc b/goal_src/jak3/levels/wascity/defend/was-pre-game.gc index e86243dd8d..b62b89a1a9 100644 --- a/goal_src/jak3/levels/wascity/defend/was-pre-game.gc +++ b/goal_src/jak3/levels/wascity/defend/was-pre-game.gc @@ -1807,11 +1807,7 @@ ) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (-> self start-delay)) - (suspend) - ) - ) + (suspend-for (-> self start-delay)) (go-virtual fall) ) :post (behavior () @@ -2077,11 +2073,7 @@ (sound-play "lose-icon") (send-event (ppointer->process (-> self parent)) 'done) (set! (-> self post-hook) #f) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.2)) - (suspend) - ) - ) + (suspend-for (seconds 0.2)) ) :post (behavior () (vector-normalize! diff --git a/goal_src/jak3/levels/wascity/dm-flyer.gc b/goal_src/jak3/levels/wascity/dm-flyer.gc index 4be6c1f2f4..af71a88ae0 100644 --- a/goal_src/jak3/levels/wascity/dm-flyer.gc +++ b/goal_src/jak3/levels/wascity/dm-flyer.gc @@ -169,11 +169,7 @@ ) ) :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) @@ -251,11 +247,7 @@ (defstate dissipate (dm-flyer-shot) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) diff --git a/goal_src/jak3/levels/wascity/maker-projectile.gc b/goal_src/jak3/levels/wascity/maker-projectile.gc index 4fc10fb159..d49c592d54 100644 --- a/goal_src/jak3/levels/wascity/maker-projectile.gc +++ b/goal_src/jak3/levels/wascity/maker-projectile.gc @@ -697,11 +697,7 @@ ) ) :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) @@ -769,12 +765,7 @@ (set! (-> v1-85 prim-core collide-with) (collide-spec)) ) 0 - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 3)) - (suspend) - (suspend) - ) - ) + (suspend-for (seconds 3) (suspend)) ) ) diff --git a/goal_src/jak3/levels/wascity/palace/waspala-obs.gc b/goal_src/jak3/levels/wascity/palace/waspala-obs.gc index fc183a3fcb..7b44323875 100644 --- a/goal_src/jak3/levels/wascity/palace/waspala-obs.gc +++ b/goal_src/jak3/levels/wascity/palace/waspala-obs.gc @@ -205,11 +205,7 @@ ) (let ((gp-0 27)) (set-setting! 'change-gun #t 0.0 0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 5)) - (suspend) - ) - ) + (suspend-for (seconds 5)) (set! (-> self gui-id) (add-process *gui-control* self (gui-channel message) (gui-action play) (-> self name) 81920.0 0) ) diff --git a/goal_src/jak3/levels/wascity/tizard.gc b/goal_src/jak3/levels/wascity/tizard.gc index dde0eeaa56..3d6406435e 100644 --- a/goal_src/jak3/levels/wascity/tizard.gc +++ b/goal_src/jak3/levels/wascity/tizard.gc @@ -72,12 +72,8 @@ ) :code (behavior () (when (-> self first-run?) - (let ((gp-0 (the int (* 300.0 (rand-vu-float-range 0.05 0.12)))) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 gp-0) - (suspend) - ) + (let ((gp-0 (the int (* 300.0 (rand-vu-float-range 0.05 0.12))))) + (suspend-for gp-0) ) (set! (-> self path-base-u) (the float (rand-vu-int-count (-> self path curve num-cverts)))) (get-point-in-path! (-> self path) (-> self root trans) (-> self path-base-u) 'interp) @@ -157,12 +153,8 @@ :virtual #t :event tizard-event-handler :code (behavior () - (let ((gp-0 (the int (* 300.0 (rand-vu-float-range 1.0 2.0)))) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 gp-0) - (suspend) - ) + (let ((gp-0 (the int (* 300.0 (rand-vu-float-range 1.0 2.0))))) + (suspend-for gp-0) ) (if (< 17294.223 (acos (vector-dot (-> self rotation-matrix fvec) (-> self path-dir)))) (go-virtual turning) diff --git a/goal_src/jak3/levels/wascity/wasall-tasks.gc b/goal_src/jak3/levels/wascity/wasall-tasks.gc index 9669e4c923..0d9a1c118c 100644 --- a/goal_src/jak3/levels/wascity/wasall-tasks.gc +++ b/goal_src/jak3/levels/wascity/wasall-tasks.gc @@ -42,10 +42,7 @@ ) (set-setting! 'fog-special-interp-targ #f f0-0 0) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 15)) - (suspend) - ) + (suspend-for (seconds 15) ) ) #f @@ -125,12 +122,11 @@ (logior! (-> this minimap-temple flags) (minimap-flag fade-out)) (set! (-> this minimap-temple) #f) ) - ;; og:preserve-this not-yet-implemented check - (if *bigmap* (bigmap-method-16 *bigmap*)) + (set-map-indices! *bigmap*) (when (and (not (-> this rod-of-god)) - ; (!= (-> *bigmap* load-index) 18) - ; (!= (-> *bigmap* load-index) 19) - ; (!= (-> *bigmap* load-index) 20) + (!= (-> *bigmap* load-index) 18) + (!= (-> *bigmap* load-index) 19) + (!= (-> *bigmap* load-index) 20) ) (let ((s4-1 (new 'stack-no-clear 'task-arrow-params))) (set! (-> s4-1 pos quad) (-> (the-as process-focusable s5-0) root trans quad)) @@ -389,10 +385,7 @@ ) #f (label cfg-22) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (talker-spawn-func (-> *talker-speech* 88) *entity-pool* (target-pos 0) (the-as region #f)) (send-event self 'complete) @@ -475,10 +468,7 @@ (defstate active (oasis-defense-intro-manager) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (open! (-> self node-info) 'event) (talker-spawn-func (-> *talker-speech* 83) *entity-pool* (target-pos 0) (the-as region #f)) @@ -600,11 +590,7 @@ (defstate active (task-manager-lock-wasdoors) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set-setting! 'airlock #f 0.0 0) ) :trans (behavior () diff --git a/goal_src/jak3/levels/wascity/wascity-turret.gc b/goal_src/jak3/levels/wascity/wascity-turret.gc index 909de81199..bf015c6b78 100644 --- a/goal_src/jak3/levels/wascity/wascity-turret.gc +++ b/goal_src/jak3/levels/wascity/wascity-turret.gc @@ -696,11 +696,7 @@ (set! (-> self facing-ocean) #t) (set! (-> self facing-city) #f) (set! (-> self reset-facing) #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (sound-play "jump-in-turret") (let* ((v1-9 (-> *game-info* sub-task-list (game-task-node wascity-gungame-resolution))) (a0-4 (handle->process (if (-> v1-9 manager) @@ -769,11 +765,7 @@ (defstate shutdown (wascity-turret) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (wct-show-flut self #t) @@ -807,11 +799,7 @@ (setup-masks (-> self draw) 0 2) (set-setting! 'matrix-blend-turret-rot 'abs 5.0 0) (set-setting! 'lock-sound-camera-to-target #t 0.0 0) - (let ((t9-4 (-> (find-parent-state) enter))) - (if t9-4 - (t9-4) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (setup-masks (-> self draw) 2 0) @@ -824,11 +812,7 @@ ) :trans (behavior () (wascity-turret-method-59 self) - (let ((t9-2 (-> (find-parent-state) trans))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler trans) ) ) diff --git a/goal_src/jak3/levels/wascity/wasdef-manager.gc b/goal_src/jak3/levels/wascity/wasdef-manager.gc index e8947f495f..9f67723fcd 100644 --- a/goal_src/jak3/levels/wascity/wasdef-manager.gc +++ b/goal_src/jak3/levels/wascity/wasdef-manager.gc @@ -1629,11 +1629,7 @@ (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 4)) - (suspend) - ) - ) + (suspend-for (seconds 4)) ) :post (behavior () (let ((gp-0 (new 'stack-no-clear 'vector))) @@ -2051,11 +2047,7 @@ :code (behavior () (maker-method-38 self) (set! *maker-num-visible* (+ *maker-num-visible* -1)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (suspend) - ) - ) + (suspend-for (seconds 3)) (if (nonzero? (-> self explosion-sound-id)) (set-action! *gui-control* diff --git a/goal_src/jak3/levels/wascity/wasgun-manager.gc b/goal_src/jak3/levels/wascity/wasgun-manager.gc index c42407c9cb..38c31cb4ec 100644 --- a/goal_src/jak3/levels/wascity/wasgun-manager.gc +++ b/goal_src/jak3/levels/wascity/wasgun-manager.gc @@ -1278,11 +1278,7 @@ (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (sound-play "point-missed" :position (wascity-turret-gun-pos)) (let ((v1-49 (handle->process (-> self mgr)))) (when v1-49 diff --git a/goal_src/jak3/levels/wascity/wasstadium/nst-tasks.gc b/goal_src/jak3/levels/wascity/wasstadium/nst-tasks.gc index de47169a8f..5e628858f6 100644 --- a/goal_src/jak3/levels/wascity/wasstadium/nst-tasks.gc +++ b/goal_src/jak3/levels/wascity/wasstadium/nst-tasks.gc @@ -273,28 +273,19 @@ ) :code (behavior () (local-vars (a0-15 vector) (a1-7 vector) (gp-6 (function vector vector float))) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) - ) + (suspend-for (seconds 0.1)) (when (not (task-node-closed? (game-task-node nest-eggs-wall))) (until (level-get *level* 'wasdoors) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (format *stdebug* "wait for player to get to garage~%") - (b! (task-node-closed? (game-task-node nest-eggs-wall)) cfg-34 :delay (nop!)) - (suspend) - ) + (suspend-for + (seconds 1) + (format *stdebug* "wait for player to get to garage~%") + (b! (task-node-closed? (game-task-node nest-eggs-wall)) cfg-34 :delay (nop!)) + (empty-form) ) ) (setup-scorpion) (task-node-close! (game-task-node nest-eggs-get-to-scorpion) 'event) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) (let ((v1-20 (rand-vu-int-range 0 1))) (b! (nonzero? v1-20) cfg-11 :delay (empty-form)) (talker-spawn-func (-> *nest-eggs-speech-list* 8) *entity-pool* (target-pos 0) (the-as region #f)) @@ -305,11 +296,7 @@ ) ) (label cfg-13) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 4)) - (suspend) - ) - ) + (suspend-for (seconds 4)) (until (< (gp-6 a0-15 a1-7) 491520.0) (format *stdebug* "wait for player to drive to eggwall~%") (b! (task-node-closed? (game-task-node nest-eggs-wall)) cfg-34 :delay (nop!)) @@ -335,20 +322,12 @@ (label cfg-25) (b! (handle->process (the-as handle gp-8)) cfg-24 :delay (nop!)) ) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 0.5)) - (suspend) - ) - ) + (suspend-for (seconds 0.5)) ) (label cfg-34) (setup-scorpion) (set-setting! 'music 'nesteggs 0.0 0) - (let ((gp-10 (current-time))) - (until (time-elapsed? gp-10 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (let ((v1-57 (rand-vu-int-range 0 6))) (cond ((zero? v1-57) @@ -391,11 +370,7 @@ ) :code (behavior () (task-node-close! (-> self info final-node) 'event) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.6)) - (suspend) - ) - ) + (suspend-for (seconds 0.6)) (let ((v1-6 (rand-vu-int-range 0 3))) (cond ((zero? v1-6) @@ -412,17 +387,8 @@ ) ) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 3)) - (format *stdebug* "task-manager-nest-cocoons: done!~%") - (suspend) - ) - ) - (let ((t9-12 (-> (find-parent-state) code))) - (if t9-12 - ((the-as (function none) t9-12)) - ) - ) + (suspend-for (seconds 3) (format *stdebug* "task-manager-nest-cocoons: done!~%")) + (call-parent-state-handler code) ) ) diff --git a/goal_src/jak3/levels/wascity/wasstadium/wasstadb-obs.gc b/goal_src/jak3/levels/wascity/wasstadium/wasstadb-obs.gc index 5b0e8c0e74..8957996575 100644 --- a/goal_src/jak3/levels/wascity/wasstadium/wasstadb-obs.gc +++ b/goal_src/jak3/levels/wascity/wasstadium/wasstadb-obs.gc @@ -1081,11 +1081,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (set! *arena-trainer-checkpoint-valid* #t) (copy-string<-string (-> *training-fail* fail continue) "wasstada-checkpoint-3") (set-setting! 'death-info *training-fail* 0.0 0) @@ -1303,11 +1299,7 @@ ) (suspend) (ja-channel-set! 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (send-event self 'death-end) (while (-> self child) (suspend) diff --git a/goal_src/jak3/levels/wascity/wasstadium/wasstadc-obs.gc b/goal_src/jak3/levels/wascity/wasstadium/wasstadc-obs.gc index 9e136388b6..636137a3d7 100644 --- a/goal_src/jak3/levels/wascity/wasstadium/wasstadc-obs.gc +++ b/goal_src/jak3/levels/wascity/wasstadium/wasstadc-obs.gc @@ -43,18 +43,10 @@ (set! (-> gp-0 map-icon) (the-as uint 13)) (set! (-> self arrow-h) (process->handle (task-arrow-spawn gp-0 self))) ) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (when (-> self arrow-h) (let ((gp-0 (-> self arrow-h process 0))) (when (or (< (vector-vector-distance (-> (the-as process-drawable gp-0) root trans) (target-pos 0)) 12288.0) @@ -386,11 +378,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) - ) + (suspend-for (seconds 1)) (ja-no-eval :group! wstd-fight-house-a-open-ja :num! (seek! 0.0) :frame-num 5.0) (until (ja-done? 0) (suspend) @@ -2153,11 +2141,7 @@ ) (let ((gp-1 (-> *game-info* gun-type))) (set-setting! 'change-gun #t 0.0 0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 5)) - (suspend) - ) - ) + (suspend-for (seconds 5)) (set! (-> self gui-id) (add-process *gui-control* self (gui-channel message) (gui-action play) (-> self name) 81920.0 0) ) @@ -2172,12 +2156,7 @@ (send-event (-> v1-33 extra process) 'off) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (print-text self (-> self text-id)) - (suspend) - ) - ) + (suspend-for (seconds 2) (print-text self (-> self text-id))) (send-event self 'complete) (until #f (suspend) @@ -2231,11 +2210,7 @@ ) (let ((gp-2 32)) (set-setting! 'change-gun #t 0.0 0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 5)) - (suspend) - ) - ) + (suspend-for (seconds 5)) (set! (-> self gui-id) (add-process *gui-control* self (gui-channel message) (gui-action play) (-> self name) 81920.0 0) ) @@ -2249,12 +2224,7 @@ (send-event (-> v1-38 extra process) 'off) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 2)) - (print-text self (-> self text-id)) - (suspend) - ) - ) + (suspend-for (seconds 2) (print-text self (-> self text-id))) (send-event self 'complete) (until #f (suspend) @@ -2457,11 +2427,7 @@ (send-event (handle->process (-> self arrow-h)) 'leave) (send-event *target* 'end-mode 'darkjak) (send-event *target* 'end-mode 'grab) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) - ) + (suspend-for (seconds 2)) (go-virtual complete) ) ) diff --git a/goal_src/jak3/levels/wascity/wlander-male.gc b/goal_src/jak3/levels/wascity/wlander-male.gc index 149f8ab576..80d61a5ead 100644 --- a/goal_src/jak3/levels/wascity/wlander-male.gc +++ b/goal_src/jak3/levels/wascity/wlander-male.gc @@ -232,11 +232,7 @@ (defstate knocked-recover (wlander) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (nav-enemy-method-184 self) (let ((a0-2 (-> self nav state)) (v1-5 *null-vector*) diff --git a/goal_src/jak3/pc/debug/default-menu-pc.gc b/goal_src/jak3/pc/debug/default-menu-pc.gc index 14b045f63e..4c1705287a 100644 --- a/goal_src/jak3/pc/debug/default-menu-pc.gc +++ b/goal_src/jak3/pc/debug/default-menu-pc.gc @@ -733,44 +733,42 @@ ) -;; (define *made-vag-list* #f) -;; (defun build-vag-list ((menu debug-menu)) -;; "Fill the vag play menu" +(define *made-vag-list* #f) +(defun build-vag-list ((menu debug-menu)) + "Fill the vag play menu" + (if *made-vag-list* + (return #f)) + (true! *made-vag-list*) -;; (if *made-vag-list* -;; (return #f)) -;; (true! *made-vag-list*) - -;; ;; clear old list -;; (debug-menu-remove-all-items menu) + ;; clear old list + (debug-menu-remove-all-items menu) -;; ;; make button for each vag, we use an index -;; (dotimes (i (-> *vag-list* allocated-length)) -;; (debug-menu-append-item menu (new-dm-func (-> *vag-list* i) i vag-player-play-from-index)) -;; ) + ;; make button for each vag, we use an index + (dotimes (i (-> *vag-list* allocated-length)) + (debug-menu-append-item menu (new-dm-func (-> *vag-list* i) i vag-player-play-from-index)) + ) -;; ;; sort by vag name - note: already sorted from before -;; ;(set! (-> menu items) (sort (-> menu items) debug-menu-node menu items) (sort (-> menu items) debug-menu-node *setting-control* user-default subtitle))) -;; (-> *setting-control* user-default subtitle)))) -;; ;; pick channel - -;; (new-dm-submenu "Vag" vag-menu) -;; ) -;; ) +(define *vag-play-menu* (the debug-menu #f)) +(defun debug-menu-make-vag-menu ((ctx debug-menu-context)) + (let ((vag-menu (new 'debug 'debug-menu ctx "Vag menu"))) + (let ((play-menu (new 'debug 'debug-menu ctx "Play Vag menu"))) + (set! *vag-play-menu* play-menu) + (debug-menu-append-item vag-menu (new-dm-submenu "Play" play-menu)) + ) + (debug-menu-append-item vag-menu (new-dm-func "Make List" *vag-play-menu* build-vag-list)) + (debug-menu-append-item vag-menu (new-dm-bool "subtitle" #f + (lambda (arg (msg debug-menu-msg)) + (if (= msg (debug-menu-msg press)) + (not! (-> *setting-control* user-default subtitle))) + (-> *setting-control* user-default subtitle)))) + ;; pick channel + (new-dm-submenu "Vag" vag-menu) + ) + ) (defun dm-frame-rate-pick-func ((bfps int) (msg debug-menu-msg)) (let ((fps (/ bfps 8))) @@ -815,7 +813,7 @@ (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-part-menu *debug-menu-context*)) (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-entity-menu *debug-menu-context*)) (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-regions-menu *debug-menu-context*)) - ;; (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-vag-menu *debug-menu-context*)) + (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-vag-menu *debug-menu-context*)) (debug-menu-append-item (-> *debug-menu-context* root-menu) (debug-menu-make-from-template *debug-menu-context* diff --git a/goal_src/jak3/pc/debug/vag-player.gc b/goal_src/jak3/pc/debug/vag-player.gc new file mode 100644 index 0000000000..d1cbc6c7c3 --- /dev/null +++ b/goal_src/jak3/pc/debug/vag-player.gc @@ -0,0 +1,456 @@ +;;-*-Lisp-*- +(in-package goal) + +#| + + vag player process for debugging vag streams and for easier subtitling. + + |# + +(declare-file (debug)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; constants +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; types and enums +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;;;---------------------------------- +;; process type +;;;---------------------------------- + + +;; the vag-player process. it lives on the PC actor pool +(deftype vag-player (process) + ( + (vag-index int32) + (id sound-id) + (speed float) + (old-speed float) + + ;; temp settings + (master-mode symbol) + (display-art-control symbol) + (debug-menu-hidden symbol) + (gui-kick-str symbol) + ) + + (:methods + (vag-stop (_type_) int) + (vag-play (_type_) sound-id) + (vag-playing? (_type_) symbol) + (vag-set-speed (_type_ float) sound-id) + ) + (:states + (vag-player-playing int) + ) + ) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; vag list +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;; an array of 64-bit values which can be turned into a string +;; each representing the name of a vag stream. convert using alloc-vag-list +(define *vagdir-names-list* (alloc-vagdir-names 'debug)) + +(defun strcmp ((a string) (b string)) + "C-style strcmp. Unlike GOAL's string comparison functions, these actually work: + (strcmp 'ab' 'a') and (strcmp 'a' 'ab') give the opposite result." + (let ((a-ptr (-> a data)) + (b-ptr (-> b data))) + (while (and (nonzero? (-> a-ptr)) + (= (-> a-ptr) (-> b-ptr))) + (&+! a-ptr 1) + (&+! b-ptr 1) + ) + (- (the int (-> a-ptr)) (the int (-> b-ptr))) + ) + ) + +(defun string-quicksort-partition ((arr (array string)) (lo int) (hi int)) + (let ((pivot (-> arr hi)) + (i (- lo 1)) + (j lo) + ) + (while (< j hi) + (when (< (strcmp (-> arr j) pivot) 0) + (+! i 1) + (swap! (-> arr i) (-> arr j)) + ) + (+! j 1) + ) + (+! i 1) + (swap! (-> arr i) (-> arr hi)) + i + ) + ) + +(defun-recursive string-quicksort-run (array string) ((arr (array string)) (lo int) (hi int)) + (when (or (>= lo hi) (< lo 0)) + (return arr) + ) + (let ((p (string-quicksort-partition arr lo hi))) + (string-quicksort-run arr lo (- p 1)) + (string-quicksort-run arr (+ p 1) hi) + ) + arr + ) + +(defun string-quicksort ((arr (array string))) + "Sort an array of strings alphabetically using quicksort. + This is about 100x faster than the normal GOAL sort." + (string-quicksort-run arr 0 (- (-> arr length) 1)) + ) + + +(defun alloc-vag-list () + "allocates and returns a boxed array with all of the vag names as strings, sorted" + (let ((list (new 'debug 'boxed-array string (the int (-> *vagdir-names-list* -1))))) + + ;; for each vag... + (dotimes (i (-> list allocated-length)) + ;; write the vag name (64 bits) into the string directly and add a null character + (set! (-> (the (pointer uint64) (-> *temp-string* data))) (-> *vagdir-names-list* i)) + (set! (-> *temp-string* data 8) 0) + (countdown (ii 8) + (if (!= #x20 (-> *temp-string* data ii)) + (set! ii 0) + (set! (-> *temp-string* data ii) 0)) + ) + + ;; copy into a new string + (set! (-> list i) (new 'debug 'string 0 *temp-string*))) + + ;; return the allocated, filled and sorted array + (string-quicksort list)) + ) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; globals +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;; the process pointer. +(define *vag-player* (the (pointer vag-player) #f)) + +;; list of vag names (as a string) +(define *vag-list* (alloc-vag-list)) +;; the highest recorded position for each vag +(define *vag-max-pos-list* (the (pointer int32) (malloc 'debug (* 4 (-> *vag-list* allocated-length))))) + +(defun get-vag-index-from-name ((name string)) + "return the index of the vag with that name in the *vag-list* or -1 if not found" + + ;; uppercase the string so we have a consistent name format + (string-upcase name *vag-temp-string* #f) + (dotimes (i (-> *vag-list* allocated-length)) + (string-upcase (-> *vag-list* i) *vag-temp-string-2* #f) + (when (string= *vag-temp-string* *vag-temp-string-2*) + (return i)) + ) + -1) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; states +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defmethod deactivate vag-player ((obj vag-player)) + (set! *vag-player* (the (pointer vag-player) #f)) + ((method-of-type process deactivate) obj) + (none) + ) + +(defstate vag-player-idle (vag-player) + :event (behavior ((from process) (argc int) (msg symbol) (block event-message-block)) + (case msg + (('play) + (let ((vag-idx (get-vag-index-from-name (the string (-> block param 0))))) + (when (!= vag-idx -1) + (go vag-player-playing vag-idx) + (return #t))) + #f) + (('play-index) + (go vag-player-playing (the int (-> block param 0)))) + ) + ) + + :code sleep-code + ) + + +(defstate vag-player-playing (vag-player) + + :event (behavior ((from process) (argc int) (msg symbol) (block event-message-block)) + (case msg + (('play) + (let ((vag-idx (get-vag-index-from-name (the string (-> block param 0))))) + (when (!= vag-idx -1) + (set! (-> self vag-index) vag-idx) + (vag-play self) + (return #t))) + #f) + (('play-index) + (set! (-> self vag-index) (the int (-> block param 0))) + (vag-play self) + #t) + ) + ) + + :enter (behavior ((index int)) + (set! (-> self master-mode) *master-mode*) + (set! (-> self debug-menu-hidden) (-> *debug-menu-context* is-hidden)) + (set! (-> self display-art-control) *display-art-control*) + (set! (-> self gui-kick-str) *gui-kick-str*) + + (set-master-mode 'menu) ;; put us in menu mode first + (true! *display-art-control*) ;; force this on + (true! (-> *debug-menu-context* is-hidden)) ;; hide debug menu + (true! *gui-kick-str*) ;; force gui control to play streams + (sound-group-continue (sound-group dialog dialog2)) ;; unpause dialog + (set-setting! 'music-volume 'abs 0.0 0) ;; mute music + (set-setting! 'sfx-volume 'abs 0.0 0) ;; mute sfx + (set-setting! 'ambient-volume 'abs 0.0 0) ;; mute ambient + (set-setting! 'dialog-volume 'abs 1.0 0) ;; max dialog + (apply-settings *setting-control*) ;; apply settings now + + (set! (-> self speed) 0.0) + (set! (-> self old-speed) 0.0) + ) + + :exit (behavior () + (vag-stop self) + + (remove-setting! 'music-volume) + (remove-setting! 'sfx-volume) + (remove-setting! 'ambient-volume) + (remove-setting! 'dialog-volume) + (apply-settings *setting-control*) + (sound-group-pause (sound-group dialog dialog2)) + (set! *display-art-control* (-> self display-art-control)) + (set! (-> *debug-menu-context* is-hidden) (-> self debug-menu-hidden)) + (set! *gui-kick-str* (-> self gui-kick-str)) + (if (!= (-> self master-mode) 'menu) + (set-master-mode (-> self master-mode))) + ) + + :code (behavior ((index int)) + (set! (-> self vag-index) index) + + (let ((exit? #f)) + (vag-play self) + (while (= (gui-status pending) (get-status *gui-control* (-> self id))) + (suspend)) + + (until (or exit? (!= *master-mode* 'menu)) + (format *stdcon* "Vag Player -- Press Triangle To Exit~%") + (cond + ((zero? (-> self id)) + (format *stdcon* "No vag queued~%")) + ((not (vag-playing? self)) + (format *stdcon* "Vag not playing~%")) + (else + (format *stdcon* "Vag playing: ~3L~D~0L~%" (the int (/ (the float (current-str-pos (-> self id))) (/ 1024.0 30))))) + ) + (format *stdcon* "Vag: ~S <- ~S(max:~3L~D~0L) -> ~S~%" (if (> (-> self vag-index) 0) (-> *vag-list* (1- (-> self vag-index)))) + (-> *vag-list* (-> self vag-index)) (-> *vag-max-pos-list* (-> self vag-index)) + (if (< (1+ (-> self vag-index)) (-> *vag-list* allocated-length)) (-> *vag-list* (1+ (-> self vag-index))))) + (format *stdcon* "X to Pause and Play~%R1 and L1 for Speed, Circle Resets~%Left and Right for Prev / Next~%Square for Subtitles (~A)~%" (-> *setting-control* user-default subtitle)) + (format *stdcon* "Speed: ~f~%" (-> self speed)) + (cond + ((cpad-pressed? 0 triangle) + (cpad-clear! 0 triangle) + (true! exit?)) + ((cpad-pressed? 0 x) + (cpad-clear! 0 x) + (cond + ((not (vag-playing? self)) + (vag-play self)) + ((= (-> self speed) -1000.0) + (set! (-> self speed) 0.0) + (sound-continue (-> self id)) + (when *sound-player-enable* + (let ((cmd (the-as sound-rpc-set-param (get-sound-buffer-entry)))) + (set! (-> cmd command) (sound-command set-param)) + (set! (-> cmd id) (-> self id)) + (set! (-> cmd params pitch-mod) 0) + (set! (-> cmd params mask) (the-as uint 2)) + (-> cmd id) + ) + ) + ) + (else + (set! (-> self speed) -1000.0) + (sound-pause (-> self id)) + ) + ) + ) + ((and (cpad-pressed? 0 left) (> (-> self vag-index) 0)) + (cpad-clear! 0 left) + (1-! (-> self vag-index)) + (vag-play self)) + ((and (cpad-pressed? 0 right) (< (1+ (-> self vag-index)) (-> *vag-list* allocated-length))) + (cpad-clear! 0 right) + (1+! (-> self vag-index)) + (vag-play self)) + ((and (cpad-hold? 0 r1 l1) (!= (-> self speed) -1000.0)) + (seek! (-> self speed) (if (cpad-hold? 0 l1) -4.0 4.0) (* 0.5 (-> self clock seconds-per-frame))) + ) + ((cpad-pressed? 0 circle) + (cpad-clear! 0 circle) + (set! (-> self speed) 0.0)) + ((cpad-pressed? 0 square) + (cpad-clear! 0 square) + (not! (-> *setting-control* user-default subtitle))) + ) + (when (vag-playing? self) + (max! (-> *vag-max-pos-list* (-> self vag-index)) (the int (/ (the float (current-str-pos (-> self id))) (/ 1024.0 30)))) + (when (and (!= (-> self speed) (-> self old-speed)) (!= (-> self speed) -1000.0)) + (vag-set-speed self (-> self speed)) + (set! (-> self old-speed) (-> self speed)))) + (suspend)) + ) + + (go vag-player-idle) + ) + ) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; methods +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defmethod vag-play vag-player ((self vag-player)) + "play the current vag stream" + (set! (-> self speed) 0.0) + (set! (-> self old-speed) 0.0) + (vag-stop self) + (set! (-> self id) (add-process *gui-control* self (gui-channel alert) (gui-action play) (-> *vag-list* (-> self vag-index)) -10.0 0))) + +(defmethod vag-stop vag-player ((self vag-player)) + "stop the current vag stream" + (set-action! *gui-control* (gui-action stop) (-> self id) (gui-channel none) (gui-action none) (the string #f) (the-as (function gui-connection symbol) #f) (the-as process #f))) + +(defmethod vag-playing? vag-player ((self vag-player)) + "is the current vag stream playing?" + (let ((status (get-status *gui-control* (-> self id)))) (or (= status (gui-status ready)) (= status (gui-status active))))) + +(defmethod vag-set-speed vag-player ((self vag-player) (speed float)) + "set the speed of the current vag stream" + (when *sound-player-enable* + (let ((cmd (the-as sound-rpc-set-param (get-sound-buffer-entry)))) + (set! (-> cmd command) (sound-command set-param)) + (set! (-> cmd id) (-> self id)) + (set! (-> cmd params pitch-mod) (the int (* 1524.0 speed))) + (set! (-> cmd params mask) (the-as uint 2)) + (-> cmd id) + ) + )) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; helper functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +(defbehavior vag-player-init-by-other vag-player () + "external initializer for vag-player process" + (set! (-> self id) (new 'static 'sound-id)) + (process-mask-clear! (-> self mask) menu pause) + (go vag-player-idle) + ) + + +(defun vag-player-stop () + "kill the vag-player process" + (kill-by-type vag-player *pc-pool*)) + +(defun vag-player-start () + "start the vag-player process" + + (when *vag-player* + (vag-player-stop) + ) + + (set! *vag-player* (process-spawn vag-player :from *pc-dead-pool* :to *pc-pool*)) + ) + + +(defun vag-player-play-from-index ((index int)) + "play a vag from its index in the vag list" + (if (not *vag-player*) + (vag-player-start)) + + (send-event (ppointer->process *vag-player*) 'play-index index)) + +(defun vag-player-play-from-name ((name string)) + "play a vag from its name" + (if (not *vag-player*) + (vag-player-start)) + + (send-event (ppointer->process *vag-player*) 'play name)) + +(defun vag-list-to-file ((file-name string)) + (if *vag-list* + (let ((file (new 'stack 'file-stream file-name 'write))) + (dotimes (i (-> *vag-list* allocated-length)) + (format file "~S~%" (-> *vag-list* i)) + ) + (file-stream-close file) + ) + #f + ) + ) + +;; start the vag-player process when this file loads. +(vag-player-start) + + +(defun scene-find-and-play ((name string)) + "go through the scene player list to find and play the requested scene" + (vag-player-stop) + (let* ((find-scene-in-act + (lambda ((scene-list (array hud-scene-info)) (name string)) + ;; for each scene in list + (doarray (scene-info scene-list) + ;; scene name matches - return that immediately + (if (and (string? (-> scene-info info)) (string= (the string (-> scene-info info)) name)) + (return scene-info)) + ;; scene name didn't match, see if there is a scene playlist + ;; if there is, then find our scene there + (when (pair? (-> scene-info info)) + (let ((iter (the pair (-> scene-info info)))) + (while (not (null? iter)) + (if (and (string? (car iter)) (string= (the string (car iter)) name)) + (return scene-info)) + (set! iter (cdr iter)) + ) + ) + ) + ) + (the hud-scene-info #f)))) + (awhen (or (find-scene-in-act *hud-select-scene-act1* name) + (find-scene-in-act *hud-select-scene-act2* name) + (find-scene-in-act *hud-select-scene-act3* name)) + (process-spawn scene-player :init scene-player-init name #t (-> (the hud-scene-info it) continue)) + ) + ) + 0) + diff --git a/goal_src/jak3/pc/features/autosplit-h.gc b/goal_src/jak3/pc/features/autosplit-h.gc new file mode 100644 index 0000000000..70f76cfc03 --- /dev/null +++ b/goal_src/jak3/pc/features/autosplit-h.gc @@ -0,0 +1,164 @@ +;;-*-Lisp-*- +(in-package goal) + +;; LiveSplit ASL requires all settings to initalized _before_ you connect the process +;; Therefore everything has to be laid out in a predictable fashion before hand +;; So this is a lot of hard-coding, but not too bad when just copied from the debug menu code +;; +;; DO NOT change the order, appending to the end is safe! + +(deftype autosplit-info (structure) + (;; Version Info + (version-major uint16) + (version-minor uint16) + ;; General stats + (num-orbs uint32) + (num-skullgems uint32) + (errol-dead? uint8) + (all-collectables-acquired? uint8) + (padding-stats uint8 198) ;; padding for future growth + ;; loading/cutscene/control related info + (game-hash uint32) + (in-cutscene? uint8) + (is-loading? uint8) + (padding-controls uint8 200) ;; padding for future growth + ;; need-resolution tasks + (res-arena-training-1 uint8) + (res-arena-fight-1 uint8) + (res-wascity-chase uint8) + (res-wascity-pre-game uint8) + (res-desert-turtle-training uint8) + (res-desert-course-race uint8) + (res-desert-artifact-race-1 uint8) + (res-wascity-leaper-race uint8) + (res-desert-hover uint8) + (res-arena-fight-2 uint8) + (res-desert-catch-lizards uint8) + (res-desert-rescue uint8) + (res-wascity-gungame uint8) + (res-arena-fight-3 uint8) + (res-nest-eggs uint8) + (res-temple-climb uint8) + (res-desert-glide uint8) + (res-volcano-darkeco uint8) + (res-temple-oracle uint8) + (res-desert-oasis-defense uint8) + (res-temple-tests uint8) + (res-comb-travel uint8) + (res-mine-explore uint8) + (res-mine-blow uint8) + (res-mine-boss uint8) + (res-sewer-met-hum uint8) + (res-city-vehicle-training uint8) + (res-city-port-fight uint8) + (res-city-port-attack uint8) + (res-city-gun-course-1 uint8) + (res-city-sniper-fight uint8) + (res-sewer-kg-met uint8) + (res-city-destroy-darkeco uint8) + (res-forest-kill-plants uint8) + (res-city-destroy-grid uint8) + (res-city-hijack-vehicle uint8) + (res-city-port-assault uint8) + (res-city-gun-course-2 uint8) + (res-city-blow-barricade uint8) + (res-city-protect-hq uint8) + (res-sewer-hum-kg uint8) + (res-city-power-game uint8) + (res-desert-artifact-race-2 uint8) + (res-nest-hunt uint8) + (res-desert-beast-battle uint8) + (res-desert-jump-mission uint8) + (res-desert-chase-marauders uint8) + (res-forest-ring-chase uint8) + (res-factory-sky-battle uint8) + (res-factory-assault uint8) + (res-factory-boss uint8) + (res-temple-defend uint8) + (res-wascity-defend uint8) + (res-forest-turn-on-machine uint8) + (res-precursor-tour uint8) + (res-city-blow-tower uint8) + (res-tower-destroy uint8) + (res-palace-ruins-patrol uint8) + (res-palace-ruins-attack uint8) + (res-comb-wild-ride uint8) + (res-precursor-destroy-ship uint8) + (res-desert-final-boss uint8) + (res-city-win uint8) + (res-desert-bbush-get-to-1 uint8) + (res-desert-bbush-get-to-2 uint8) + (res-desert-bbush-get-to-3 uint8) + (res-desert-bbush-get-to-4 uint8) + (res-desert-bbush-get-to-5 uint8) + (res-desert-bbush-get-to-6 uint8) + (res-desert-bbush-get-to-7 uint8) + (res-desert-bbush-get-to-8 uint8) + (res-desert-bbush-get-to-9 uint8) + (res-desert-bbush-get-to-11 uint8) + (res-desert-bbush-get-to-12 uint8) + (res-desert-bbush-get-to-14 uint8) + (res-desert-bbush-get-to-16 uint8) + (res-desert-bbush-get-to-17 uint8) + (res-wascity-bbush-get-to-18 uint8) + (res-desert-bbush-get-to-19 uint8) + (res-wascity-bbush-get-to-20 uint8) + (res-wascity-bbush-get-to-21 uint8) + (res-wascity-bbush-get-to-22 uint8) + (res-wascity-bbush-get-to-23 uint8) + (res-wascity-bbush-get-to-24 uint8) + (res-wascity-bbush-get-to-25 uint8) + (res-city-bbush-get-to-26 uint8) + (res-city-bbush-get-to-27 uint8) + (res-city-bbush-get-to-28 uint8) + (res-city-bbush-get-to-29 uint8) + (res-city-bbush-get-to-30 uint8) + (res-city-bbush-get-to-31 uint8) + (res-city-bbush-get-to-32 uint8) + (res-city-bbush-get-to-33 uint8) + (res-city-bbush-get-to-34 uint8) + (res-city-bbush-get-to-35 uint8) + (res-city-bbush-get-to-36 uint8) + (res-city-bbush-get-to-37 uint8) + (res-city-bbush-get-to-38 uint8) + (res-city-bbush-get-to-39 uint8) + (res-city-bbush-get-to-40 uint8) + (res-city-bbush-get-to-41 uint8) + (res-city-bbush-get-to-42 uint8) + (res-city-bbush-get-to-43 uint8) + (res-city-bbush-get-to-44 uint8) + (res-desert-bbush-ring-1 uint8) + (res-desert-bbush-ring-2 uint8) + (res-wascity-bbush-ring-3 uint8) + (res-wascity-bbush-ring-4 uint8) + (res-city-bbush-ring-5 uint8) + (res-city-bbush-ring-6 uint8) + (res-desert-bbush-egg-spider-1 uint8) + (res-desert-bbush-spirit-chase-1 uint8) + (res-wascity-bbush-spirit-chase-2 uint8) + (res-city-bbush-spirit-chase-3 uint8) + (res-desert-bbush-timer-chase-1 uint8) + (res-wascity-bbush-timer-chase-2 uint8) + (res-desert-bbush-air-time uint8) + (res-desert-bbush-total-air-time uint8) + (res-desert-bbush-jump-distance uint8) + (res-desert-bbush-total-jump-distance uint8) + (res-desert-bbush-roll-count uint8) + (res-desert-bbush-time-trial-1 uint8) + (res-desert-bbush-rally uint8) + (res-city-bbush-port-attack uint8) + (res-desert-rescue-bbush uint8) + (res-city-gun-course-play-for-fun uint8) + (res-city-jetboard-bbush uint8) + (res-desert-bbush-destroy-interceptors uint8) + ;; TODO misc other task-nodes + (arena-fight-1-throne uint8) ;; after arena 1 cutscene + ;; TODO - orbs in level X + ;; end marker just to make things look nice in a memory view + (end-marker uint8 4)) + (:methods + (reset! (_type_) object) + (update! (_type_) object) + (debug-draw (_type_) object))) + +(define-extern *autosplit-info-jak3* autosplit-info) diff --git a/goal_src/jak3/pc/features/autosplit.gc b/goal_src/jak3/pc/features/autosplit.gc new file mode 100644 index 0000000000..8d1109f41d --- /dev/null +++ b/goal_src/jak3/pc/features/autosplit.gc @@ -0,0 +1,257 @@ +;;-*-Lisp-*- +(in-package goal) +(define *autosplit-info-jak3* (new 'static 'autosplit-info)) + +(pc-init-autosplitter-struct) + +;; Setup Version +(set! (-> *autosplit-info-jak3* version-major) 0) + +(set! (-> *autosplit-info-jak3* version-minor) 1) + +;; Setup markers +(charp<-string (-> *autosplit-info-jak3* end-marker) "end") + +;; Setup Padding +(charp<-string (-> *autosplit-info-jak3* padding-stats) "padding-stats!") + +(charp<-string (-> *autosplit-info-jak3* padding-controls) "padding-controls!") + +(defconstant MAX_ORBS 600) + +(defconstant AUTOSPLITTER_DEBUG #f) + +(defmacro autosplit-flag-task-complete! (field-name task-name) + "Given a field name in the autosplitter struct, and a [[game-task]] name to check, sets either a 0 or a 1" + `(begin + (if (!= (-> this ,field-name) (if (task-complete? *game-info* (game-task ,task-name)) 1 0)) + (format 0 "AUTOSPLIT for ~A~%" (quote ,task-name))) + (set! (-> this ,field-name) (if (task-complete? *game-info* (game-task ,task-name)) 1 0)))) + +(defmacro autosplit-flag-task-node-closed! (field-name task-node-name) + "Given a field name in the autosplitter struct, and a [[game-task-node]] name to check, sets either a 0 or a 1" + `(begin + (if (!= (-> this ,field-name) (if (task-node-closed? (game-task-node ,task-node-name)) 1 0)) + (format 0 "AUTOSPLIT for ~A~%" (quote ,task-node-name))) + (set! (-> this ,field-name) (if (task-node-closed? (game-task-node ,task-node-name)) 1 0)))) + +(defmethod update! ((this autosplit-info)) + ;; general statistics + ;; when we are blacked out in loads the value of these are temporarily 0, and that messes with the auto splitter. + (let ((in-blackout? (>= (-> *game-info* blackout-time) (current-time)))) + (when (not in-blackout?) + (set! (-> this num-orbs) (the int (-> *game-info* skill-total))) + (set! (-> this num-skullgems) (the int (-> *game-info* gem-total))) + ;; ending conditions + ;; all collectables + ;; - check for all features + ;; - check for all vehicles + ;; - check for all inventory items + ;; - check for all orbs + (set! (-> this all-collectables-acquired?) + (if (and (logtesta? (-> *game-info* features) + (game-feature jakc + board + board-launch + board-zap + darkeco + darkjak + darkjak + darkjak-smack + darkjak-bomb0 + darkjak-bomb1 + lighteco + lightjak + lightjak-regen + lightjak-swoop + lightjak-freeze + lightjak-shield + gun + gun-red-1 + gun-yellow-1 + gun-blue-1 + gun-dark-1 + gun-red-2 + gun-yellow-2 + gun-blue-2 + gun-dark-2 + gun-red-3 + gun-yellow-3 + gun-blue-3 + gun-dark-3)) + (logtesta? (-> *game-info* vehicles) (game-vehicles v-turtle v-snake v-scorpion v-toad v-fox v-rhino v-mirage v-x-ride)) + (logtesta? (-> *game-info* items) + (game-items amulet0 + amulet1 + amulet2 + pass-front-gate + seal-of-mar + cypher-gliph + artifact-holocube + artifact-av-reflector + artifact-av-prism + artifact-av-generator + artifact-av-map + light-eco-crystal0 + light-eco-crystal1 + light-eco-crystal2 + light-eco-crystal3 + dark-eco-crystal0 + dark-eco-crystal1 + dark-eco-crystal2 + dark-eco-crystal3)) + (>= (-> this num-orbs) MAX_ORBS)) + 1 + 0)))) + ;; loading/cutscene related flags + (set! (-> this in-cutscene?) (if (movie?) 1 0)) + ;; need resolution flags + (autosplit-flag-task-complete! res-arena-training-1 arena-training-1) + (autosplit-flag-task-complete! res-arena-fight-1 arena-fight-1) + (autosplit-flag-task-complete! res-wascity-chase wascity-chase) + (autosplit-flag-task-complete! res-wascity-pre-game wascity-pre-game) + (autosplit-flag-task-complete! res-desert-turtle-training desert-turtle-training) + (autosplit-flag-task-complete! res-desert-course-race desert-course-race) + (autosplit-flag-task-complete! res-desert-artifact-race-1 desert-artifact-race-1) + (autosplit-flag-task-complete! res-wascity-leaper-race wascity-leaper-race) + (autosplit-flag-task-complete! res-desert-hover desert-hover) + (autosplit-flag-task-complete! res-arena-fight-2 arena-fight-2) + (autosplit-flag-task-complete! res-desert-catch-lizards desert-catch-lizards) + (autosplit-flag-task-complete! res-desert-rescue desert-rescue) + (autosplit-flag-task-complete! res-wascity-gungame wascity-gungame) + (autosplit-flag-task-complete! res-arena-fight-3 arena-fight-3) + (autosplit-flag-task-complete! res-nest-eggs nest-eggs) + (autosplit-flag-task-complete! res-temple-climb temple-climb) + (autosplit-flag-task-complete! res-desert-glide desert-glide) + (autosplit-flag-task-complete! res-volcano-darkeco volcano-darkeco) + (autosplit-flag-task-complete! res-temple-oracle temple-oracle) + (autosplit-flag-task-complete! res-desert-oasis-defense desert-oasis-defense) + (autosplit-flag-task-complete! res-temple-tests temple-tests) + (autosplit-flag-task-complete! res-comb-travel comb-travel) + (autosplit-flag-task-complete! res-mine-explore mine-explore) + (autosplit-flag-task-complete! res-mine-blow mine-blow) + (autosplit-flag-task-complete! res-mine-boss mine-boss) + (autosplit-flag-task-complete! res-sewer-met-hum sewer-met-hum) + (autosplit-flag-task-complete! res-city-vehicle-training city-vehicle-training) + (autosplit-flag-task-complete! res-city-port-fight city-port-fight) + (autosplit-flag-task-complete! res-city-port-attack city-port-attack) + (autosplit-flag-task-complete! res-city-gun-course-1 city-gun-course-1) + (autosplit-flag-task-complete! res-city-sniper-fight city-sniper-fight) + (autosplit-flag-task-complete! res-sewer-kg-met sewer-kg-met) + (autosplit-flag-task-complete! res-city-destroy-darkeco city-destroy-darkeco) + (autosplit-flag-task-complete! res-forest-kill-plants forest-kill-plants) + (autosplit-flag-task-complete! res-city-destroy-grid city-destroy-grid) + (autosplit-flag-task-complete! res-city-hijack-vehicle city-hijack-vehicle) + (autosplit-flag-task-complete! res-city-port-assault city-port-assault) + (autosplit-flag-task-complete! res-city-gun-course-2 city-gun-course-2) + (autosplit-flag-task-complete! res-city-blow-barricade city-blow-barricade) + (autosplit-flag-task-complete! res-city-protect-hq city-protect-hq) + (autosplit-flag-task-complete! res-sewer-hum-kg sewer-hum-kg) + (autosplit-flag-task-complete! res-city-power-game city-power-game) + (autosplit-flag-task-complete! res-desert-artifact-race-2 desert-artifact-race-2) + (autosplit-flag-task-complete! res-nest-hunt nest-hunt) + (autosplit-flag-task-complete! res-desert-beast-battle desert-beast-battle) + (autosplit-flag-task-complete! res-desert-jump-mission desert-jump-mission) + (autosplit-flag-task-complete! res-desert-chase-marauders desert-chase-marauders) + (autosplit-flag-task-complete! res-forest-ring-chase forest-ring-chase) + (autosplit-flag-task-complete! res-factory-sky-battle factory-sky-battle) + (autosplit-flag-task-complete! res-factory-assault factory-assault) + (autosplit-flag-task-complete! res-factory-boss factory-boss) + (autosplit-flag-task-complete! res-temple-defend temple-defend) + (autosplit-flag-task-complete! res-wascity-defend wascity-defend) + (autosplit-flag-task-complete! res-forest-turn-on-machine forest-turn-on-machine) + (autosplit-flag-task-complete! res-precursor-tour precursor-tour) + (autosplit-flag-task-complete! res-city-blow-tower city-blow-tower) + (autosplit-flag-task-complete! res-tower-destroy tower-destroy) + (autosplit-flag-task-complete! res-palace-ruins-patrol palace-ruins-patrol) + (autosplit-flag-task-complete! res-palace-ruins-attack palace-ruins-attack) + (autosplit-flag-task-complete! res-comb-wild-ride comb-wild-ride) + (autosplit-flag-task-complete! res-precursor-destroy-ship precursor-destroy-ship) + (autosplit-flag-task-complete! res-desert-final-boss desert-final-boss) + (autosplit-flag-task-complete! res-city-win city-win) + (autosplit-flag-task-complete! res-desert-bbush-get-to-1 desert-bbush-get-to-1) + (autosplit-flag-task-complete! res-desert-bbush-get-to-2 desert-bbush-get-to-2) + (autosplit-flag-task-complete! res-desert-bbush-get-to-3 desert-bbush-get-to-3) + (autosplit-flag-task-complete! res-desert-bbush-get-to-4 desert-bbush-get-to-4) + (autosplit-flag-task-complete! res-desert-bbush-get-to-5 desert-bbush-get-to-5) + (autosplit-flag-task-complete! res-desert-bbush-get-to-6 desert-bbush-get-to-6) + (autosplit-flag-task-complete! res-desert-bbush-get-to-7 desert-bbush-get-to-7) + (autosplit-flag-task-complete! res-desert-bbush-get-to-8 desert-bbush-get-to-8) + (autosplit-flag-task-complete! res-desert-bbush-get-to-9 desert-bbush-get-to-9) + (autosplit-flag-task-complete! res-desert-bbush-get-to-11 desert-bbush-get-to-11) + (autosplit-flag-task-complete! res-desert-bbush-get-to-12 desert-bbush-get-to-12) + (autosplit-flag-task-complete! res-desert-bbush-get-to-14 desert-bbush-get-to-14) + (autosplit-flag-task-complete! res-desert-bbush-get-to-16 desert-bbush-get-to-16) + (autosplit-flag-task-complete! res-desert-bbush-get-to-17 desert-bbush-get-to-17) + (autosplit-flag-task-complete! res-wascity-bbush-get-to-18 wascity-bbush-get-to-18) + (autosplit-flag-task-complete! res-desert-bbush-get-to-19 desert-bbush-get-to-19) + (autosplit-flag-task-complete! res-wascity-bbush-get-to-20 wascity-bbush-get-to-20) + (autosplit-flag-task-complete! res-wascity-bbush-get-to-21 wascity-bbush-get-to-21) + (autosplit-flag-task-complete! res-wascity-bbush-get-to-22 wascity-bbush-get-to-22) + (autosplit-flag-task-complete! res-wascity-bbush-get-to-23 wascity-bbush-get-to-23) + (autosplit-flag-task-complete! res-wascity-bbush-get-to-24 wascity-bbush-get-to-24) + (autosplit-flag-task-complete! res-wascity-bbush-get-to-25 wascity-bbush-get-to-25) + (autosplit-flag-task-complete! res-city-bbush-get-to-26 city-bbush-get-to-26) + (autosplit-flag-task-complete! res-city-bbush-get-to-27 city-bbush-get-to-27) + (autosplit-flag-task-complete! res-city-bbush-get-to-28 city-bbush-get-to-28) + (autosplit-flag-task-complete! res-city-bbush-get-to-29 city-bbush-get-to-29) + (autosplit-flag-task-complete! res-city-bbush-get-to-30 city-bbush-get-to-30) + (autosplit-flag-task-complete! res-city-bbush-get-to-31 city-bbush-get-to-31) + (autosplit-flag-task-complete! res-city-bbush-get-to-32 city-bbush-get-to-32) + (autosplit-flag-task-complete! res-city-bbush-get-to-33 city-bbush-get-to-33) + (autosplit-flag-task-complete! res-city-bbush-get-to-34 city-bbush-get-to-34) + (autosplit-flag-task-complete! res-city-bbush-get-to-35 city-bbush-get-to-35) + (autosplit-flag-task-complete! res-city-bbush-get-to-36 city-bbush-get-to-36) + (autosplit-flag-task-complete! res-city-bbush-get-to-37 city-bbush-get-to-37) + (autosplit-flag-task-complete! res-city-bbush-get-to-38 city-bbush-get-to-38) + (autosplit-flag-task-complete! res-city-bbush-get-to-39 city-bbush-get-to-39) + (autosplit-flag-task-complete! res-city-bbush-get-to-40 city-bbush-get-to-40) + (autosplit-flag-task-complete! res-city-bbush-get-to-41 city-bbush-get-to-41) + (autosplit-flag-task-complete! res-city-bbush-get-to-42 city-bbush-get-to-42) + (autosplit-flag-task-complete! res-city-bbush-get-to-43 city-bbush-get-to-43) + (autosplit-flag-task-complete! res-city-bbush-get-to-44 city-bbush-get-to-44) + (autosplit-flag-task-complete! res-desert-bbush-ring-1 desert-bbush-ring-1) + (autosplit-flag-task-complete! res-desert-bbush-ring-2 desert-bbush-ring-2) + (autosplit-flag-task-complete! res-wascity-bbush-ring-3 wascity-bbush-ring-3) + (autosplit-flag-task-complete! res-wascity-bbush-ring-4 wascity-bbush-ring-4) + (autosplit-flag-task-complete! res-city-bbush-ring-5 city-bbush-ring-5) + (autosplit-flag-task-complete! res-city-bbush-ring-6 city-bbush-ring-6) + (autosplit-flag-task-complete! res-desert-bbush-egg-spider-1 desert-bbush-egg-spider-1) + (autosplit-flag-task-complete! res-desert-bbush-spirit-chase-1 desert-bbush-spirit-chase-1) + (autosplit-flag-task-complete! res-wascity-bbush-spirit-chase-2 wascity-bbush-spirit-chase-2) + (autosplit-flag-task-complete! res-city-bbush-spirit-chase-3 city-bbush-spirit-chase-3) + (autosplit-flag-task-complete! res-desert-bbush-timer-chase-1 desert-bbush-timer-chase-1) + (autosplit-flag-task-complete! res-wascity-bbush-timer-chase-2 wascity-bbush-timer-chase-2) + (autosplit-flag-task-complete! res-desert-bbush-air-time desert-bbush-air-time) + (autosplit-flag-task-complete! res-desert-bbush-total-air-time desert-bbush-total-air-time) + (autosplit-flag-task-complete! res-desert-bbush-jump-distance desert-bbush-jump-distance) + (autosplit-flag-task-complete! res-desert-bbush-total-jump-distance desert-bbush-total-jump-distance) + (autosplit-flag-task-complete! res-desert-bbush-roll-count desert-bbush-roll-count) + (autosplit-flag-task-complete! res-desert-bbush-time-trial-1 desert-bbush-time-trial-1) + (autosplit-flag-task-complete! res-desert-bbush-rally desert-bbush-rally) + (autosplit-flag-task-complete! res-city-bbush-port-attack city-bbush-port-attack) + (autosplit-flag-task-complete! res-desert-rescue-bbush desert-rescue-bbush) + (autosplit-flag-task-complete! res-city-gun-course-play-for-fun city-gun-course-play-for-fun) + (autosplit-flag-task-complete! res-city-jetboard-bbush city-jetboard-bbush) + (autosplit-flag-task-complete! res-desert-bbush-destroy-interceptors desert-bbush-destroy-interceptors) + ;; misc other tasks + (autosplit-flag-task-node-closed! arena-fight-1-throne arena-fight-1-throne) ;; after arena 1 cutscene + ;; debug only, draw stuff to the screen so i don't have to stare at a memory editor + (if AUTOSPLITTER_DEBUG (debug-draw this))) + +(defmethod reset! ((this autosplit-info)) + (set! (-> this game-hash) (pc-get-unix-timestamp)) + (set! (-> this errol-dead?) 0)) + +(defmethod debug-draw ((this autosplit-info)) + (format (clear *temp-string*) "errol-dead?: ~D~%" (-> this errol-dead?)) + (format *temp-string* "all-collectables-acquired?: ~D~%" (-> this all-collectables-acquired?)) + (with-dma-buffer-add-bucket ((buf (-> (current-frame) global-buf)) (bucket-id debug-no-zbuf1)) + ;; reset bucket settings prior to drawing - font won't do this for us, and + ;; draw-raw-image can sometimes mess them up. (intro sequence) + (dma-buffer-add-gs-set-flusha buf + (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1))) + (let ((font-ctx (new 'stack 'font-context *font-default-matrix* 10 50 0.0 (font-color default) (font-flags shadow kerning large)))) + (set! (-> font-ctx scale) 0.325) + (draw-string-adv *temp-string* buf font-ctx)))) diff --git a/goal_src/jak3/pc/features/speedruns-h.gc b/goal_src/jak3/pc/features/speedruns-h.gc new file mode 100644 index 0000000000..3d5bede323 --- /dev/null +++ b/goal_src/jak3/pc/features/speedruns-h.gc @@ -0,0 +1,134 @@ +;;-*-Lisp-*- +(in-package goal) + +;; TEST - safe with malformed entries + +(deftype speedrun-timer (process) + ((draw? symbol) + (started? symbol) + (stopped? symbol) + (start-time time-frame) + (end-time time-frame) + (recorded-time float)) + (:methods + (draw-timer (_type_) object) + (start! (_type_) object) + (reset! (_type_) object) + (stop! (_type_) float)) + (:state-methods + idle)) + +(defbehavior speedrun-timer-init-by-other speedrun-timer () + (false! (-> self draw?)) + (false! (-> self started?)) + (set! (-> self start-time) 0) + (set! (-> self end-time) 0) + (set! (-> self recorded-time) 0.0) + (go-virtual idle)) + +(defstate idle (speedrun-timer) + :virtual #t + :code + (behavior () + (loop + (when (-> self draw?) + (draw-timer self)) + (suspend)))) + +;; TODO - put in util +(deftype objective-zone (process) + ((start? symbol) + (v1 vector :inline) + (v2 vector :inline) + (on-enter (function none)) + (on-exit (function none))) + (:methods + (draw-zone (_type_) object)) + (:state-methods + waiting-for-player + player-inside)) + +(deftype objective-zone-init-params (structure) + ((v1 vector :inline) + (v2 vector :inline))) + +(defenum speedrun-practice-flags + (none)) + +;; reset method +(deftype speedrun-practice-objective (structure) + ((index int32) + (flags speedrun-practice-flags) + (completed-task game-task) + (features game-feature) + (secrets game-secrets) + (vehicles game-vehicles) + (starting-position vector) + (starting-rotation vector) + (starting-camera-position vector) + (starting-camera-rotation matrix) + (end-task game-task) + (start-zone-init-params objective-zone-init-params) + (start-zone (pointer objective-zone)) + (end-zone-init-params objective-zone-init-params) + (end-zone (pointer objective-zone))) + (:methods + (draw-info (_type_) object) + (reset! (_type_) object))) + +(defenum speedrun-category + :type uint32 + ;; Main Categories + (newgame-normal 0) + (newgame-heromode 1) + ;; TODO - add ILs and such later + ;; there's no point in adding categories that just start from a new-game and have later restrictions + ;; because we aren't going to modify the code to make that possible + ;; ie. removing mars tomb skip if you pick "all missions" + ;; Random one for experimentation + (all-cheats-allowed 999) + (custom 9999)) + +(deftype speedrun-custom-category (structure) + ((index int32) + (secrets game-secrets) + (features game-feature) + (vehicles game-vehicles) + (forbidden-features game-feature) + (pc-cheats pc-cheats) + (completed-task game-task))) + +(deftype speedrun-info (structure) + ((category speedrun-category) + (active-custom-category speedrun-custom-category) + (dump-custom-category speedrun-custom-category) + (display-run-info? symbol) + (practicing? symbol) + (active-practice-objective speedrun-practice-objective) + (waiting-to-record-practice-attempt? symbol) + (run-started-at time-frame)) + (:methods + (set-category! (_type_ speedrun-category) object) + (start-run! (_type_) object) + (enforce-settings! (_type_) object) + (update! (_type_) object) + (draw-run-info (_type_) object))) + +(define-extern *speedrun-info* speedrun-info) + +(defenum speedrun-menu-command + :type uint32 + (reset 0) + (exit 1)) + +(deftype speedrun-manager (process) + ((popup-menu (pointer popup-menu)) + (ignore-menu-toggle? symbol) + (opened-with-start? symbol) + (timer (pointer speedrun-timer))) + (:methods + (draw-menu (_type_) object)) + (:state-methods + idle)) + +(define-extern *speedrun-manager* (pointer speedrun-manager)) diff --git a/goal_src/jak3/pc/features/speedruns.gc b/goal_src/jak3/pc/features/speedruns.gc new file mode 100644 index 0000000000..9b88ceb22d --- /dev/null +++ b/goal_src/jak3/pc/features/speedruns.gc @@ -0,0 +1,766 @@ +;;-*-Lisp-*- +(in-package goal) + +;; TODO later - customize menu open keybind + +(define-extern task-close! (function string symbol)) + +(define-extern *pc-dead-pool* dead-pool) + +(define *speedrun-info* (new 'static 'speedrun-info)) + +(set! (-> *speedrun-info* active-custom-category) (new 'static 'speedrun-custom-category)) + +(set! (-> *speedrun-info* dump-custom-category) (new 'static 'speedrun-custom-category)) + +(set! (-> *speedrun-info* active-practice-objective) (new 'static 'speedrun-practice-objective)) + +(set! (-> *speedrun-info* active-practice-objective starting-position) (new 'static 'vector)) + +(set! (-> *speedrun-info* active-practice-objective starting-rotation) (new 'static 'vector)) + +(set! (-> *speedrun-info* active-practice-objective starting-camera-position) (new 'static 'vector)) + +(set! (-> *speedrun-info* active-practice-objective starting-camera-rotation) (new 'static 'matrix)) + +(set! (-> *speedrun-info* active-practice-objective start-zone-init-params) (new 'static 'objective-zone-init-params)) + +(set! (-> *speedrun-info* active-practice-objective end-zone-init-params) (new 'static 'objective-zone-init-params)) + +(defmethod draw-timer ((this speedrun-timer)) + (clear *temp-string*) + (clear *pc-encoded-temp-string*) + (cond + ((-> this started?) + (format *temp-string* "~,,2fs~%" (* (the float (- (current-time) (-> this start-time))) 0.0033333334))) + ((and (!= 0 (-> this end-time))) + (format *temp-string* "~,,2fs~%" (* (the float (- (-> this end-time) (-> this start-time))) 0.0033333334))) + (else (format *temp-string* "0.0s~%"))) + (when *target* + (format *temp-string* "~,,2M~%" (-> *target* control ctrl-xz-vel))) + (pc-encode-utf8-string *temp-string* *pc-encoded-temp-string*) + (with-dma-buffer-add-bucket ((buf (-> (current-frame) global-buf)) (bucket-id debug-no-zbuf1)) + ;; reset bucket settings prior to drawing - font won't do this for us, and + ;; draw-raw-image can sometimes mess them up. (intro sequence) + (dma-buffer-add-gs-set-flusha buf + (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1))) + (let ((font-ctx (new 'stack 'font-context *font-default-matrix* 256 350 0.0 (font-color default) (font-flags middle shadow kerning large)))) + (set! (-> font-ctx scale) 0.325) + (draw-string-adv *pc-encoded-temp-string* buf font-ctx)))) + +(defmethod start! ((this speedrun-timer)) + (true! (-> this started?)) + (false! (-> this stopped?)) + (set-time! (-> this start-time)) + (set! (-> this end-time) 0)) + +(defmethod reset! ((this speedrun-timer)) + (false! (-> this started?)) + (false! (-> this stopped?)) + (set! (-> this start-time) 0) + (set! (-> this end-time) 0)) + +(defmethod stop! ((this speedrun-timer)) + (when (not (-> this stopped?)) + (false! (-> this started?)) + (true! (-> this stopped?)) + (set-time! (-> this end-time)) + (set! (-> this recorded-time) (* (the float (- (-> this end-time) (-> this start-time))) 0.0033333334))) + (-> this recorded-time)) + +(defmethod set-category! ((this speedrun-info) (category speedrun-category)) + (set! (-> this category) category)) + +(defconstant HERO_MODE_SECRETS + (game-secrets hero-mode + endless-ammo + invulnerable + endless-dark + endless-light + unlimited-turbos + vehicle-hit-points + board-fast + vehicle-fox + vehicle-mirage + vehicle-x-ride + darkjak-tracking + button-invis + gun-upgrade-red-1 + gun-upgrade-red-2 + gun-upgrade-red-3 + gun-upgrade-yellow-1 + gun-upgrade-yellow-2 + gun-upgrade-yellow-3 + gun-upgrade-blue-1 + gun-upgrade-blue-2 + gun-upgrade-blue-3 + gun-upgrade-dark-1 + gun-upgrade-dark-2 + gun-upgrade-dark-3 + gun-upgrade-ammo-red + gun-upgrade-ammo-yellow + gun-upgrade-ammo-blue + gun-upgrade-ammo-dark)) + +(defconstant HERO_MODE_FEATURES + (game-feature gun + gun-red-1 + gun-red-2 + gun-red-3 + gun-yellow-1 + gun-yellow-2 + gun-yellow-3 + gun-blue-1 + gun-blue-2 + gun-blue-3 + gun-dark-1 + gun-dark-2 + gun-dark-3 + board + gun-upgrade-yellow-ammo-1 + gun-upgrade-yellow-ammo-2 + gun-upgrade-red-ammo-1 + gun-upgrade-red-ammo-2 + gun-upgrade-blue-ammo-1 + gun-upgrade-blue-ammo-2 + gun-upgrade-dark-ammo-1 + gun-upgrade-dark-ammo-2 + board-launch + board-zap + darkjak + darkjak-bomb0 + darkjak-bomb1 + lightjak + lightjak-regen + lightjak-freeze + lightjak-shield + armor0 + armor1 + armor2 + armor3 + lighteco + darkeco)) + +(defmethod start-run! ((this speedrun-info)) + ;; randomize game id so the autosplitter knows to restart + (reset! *autosplit-info-jak3*) + ;; turn on speedrun verification display + (true! (-> this display-run-info?)) + (send-event (ppointer->process *speedrun-manager*) 'start-run) + ;; ensure any required settings are enabled + (enforce-settings! this) + ;; finalize any category specific setup code + (case (-> this category) + (((speedrun-category newgame-normal)) + (set! (-> *game-info* mode) 'debug) + (initialize! *game-info* 'game (the game-save #f) (the string #f) (the resetter-spec #f)) + (set! (-> *game-info* mode) 'play) + (start 'play (get-continue-by-name *game-info* "wasstada-jump-training")) + (play-task (game-task arena-training-1) 'debug #f)) + (((speedrun-category newgame-heromode)) + (process-spawn-function process + (lambda :behavior process () + (set! (-> *game-info* mode) 'debug) + (initialize! *game-info* 'game (the game-save #f) (the string #f) (the resetter-spec #f)) + (set! (-> *game-info* mode) 'play) + (logior! (-> *game-info* secrets) (game-secrets hero-mode)) + (logior! (-> *game-info* purchase-secrets) (game-secrets hero-mode)) + (start 'play (get-continue-by-name *game-info* "wasstada-jump-training")) + (play-task (game-task arena-training-1) 'debug #f) + (until (and *target* (= (-> *target* next-state name) 'target-stance)) + (suspend)) + (set! (-> *game-info* secrets) HERO_MODE_SECRETS) + (set! (-> *game-info* purchase-secrets) HERO_MODE_SECRETS) + (set! (-> *game-info* features) HERO_MODE_FEATURES)))) + (((speedrun-category all-cheats-allowed)) + (process-spawn-function process + (lambda :behavior process () + (set! (-> *game-info* mode) 'debug) + (initialize! *game-info* 'game (the game-save #f) (the string #f) (the resetter-spec #f)) + (set! (-> *game-info* mode) 'play) + (start 'play (get-continue-by-name *game-info* "wasstada-jump-training")) + (play-task (game-task arena-training-1) 'debug #f)))) + (((speedrun-category custom)) + (process-spawn-function process + (lambda :behavior process () + (clear *temp-string*) + (pc-sr-mode-get-custom-category-continue-point (-> *speedrun-info* active-custom-category index) *temp-string*) + (if (string= *temp-string* EMPTY_STRING) + (initialize! *game-info* 'game (the game-save #f) "intro-start" (the resetter-spec #f)) + (initialize! *game-info* 'game (the game-save #f) *temp-string* (the resetter-spec #f))) + (until (and *target* (= (-> *target* next-state name) 'target-stance)) + (suspend)) + (when (nonzero? (-> *speedrun-info* active-custom-category completed-task)) + (task-resolution-close! (-> *speedrun-info* active-custom-category completed-task))))))) + (if (!= -1 (-> *game-info* auto-save-which)) (set! (-> *setting-control* user-default auto-save) #t))) + +(defmethod enforce-settings! ((this speedrun-info)) + (true! (-> *pc-settings* ps2-actor-vis?)) ;; force PS2 actor visibility + (set-frame-rate! *pc-settings* 60 #t) ;; force FPS to `60` + ;; For posterity, the main reason why changing the cheats is useful is for two main reasons: + ;; - If you are playing a category that requires cheats (ie. a turbo jetboard one) you'd + ;; probably like the game to automatically set the appropriate ones for you + ;; - If you are playing a category that forbids cheats, you wouldn't want your run invalidated because you forgot + (case (-> this category) + (((speedrun-category newgame-normal) (speedrun-category newgame-heromode)) + ;; disable any active cheats + (set! (-> *pc-settings* cheats) (pc-cheats))) + (((speedrun-category custom)) + (set! (-> *game-info* purchase-secrets) (-> *speedrun-info* active-custom-category secrets)) + (set! (-> *game-info* secrets) (-> *speedrun-info* active-custom-category secrets)) + (logior! (-> *game-info* features) (-> *speedrun-info* active-custom-category features)) + (logclear! (-> *game-info* features) (-> *speedrun-info* active-custom-category forbidden-features)) + (logior! (-> *game-info* vehicles) (-> *speedrun-info* active-custom-category vehicles)) + (set! (-> *pc-settings* cheats) (-> *speedrun-info* active-custom-category pc-cheats))))) + +(defmethod draw-zone ((this objective-zone)) + (add-debug-box #t + (bucket-id debug) + (-> this v1) + (-> this v2) + (if (-> this start?) (static-rgba #xff #xff #x00 #x80) (static-rgba #xff #x00 #xff #x80)))) + +(defstate waiting-for-player (objective-zone) + :virtual #t + :event + (behavior ((proc process) (argc int) (message symbol) (block event-message-block)) + #t) + :trans + (behavior () + ;; Check to see if we have entered the zone + (let ((min-point-x (fmin (-> self v1 x) (-> self v2 x))) + (min-point-y (fmin (-> self v1 y) (-> self v2 y))) + (min-point-z (fmin (-> self v1 z) (-> self v2 z))) + (max-point-x (fmax (-> self v1 x) (-> self v2 x))) + (max-point-y (fmax (-> self v1 y) (-> self v2 y))) + (max-point-z (fmax (-> self v1 z) (-> self v2 z))) + (pos (target-pos 0))) + (when (and (and (<= min-point-x (-> pos x)) (<= (-> pos x) max-point-x)) + (and (<= min-point-y (-> pos y)) (<= (-> pos y) max-point-y)) + (and (<= min-point-z (-> pos z)) (<= (-> pos z) max-point-z))) + (when (nonzero? (-> self on-enter)) + ((-> self on-enter))) + (go-virtual player-inside)))) + :code + (behavior () + (loop + (draw-zone self) + (suspend)))) + +(defstate player-inside (objective-zone) + :virtual #t + :trans + (behavior () + ;; Check to see if we have entered the zone + (let ((min-point-x (fmin (-> self v1 x) (-> self v2 x))) + (min-point-y (fmin (-> self v1 y) (-> self v2 y))) + (min-point-z (fmin (-> self v1 z) (-> self v2 z))) + (max-point-x (fmax (-> self v1 x) (-> self v2 x))) + (max-point-y (fmax (-> self v1 y) (-> self v2 y))) + (max-point-z (fmax (-> self v1 z) (-> self v2 z))) + (pos (target-pos 0))) + (when (not (and (and (<= min-point-x (-> pos x)) (<= (-> pos x) max-point-x)) + (and (<= min-point-y (-> pos y)) (<= (-> pos y) max-point-y)) + (and (<= min-point-z (-> pos z)) (<= (-> pos z) max-point-z)))) + (when (nonzero? (-> self on-exit)) + ((-> self on-exit))) + (go-virtual waiting-for-player)))) + :code + (behavior () + (loop + (draw-zone self) + (suspend)))) + +(defbehavior objective-zone-init-by-other objective-zone ((start? symbol) (params objective-zone-init-params)) + (set! (-> self start?) start?) + (vector-copy! (-> self v1) (-> params v1)) + (vector-copy! (-> self v2) (-> params v2)) + (go-virtual waiting-for-player)) + +(defmethod draw-info ((this speedrun-practice-objective)) + (clear *temp-string*) + (clear *pc-encoded-temp-string*) + (pc-sr-mode-get-practice-entry-name (-> this index) *pc-encoded-temp-string*) + (format *temp-string* "Practicing: ~S~%" *pc-encoded-temp-string*) + (if (> (pc-sr-mode-get-practice-entry-history-attempts (-> this index)) 0) + (format *temp-string* + "History: ~D/~D (~,,2f%)~%" + (pc-sr-mode-get-practice-entry-history-success (-> this index)) + (pc-sr-mode-get-practice-entry-history-attempts (-> this index)) + (* 100.0 + (/ (the float (pc-sr-mode-get-practice-entry-history-success (-> this index))) + (the float (pc-sr-mode-get-practice-entry-history-attempts (-> this index)))))) + (format *temp-string* "History: --~%")) + (if (> (pc-sr-mode-get-practice-entry-session-attempts (-> this index)) 0) + (format *temp-string* + "Session: ~D/~D (~,,2f%)~%" + (pc-sr-mode-get-practice-entry-session-success (-> this index)) + (pc-sr-mode-get-practice-entry-session-attempts (-> this index)) + (* 100.0 + (/ (the float (pc-sr-mode-get-practice-entry-session-success (-> this index))) + (the float (pc-sr-mode-get-practice-entry-session-attempts (-> this index)))))) + (format *temp-string* "Session: --~%")) + (pc-sr-mode-get-practice-entry-avg-time (-> this index) *pc-encoded-temp-string*) + (format *temp-string* "Average Time: ~Ss~%" *pc-encoded-temp-string*) + (pc-sr-mode-get-practice-entry-fastest-time (-> this index) *pc-encoded-temp-string*) + (format *temp-string* "Fastest Time: ~Ss~%" *pc-encoded-temp-string*) + (format *temp-string* "\c91 L3: Reset~%") + (pc-encode-utf8-string *temp-string* *pc-encoded-temp-string*) + (with-dma-buffer-add-bucket ((buf (-> (current-frame) global-buf)) (bucket-id debug-no-zbuf2)) + ;; reset bucket settings prior to drawing - font won't do this for us, and + ;; draw-raw-image can sometimes mess them up. (intro sequence) + (dma-buffer-add-gs-set-flusha buf + (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1))) + (let ((font-ctx (new 'stack 'font-context *font-default-matrix* 510 20 0.0 (font-color default) (font-flags right shadow kerning large)))) + (set! (-> font-ctx scale) 0.325) + (draw-string-adv *pc-encoded-temp-string* buf font-ctx)))) + +(defmethod reset! ((this speedrun-practice-objective)) + ;; record attempt if attempt was started + (when (-> *speedrun-info* waiting-to-record-practice-attempt?) + (pc-sr-mode-record-practice-entry-attempt! (-> this index) + #f + (&-> (the speedrun-timer (ppointer->process (-> *speedrun-manager* 0 timer))) recorded-time))) + ;; TODO - load checkpoint if not already in that checkpoint + ;; TODO - set features / cheats / completed-task / etc + ;; Update player position + (vector-copy! (-> *target* root trans) (-> this starting-position)) + (vector-copy! (-> *target* root quat) (-> this starting-rotation)) + ;; - get off jetboard and reset speed + (vector-copy! (-> *target* control transv) *zero-vector*) + (send-event *target* 'change-mode 'normal) + ;; Update camera position and rotation + (vector-copy! (-> *camera-combiner* trans) (-> this starting-camera-position)) + (matrix-identity! (-> *camera-combiner* inv-camera-rot)) + (matrix-copy! (-> *camera-combiner* inv-camera-rot) (-> this starting-camera-rotation)) + (process-spawn-function process + (lambda :behavior process () + (suspend) + (send-event *camera* 'teleport) + (deactivate self))) + (cam-master-activate-slave #f)) + +(define *speedrun-popup-menu-entries* + (new 'static + 'boxed-array + :type + popup-menu-entry + (new 'static + 'popup-menu-button + :label "Reset" + :on-confirm + (lambda () + (send-event (ppointer->process *speedrun-manager*) 'invoke (speedrun-menu-command reset)) + (send-event (-> *speedrun-manager* 0 popup-menu 0) 'close-menu))) + (new 'static + 'popup-menu-submenu + :label "Built-in Category Select" + :entries + (new 'static + 'boxed-array + :type + popup-menu-entry + (new 'static + 'popup-menu-flag + :label "Normal" + :on-confirm + (lambda () + (set-category! *speedrun-info* (speedrun-category newgame-normal))) + :is-toggled? + (lambda () + (= (-> *speedrun-info* category) (speedrun-category newgame-normal)))) + (new 'static + 'popup-menu-flag + :label "Hero Mode" + :on-confirm + (lambda () + (set-category! *speedrun-info* (speedrun-category newgame-heromode))) + :is-toggled? + (lambda () + (= (-> *speedrun-info* category) (speedrun-category newgame-heromode)))) + (new 'static + 'popup-menu-flag + :label "All Cheats Allowed" + :on-confirm + (lambda () + (set-category! *speedrun-info* (speedrun-category all-cheats-allowed))) + :is-toggled? + (lambda () + (= (-> *speedrun-info* category) (speedrun-category all-cheats-allowed)))))) + (new 'static + 'popup-menu-dynamic-submenu + :label "Custom Category Select" + :get-length + (lambda () + (pc-sr-mode-get-custom-category-amount)) + :get-entry-label + (lambda ((index int) (str-dest string)) + (pc-sr-mode-get-custom-category-name index str-dest)) + :on-entry-confirm + (lambda ((index int)) + ;; hydrate from cpp + (pc-sr-mode-init-custom-category-info! index (-> *speedrun-info* active-custom-category)) + (set-category! *speedrun-info* (speedrun-category custom))) + :entry-selected? + (lambda ((index int)) + (and (= (-> *speedrun-info* category) (speedrun-category custom)) + (= index (-> *speedrun-info* active-custom-category index))))) + ;; TODO - disabled until finalized + ; (new 'static + ; 'popup-menu-dynamic-submenu + ; :label "Practice select" + ; :entry-disabled? + ; (lambda () + ; (not (-> *speedrun-info* practicing?))) + ; :get-length + ; (lambda () + ; (pc-sr-mode-get-practice-entries-amount)) + ; :get-entry-label + ; (lambda ((index int) (str-dest string)) + ; (pc-sr-mode-get-practice-entry-name index str-dest)) + ; :on-entry-confirm + ; (lambda ((index int)) + ; ;; turn on timer + ; (set! (-> (the speedrun-timer (ppointer->process (-> *speedrun-manager* 0 timer))) draw?) #t) + ; ;; tear down old processes + ; (when (nonzero? (-> *speedrun-info* active-practice-objective start-zone)) + ; (deactivate (-> *speedrun-info* active-practice-objective start-zone 0))) + ; (when (nonzero? (-> *speedrun-info* active-practice-objective end-zone)) + ; (deactivate (-> *speedrun-info* active-practice-objective end-zone 0))) + ; ;; init from cpp + ; (pc-sr-mode-init-practice-info! index (-> *speedrun-info* active-practice-objective)) + ; ;; startup new processes + ; (set! (-> *speedrun-info* active-practice-objective start-zone) + ; (the (pointer objective-zone) + ; (process-spawn objective-zone #t (-> *speedrun-info* active-practice-objective start-zone-init-params)))) + ; (set! (-> *speedrun-info* active-practice-objective start-zone 0 on-exit) + ; (lambda () + ; (start! (the speedrun-timer (ppointer->process (-> *speedrun-manager* 0 timer)))) + ; (set! (-> *speedrun-info* waiting-to-record-practice-attempt?) #t) + ; (none))) + ; (set! (-> *speedrun-info* active-practice-objective start-zone 0 on-enter) + ; (lambda () + ; (when (and *target* (>= (-> *target* control ctrl-xz-vel) (meters 30.0))) + ; (vector-copy! (-> *target* control transv) *zero-vector*)) + ; (set! (-> *speedrun-info* waiting-to-record-practice-attempt?) #f) + ; (reset! (the speedrun-timer (ppointer->process (-> *speedrun-manager* 0 timer)))) + ; (none))) + ; (when (= 0 (-> *speedrun-info* active-practice-objective end-task)) + ; (set! (-> *speedrun-info* active-practice-objective end-zone) + ; (the (pointer objective-zone) + ; (process-spawn objective-zone #f (-> *speedrun-info* active-practice-objective end-zone-init-params)))) + ; (set! (-> *speedrun-info* active-practice-objective end-zone 0 on-enter) + ; (lambda () + ; (when (-> *speedrun-info* waiting-to-record-practice-attempt?) + ; (stop! (the speedrun-timer (ppointer->process (-> *speedrun-manager* 0 timer)))) + ; (if (pc-sr-mode-record-practice-entry-attempt! (-> *speedrun-info* active-practice-objective index) + ; #t + ; (&-> (the speedrun-timer (ppointer->process (-> *speedrun-manager* 0 timer))) recorded-time)) + ; (sound-play "skill-pickup") + ; (sound-play "menu-pick")) + ; (set! (-> *speedrun-info* waiting-to-record-practice-attempt?) #f)) + ; (none)))) + ; (set! (-> *speedrun-info* practicing?) #t) + ; (reset! (-> *speedrun-info* active-practice-objective)) + ; (set-master-mode 'game) + ; (send-event (ppointer->process (-> *speedrun-manager* 0 popup-menu)) 'close-menu)) + ; :entry-selected? + ; (lambda ((index int)) + ; (and (-> *speedrun-info* practicing?) (= index (-> *speedrun-info* active-practice-objective index))))) + ; (new 'static + ; 'popup-menu-button + ; :label "Stop practicing" + ; :entry-disabled? + ; (lambda () + ; (not (-> *speedrun-info* practicing?))) + ; :on-confirm + ; (lambda () + ; (when (-> *speedrun-info* practicing?) + ; (when (nonzero? (-> *speedrun-info* active-practice-objective start-zone)) + ; (deactivate (-> *speedrun-info* active-practice-objective start-zone 0))) + ; (when (nonzero? (-> *speedrun-info* active-practice-objective end-zone)) + ; (deactivate (-> *speedrun-info* active-practice-objective end-zone 0)))) + ; (set! (-> *speedrun-info* practicing?) #f) + ; (set! (-> (the speedrun-timer (ppointer->process (-> *speedrun-manager* 0 timer))) draw?) #f))) + (new 'static + 'popup-menu-submenu + :label "Tools" + :entries + (new 'static + 'boxed-array + :type + popup-menu-entry + (new 'static + 'popup-menu-submenu + :label "Create custom category" + :entries + (new 'static + 'boxed-array + :type + popup-menu-entry + (new 'static + 'popup-menu-dynamic-submenu + :label "Select secrets" + :get-length + (lambda () + 58) + :get-entry-label + (lambda ((index int) (str-dest string)) + (copy-string<-string str-dest (bitfield->string game-secrets index))) + :on-entry-confirm + (lambda ((index int)) + (logxor! (-> *speedrun-info* dump-custom-category secrets) (shl 1 index))) + :entry-selected? + (lambda ((index int)) + (logtest? (-> *speedrun-info* dump-custom-category secrets) (shl 1 index))) + :on-reset + (lambda () + (set! (-> *speedrun-info* dump-custom-category secrets) (game-secrets)))) + (new 'static + 'popup-menu-dynamic-submenu + :label "Select features" + :get-length + (lambda () + 58) + :get-entry-label + (lambda ((index int) (str-dest string)) + (copy-string<-string str-dest (bitfield->string game-feature index))) + :on-entry-confirm + (lambda ((index int)) + (logxor! (-> *speedrun-info* dump-custom-category features) (shl 1 index))) + :entry-selected? + (lambda ((index int)) + (logtest? (-> *speedrun-info* dump-custom-category features) (shl 1 index))) + :on-reset + (lambda () + (set! (-> *speedrun-info* dump-custom-category features) (game-feature)))) + (new 'static + 'popup-menu-dynamic-submenu + :label "Select vehicles" + :get-length + (lambda () + 8) + :get-entry-label + (lambda ((index int) (str-dest string)) + (copy-string<-string str-dest (bitfield->string game-vehicles index))) + :on-entry-confirm + (lambda ((index int)) + (logxor! (-> *speedrun-info* dump-custom-category vehicles) (shl 1 index))) + :entry-selected? + (lambda ((index int)) + (logtest? (-> *speedrun-info* dump-custom-category vehicles) (shl 1 index))) + :on-reset + (lambda () + (set! (-> *speedrun-info* dump-custom-category vehicles) (game-vehicles)))) + (new 'static + 'popup-menu-dynamic-submenu + :label "Forbid features" + :get-length + (lambda () + 58) + :get-entry-label + (lambda ((index int) (str-dest string)) + (copy-string<-string str-dest (bitfield->string game-feature index))) + :on-entry-confirm + (lambda ((index int)) + (logxor! (-> *speedrun-info* dump-custom-category forbidden-features) (shl 1 index))) + :entry-selected? + (lambda ((index int)) + (logtest? (-> *speedrun-info* dump-custom-category forbidden-features) (shl 1 index))) + :on-reset + (lambda () + (set! (-> *speedrun-info* dump-custom-category forbidden-features) (game-feature)))) + (new 'static + 'popup-menu-dynamic-submenu + :label "Select cheats" + :get-length + (lambda () + 17) + :get-entry-label + (lambda ((index int) (str-dest string)) + (copy-string<-string str-dest (bitfield->string pc-cheats index))) + :on-entry-confirm + (lambda ((index int)) + (logxor! (-> *speedrun-info* dump-custom-category pc-cheats) (shl 1 index))) + :entry-selected? + (lambda ((index int)) + (logtest? (-> *speedrun-info* dump-custom-category pc-cheats) (shl 1 index))) + :on-reset + (lambda () + (set! (-> *speedrun-info* dump-custom-category pc-cheats) (pc-cheats)))) + (new 'static + 'popup-menu-dynamic-submenu + :label "Select completed task" + :get-length + (lambda () + (dec (the int (game-task max)))) + :get-entry-label + (lambda ((index int) (str-dest string)) + (copy-string<-string str-dest (enum->string game-task index))) + :on-entry-confirm + (lambda ((index int)) + (set! (-> *speedrun-info* dump-custom-category completed-task) (the game-task index))) + :entry-selected? + (lambda ((index int)) + (= (-> *speedrun-info* dump-custom-category completed-task) (the game-task index))) + :on-reset + (lambda () + (set! (-> *speedrun-info* dump-custom-category completed-task) (game-task none)))) + (new 'static + 'popup-menu-button + :label "Save new category to file" + :on-confirm + (lambda () + (pc-sr-mode-dump-new-custom-category (-> *speedrun-info* dump-custom-category)))))))) + (new 'static + 'popup-menu-button + :label "Exit" + :on-confirm + (lambda () + (send-event (ppointer->process *speedrun-manager*) 'invoke (speedrun-menu-command exit)))))) + +(define *speedrun-manager* (the (pointer speedrun-manager) #f)) + +(defbehavior speedrun-manager-init-by-other speedrun-manager () + (process-mask-clear! (-> self mask) menu pause) + (set! *speedrun-manager* (the (pointer speedrun-manager) (process->ppointer self))) + (set! (-> self popup-menu) (process-spawn popup-menu "Speedrun Menu" *speedrun-popup-menu-entries* :to self)) + (set! (-> self timer) (process-spawn speedrun-timer :to self)) + (set! (-> self ignore-menu-toggle?) #f) + (set! (-> self opened-with-start?) #f) + (set! (-> *speedrun-info* practicing?) #f) + (set! (-> *speedrun-info* waiting-to-record-practice-attempt?) #f) + (go-virtual idle)) + +(defmethod update! ((this speedrun-info)) + "A per frame update for speedrunning related stuff" + ;; Ensure the speedrunner menu process is enabled or destroyed + (when (and (-> *pc-settings* speedrunner-mode?) (not *speedrun-manager*)) + (process-spawn speedrun-manager :from *pc-dead-pool* :to *pc-pool*)) + (when (and (not (-> *pc-settings* speedrunner-mode?)) *speedrun-manager*) + (deactivate (-> *speedrun-manager* 0))) + ;; do speedrunner mode things + (when (-> *pc-settings* speedrunner-mode?) + ;; Update auto-splitter struct + (update! *autosplit-info-jak3*) + ;; see if we should stop drawing the run info (when you finish arena training) + (when (and (!= (-> this category) (speedrun-category custom)) (task-complete? *game-info* (game-task arena-training-1))) + (false! (-> this display-run-info?))) + ;; Draw info to the screen + (when (and (not (-> *speedrun-info* practicing?)) (-> this display-run-info?)) + (draw-run-info this)) + ;; enforce settings even if they've changed them + (enforce-settings! this) + ;; draw objective info if practicing + (when (-> *speedrun-info* practicing?) + (draw-info (-> this active-practice-objective))))) + +(defmethod draw-run-info ((this speedrun-info)) + "Draw speedrun related settings in the bottom left corner" + (when (and (-> *pc-settings* speedrunner-mode?) (-> this display-run-info?)) + (clear *temp-string*) + (clear *pc-encoded-temp-string*) + (clear *pc-cpp-temp-string*) + (cond + ((= (-> this category) (speedrun-category custom)) + (pc-sr-mode-get-custom-category-name (-> this active-custom-category index) *pc-cpp-temp-string*) + (format *temp-string* + "Category: ~S~%Secrets: ~D~%Features: ~D~%Forbidden Features: ~D~%Cheats: ~D~%Version: ~S~%" + *pc-cpp-temp-string* + (-> this active-custom-category secrets) + (-> this active-custom-category features) + (-> this active-custom-category forbidden-features) + (-> this active-custom-category pc-cheats) + *pc-settings-built-sha*)) + (else + (format *temp-string* + "Category: ~S~%PC Cheats: ~S~%Frame Rate: ~D~%PS2 Actor Vis?: ~S~%Version: ~S~%" + (enum->string speedrun-category (-> this category)) + (if (= (-> *pc-settings* cheats) (pc-cheats)) "None" (pc-cheats->string (-> *pc-settings* cheats) *temp-string2*)) + (-> *pc-settings* target-fps) + (if (-> *pc-settings* ps2-actor-vis?) "true" "false") + *pc-settings-built-sha*))) + (pc-encode-utf8-string *temp-string* *pc-encoded-temp-string*) + (with-dma-buffer-add-bucket ((buf (-> (current-frame) global-buf)) (bucket-id debug-no-zbuf2)) + ;; reset bucket settings prior to drawing - font won't do this for us, and + ;; draw-raw-image can sometimes mess them up. (intro sequence) + (dma-buffer-add-gs-set-flusha buf + (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1))) + (let ((font-ctx (new 'stack + 'font-context + *font-default-matrix* + 510 + (if (= (-> this category) (speedrun-category custom)) 355 365) + 0.0 + (font-color default) + (font-flags right shadow kerning large)))) + (set! (-> font-ctx scale) 0.325) + (draw-string-adv *pc-encoded-temp-string* buf font-ctx))))) + +;; Speedrun Menu + +(defmethod deactivate ((this speedrun-manager)) + (set! *speedrun-manager* (the (pointer speedrun-manager) #f)) + (call-parent-method this)) + +(defmethod draw-menu ((this speedrun-manager)) + ;; don't allow the menu to open during blackouts, apparently causes bugs + (if (< (-> *game-info* blackout-time) (current-time)) + ;; handle opening and closing the menu + (cond + ((!= (-> *pc-settings* speedrunner-mode-custom-bind) 0) + ;; the user has let go of the keybind completely or partially, allow the bind to trigger again + (when (and (-> this ignore-menu-toggle?) + (!= (cpad-hold 0) (logior (cpad-hold 0) (-> *pc-settings* speedrunner-mode-custom-bind)))) + (false! (-> this ignore-menu-toggle?))) + ;; bind handler + (when (and (not (-> this ignore-menu-toggle?)) + (= (cpad-hold 0) (logior (cpad-hold 0) (-> *pc-settings* speedrunner-mode-custom-bind)))) + (send-event (ppointer->process (-> this popup-menu)) 'open-menu) + (logclear! (cpad-hold 0) (-> *pc-settings* speedrunner-mode-custom-bind)) + (logclear! (cpad-pressed 0) (-> *pc-settings* speedrunner-mode-custom-bind)) + (true! (-> this ignore-menu-toggle?)))) + (else + (when (and (-> this ignore-menu-toggle?) + (or (not (cpad-hold? 0 l1)) (not (cpad-hold? 0 r1))) + (or (and (-> this opened-with-start?) (not (cpad-hold? 0 start))) + (and (not (-> this opened-with-start?)) (not (cpad-hold? 0 select))))) + (set! (-> this ignore-menu-toggle?) #f)) + (when (and (cpad-hold? 0 l1) + (cpad-hold? 0 r1) + (or (cpad-hold? 0 select) (cpad-hold? 0 start)) + (not (-> this ignore-menu-toggle?))) + (send-event (ppointer->process (-> this popup-menu)) 'open-menu) + (cpad-clear! 0 l1 r1) + (cond + ((cpad-hold? 0 select) (cpad-clear! 0 select) (false! (-> this opened-with-start?))) + ((cpad-hold? 0 start) (cpad-clear! 0 start) (true! (-> this opened-with-start?)))) + (true! (-> this ignore-menu-toggle?))))))) + +(defstate idle (speedrun-manager) + :virtual #t + :event + (behavior ((proc process) (argc int) (message symbol) (block event-message-block)) + (case message + (('start-run) (set-time! (-> *speedrun-info* run-started-at))) + (('invoke) + (case (-> block param 0) + (((speedrun-menu-command reset)) (start-run! *speedrun-info*)) + (((speedrun-menu-command exit)) (set-master-mode 'game) (send-event (ppointer->process (-> self popup-menu)) 'close-menu)) + (else (format 0 "nyi: invoke ~D~%" (-> block param 0))))))) + :trans + (behavior () + (draw-menu self)) + :code + (behavior () + (until #f + (when (and (-> *speedrun-info* practicing?) (cpad-pressed? 0 l3)) + (reset! (-> *speedrun-info* active-practice-objective))) + (when (and (-> *speedrun-info* display-run-info?) + (= (-> *speedrun-info* category) (speedrun-category custom)) + (time-elapsed? (-> *speedrun-info* run-started-at) (seconds 15))) + (false! (-> *speedrun-info* display-run-info?))) + (suspend)))) diff --git a/goal_src/jak3/pc/pckernel-impl.gc b/goal_src/jak3/pc/pckernel-impl.gc index 524ca7d6e9..74f835b68c 100644 --- a/goal_src/jak3/pc/pckernel-impl.gc +++ b/goal_src/jak3/pc/pckernel-impl.gc @@ -42,6 +42,10 @@ (weather-good) ) +(defun pc-cheats->string ((cheats pc-cheats) (buf object)) + (bit-enum->string pc-cheats cheats buf) + buf) + ;; pc enum for languages. this is the game's languages + custom ones. (defenum pc-language :type uint16 @@ -72,7 +76,7 @@ (custom 999) ;; temp ) -;; The Jak 2 version of the pc-settings object. +;; The Jak 3 version of the pc-settings object. (deftype pc-settings-jak3 (pc-settings) (;; cheats (cheats pc-cheats) diff --git a/goal_src/jak3/pc/pckernel.gc b/goal_src/jak3/pc/pckernel.gc index 45d803f441..c684f355b8 100644 --- a/goal_src/jak3/pc/pckernel.gc +++ b/goal_src/jak3/pc/pckernel.gc @@ -303,9 +303,9 @@ (defmethod update-speedrun ((obj pc-settings-jak3)) "update speedrun module" ;; TODO - update to new with-profiler syntax - ;; (with-profiler "speedrun-update" - ;(update! *speedrun-info*) - ;;) + ; (with-profiler "speedrun-update" + (update! *speedrun-info*) + ; ) (none)) (defmethod update-video-hacks ((obj pc-settings-jak3)) @@ -751,7 +751,8 @@ ;; the actor pool for PC processes! it has space for 4 processes, with 16K of space. (define *pc-dead-pool* (new 'global 'dead-pool 4 (* 16 1024) "*pc-dead-pool*")) - +(set! (-> *pc-pool* clock) (-> *display* base-clock)) +(+! (-> *display* base-clock ref-count) 1) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/goal_src/jak3/pc/subtitle3-h.gc b/goal_src/jak3/pc/subtitle3-h.gc new file mode 100644 index 0000000000..d6cd494c65 --- /dev/null +++ b/goal_src/jak3/pc/subtitle3-h.gc @@ -0,0 +1,381 @@ +;;-*-Lisp-*- +(in-package goal) + +#| + + Code for subtitles for the PC port. A PC actor pool is provided, and the subtitle3 process lives there. + Jak 3 has subtitles, but only for cutscenes and only for the actual spoken text. + The subtitle process automatically looks for currently-playing audio in the gui control. + It looks for specific channels there, NOT including the movie or subtitle channel. + + This updated subtitle system has a few different features than the Jak 1 subtitle system: + - you can have multiple playing subtitles at once. Additional subtitles are rendered above the older ones, + just like real subtitles. This goes for both multiple subtitles within the same scene, and also multiple scenes + playing at once. + - it can "merge" with the pre-existing subtitle system. Some code in scene.gc is changed to redirect subtitles + to here to do that. + - you supply the start AND end times as opposed to just the start time. + - the speaker names are color-coded. + Note that subtitle images are NOT supported with this! Merge mode will also NOT work with subtitle images. + + Similarly to the generic text file, only one subtitles text file is loaded at once, stored in a specific + heap. + + |# + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; constants +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defconstant PC_SUBTITLE_FILE_SIZE (* 600 1024)) ;; 600K heap for subtitles. adjust later if necessary. +(defconstant PC_SUBTITLE_FILE_NAME "subti3") +(defconstant PC_SUBTITLE_QUEUE_SIZE 5) ;; up to 5 things that display subtitles can be detected at once +(defconstant PC_SUBTITLE_QUEUE_MAX_LINES 2) ;; up to 2 lines can be queued per queueable thing +(defconstant PC_SUBTITLE_MAX_LINES 10) ;; max subtitles that can be displayed at once: queue-size * queue-lines + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; types and enums +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;------------------------ +;; data +;;;------------------------ + + +(defenum pc-subtitle3-flags + :bitfield #t + :type uint16 + (offscreen) ;; speaker is offscreen. + (merge) ;; line of text comes from movie subtitles + ) + +;; the list of available speakers for subtitles +(defenum pc-subtitle3-speaker + :type uint16 + (none) ;; won't display a speaker - use this for tutorial messages etc. + + (jak) + (darkjak) + (daxter) + (pecker) + (ashelin) + (veger) + (samos) + (damas) + (kleiver) + (seem) + (errol) + (errol-hologram) ;; desert-hover-res + (sig) + (torn) + (tess) + (guard) + (guard-a) + (guard-b) + (keira) + (vin) + (onin) + (jinx) + (wastelander-male) + (wastelander-female) + (citizen-male) + (citizen-female) + (marauder) + (oracle) + (precursor) + (ottsel-leader) + (ottsel-surfer) + (ottsel-dummy) + (ottsel-veger) + (ottsel-tess) + (computer) + + ;; museum + (krew) + (baron) + + ;; naughty dog developer commentary + (scherr) + (arey) + (baldwin) + (schimpf) + (martinsen) + (phillips) + (yates) + + (max)) + +;; information about a single line of subtitles +(deftype subtitle3-line (structure) + ( + (start-frame float) ;; the first frame to show the line on + (end-frame float) ;; the last frame to show the line on + (text string) ;; the text for the subtitle3 line + (speaker pc-subtitle3-speaker) ;; who the line speaker is + (flags pc-subtitle3-flags) ;; flags + ) + :pack-me + ) + +;; an individual entry to a subtitle3 text making up a "scene" (audio file, spool), comprised of a series of lines +(deftype subtitle3-scene (structure) + ( + ;; the name of the spool-anim or audio file + (name string) + ;; the amount of lines + (length int32) + ;; line data + (lines (inline-array subtitle3-line)) + ) + :pack-me + :size-assert #xc ;; compact! + + (:methods + (get-line-at-pos (_type_ float int) subtitle3-line) + ) + ) + +;; the global subtitle3 text info bank +(deftype subtitle3-text-info (basic) + ((length int16) + (version int16) + (lang pc-language) + (speaker-length int16) + (speaker-names (pointer string)) + (data subtitle3-scene :inline :dynamic) + ) + + (:methods + (get-speaker (_type_ pc-subtitle3-speaker) string) + (get-scene-by-name (_type_ string) subtitle3-scene) + ) + ) + + +(defmacro subtitle3-flags? (sub &rest flags) + `(logtest? (-> ,sub flags) (pc-subtitle3-flags ,@flags))) + + +(defmethod inspect ((obj subtitle3-text-info)) + (if (not obj) + (return (the subtitle3-text-info #f))) + (format #t "[~8x] ~A~%" obj (-> obj type)) + (format #t "~1Tlength: ~D~%" (-> obj length)) + (format #t "~1Tversion: ~D~%" (-> obj version)) + (format #t "~1Tlang: ~D~%" (-> obj lang)) + (format #t "~1Tspeaker-names[~D] @ #x~x~%" (-> obj speaker-length) (-> obj speaker-names)) + (dotimes (i (-> obj speaker-length)) + (format #t "~2T[~D]: ~A~%" i (-> obj speaker-names i))) + (format #t "~1Tdata[0] @ #x~x~%" (-> obj data)) + (dotimes (i (-> obj length)) + (format #t "~2T--------~%") + (format #t "~2Tname: ~A~%" (-> obj data i name)) + (format #t "~2Tlines[~D] @ #x~x~%" (-> obj data i length) (-> obj data i lines)) + (dotimes (ii (-> obj data i length)) + (format #t "~3T[~f to ~f] (#x~x)(~S) ~A~%" (-> obj data i lines ii start-frame) (-> obj data i lines ii end-frame) + (-> obj data i lines ii flags) + (enum->string pc-subtitle3-speaker (-> obj data i lines ii speaker)) + (-> obj data i lines ii text))) + ) + obj) + + +;;;---------------------------------- +;; process type +;;;---------------------------------- + + +;; graphic parameters for subtitles +(deftype subtitle3-bank (structure) + ((scale float) + (width float) + (lines float) + ) + ) + +(define *SUBTITLE3-bank* + (new 'static 'subtitle3-bank + :scale 0.9 + :width 0.65 + :lines 2.0 + )) + + +(deftype subtitle3-queue-element (structure) + ((id sound-id) + (gui gui-connection) + ) + :pack-me + + (:methods + (clear-line (_type_) int)) + ) + +(deftype subtitle3-line-queue-element (structure) + ((line subtitle3-line) + (y float) + ) + :pack-me + + (:methods + (set-params! (_type_ subtitle3-line float) int)) + ) + +(deftype subtitle3-line-queue (structure) + ((elts subtitle3-line-queue-element PC_SUBTITLE_MAX_LINES :inline) + ) + :pack-me + ) + +;; the subtitle3 process! it lives on the PC actor pool +(deftype subtitle3 (process) + ( + (font font-context) ;; the font to use for the subtitles. + + (have-message? symbol) ;; if there is a message displaying at the bottom, move subtitles up + (have-minimap? symbol) ;; if there is a minimap displaying at the bottom, shrink subtitles + (have-subtitles? symbol) ;; #t if we rendered any subtitles on the last frame. + + (movie-mode? symbol) ;; #t if we're in movie mode + (movie-line string) ;; a copy of the current movie line + (movie-gui gui-connection) ;; the gui entry for the movie. we need this to put it in the gui queue + (movie-pos float) + + (gui-id sound-id) + ;; store the gui id of channels with subtitles that we find. + ;; that way if subtitle B appears above A, it wont move back down + ;; if A ends before B + (queue subtitle3-queue-element PC_SUBTITLE_QUEUE_SIZE :inline) + (lines subtitle3-line-queue 2 :inline) + (line-queue-idx int8) + + ;; debug + (cheat-backup symbol) + (checking-lines? symbol) + (current-debug-subtitle subtitle3-line) + (current-debug-scene int32) + (current-debug-line int32) + ) + + (:methods + (clear-queue (_type_) int) + (update-gui-connections (_type_) int) + (get-empty-queue (_type_) int) + (gui-queued? (_type_ gui-connection) symbol) + (add-to-queue (_type_ gui-connection) gui-connection) + (get-active-subtitles (_type_) int) + (subtitle-format (_type_ subtitle3-line) string) + (draw-subtitles (_type_) int) + (debug-print-queue (_type_) int) + (debug-print-speakers (_type_) int) + (start-gui (_type_) sound-id) + (stop-gui (_type_) sound-id) + ) + (:states + subtitle3-debug + subtitle3-debug-checking-lines) + ) + + + + +;;;---------------------------------------------- +;; globals +;;;---------------------------------------------- + + +;; the subtitle3 process. +(define *subtitle3* (the (pointer subtitle3) #f)) + +;; subtitle3 text data +(define *subtitle3-text* (the subtitle3-text-info #f)) +(kheap-alloc (define *subtitle3-text-heap* (new 'global 'kheap)) PC_SUBTITLE_FILE_SIZE) + +;; temp strings for name look-up +(define *vag-temp-string* (new 'global 'string 128 (the string #f))) +(define *vag-temp-string-2* (new 'global 'string 128 (the string #f))) + +;; speaker color table +(define *subtitle3-speaker-color-table* (the (pointer rgba) (malloc 'global (* (size-of rgba) (pc-subtitle3-speaker max))))) + +;; debug option +(define *display-subtitle-speakers* #f) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; helper functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defmethod length ((obj subtitle3-text-info)) + "Get the length (number of subtitle3 scenes) in a subtitle3-text-info." + (-> obj length) + ) + +(defmethod length ((obj subtitle3-scene)) + "Get the length (number of subtitle3 lines) in a subtitle3-scene." + (-> obj length) + ) + + +(defmacro set-subtitle-speaker-color! (speaker color) + "macro for setting a color in *subtitle3-speaker-color-table*" + `(set! (-> *subtitle3-speaker-color-table* (pc-subtitle3-speaker ,speaker)) ,color)) +(defmacro set-subtitle-speaker-color<-speaker! (speaker speaker-from) + "macro for setting a color in *subtitle3-speaker-color-table* the same as a different speaker" + `(set-subtitle-speaker-color! ,speaker (-> *subtitle3-speaker-color-table* (pc-subtitle3-speaker ,speaker-from)))) + +(defun set-subtitle-speaker-colors () + "fill the subtitle speaker color table" + + (dotimes (i (pc-subtitle3-speaker max)) + (set! (-> *subtitle3-speaker-color-table* i) (-> *font-work* color-table (font-color red) color 0)) + ) + + (set-subtitle-speaker-color! jak (static-rgba #x70 #x80 #x00 #x80)) + (set-subtitle-speaker-color! darkjak (static-rgba #x68 #x68 #x80 #x80)) + (set-subtitle-speaker-color! daxter (static-rgba #x80 #x35 #x00 #x80)) + (set-subtitle-speaker-color! samos (static-rgba #x30 #x80 #x08 #x80)) + (set-subtitle-speaker-color! pecker (static-rgba #x80 #x80 #x00 #x80)) + (set-subtitle-speaker-color! damas (static-rgba #x30 #x45 #x75 #x80)) + (set-subtitle-speaker-color! kleiver (static-rgba #x40 #x30 #x15 #x80)) + (set-subtitle-speaker-color! marauder (static-rgba #x50 #x30 #x15 #x80)) + (set-subtitle-speaker-color! seem (static-rgba #x80 #x45 #x00 #x80)) + (set-subtitle-speaker-color! veger (static-rgba #x40 #x10 #x10 #x80)) + (set-subtitle-speaker-color! krew (static-rgba #x10 #x48 #x10 #x80)) + (set-subtitle-speaker-color! baron (static-rgba #x60 #x00 #x00 #x80)) + (set-subtitle-speaker-color! ashelin (static-rgba #x80 #x18 #x18 #x80)) + (set-subtitle-speaker-color! torn (static-rgba #x40 #x40 #x50 #x80)) + (set-subtitle-speaker-color! errol (static-rgba #x80 #x10 #x00 #x80)) + (set-subtitle-speaker-color! sig (static-rgba #x70 #x70 #x80 #x80)) + (set-subtitle-speaker-color! vin (static-rgba #x38 #x80 #x80 #x80)) + (set-subtitle-speaker-color! guard (static-rgba #x00 #x50 #x80 #x80)) + (set-subtitle-speaker-color! keira (static-rgba #x00 #x40 #x28 #x80)) + (set-subtitle-speaker-color! tess (static-rgba #x80 #x80 #x38 #x80)) + (set-subtitle-speaker-color! onin (static-rgba #x80 #x80 #x80 #x80)) + (set-subtitle-speaker-color! jinx (static-rgba #x50 #x40 #x00 #x80)) + (set-subtitle-speaker-color! precursor (static-rgba #x00 #x60 #x80 #x80)) + (set-subtitle-speaker-color! computer (static-rgba #x60 #x60 #x60 #x80)) + (set-subtitle-speaker-color! citizen-male (static-rgba #x70 #x70 #x70 #x80)) + (set-subtitle-speaker-color! citizen-female (static-rgba #x70 #x70 #x70 #x80)) + + (set-subtitle-speaker-color<-speaker! ottsel-leader daxter) + (set-subtitle-speaker-color<-speaker! ottsel-surfer daxter) + (set-subtitle-speaker-color<-speaker! ottsel-dummy daxter) + (set-subtitle-speaker-color<-speaker! ottsel-veger veger) + (set-subtitle-speaker-color<-speaker! ottsel-tess tess) + (set-subtitle-speaker-color<-speaker! errol-hologram errol) + (set-subtitle-speaker-color<-speaker! guard-a guard) + (set-subtitle-speaker-color<-speaker! guard-b guard) + (set-subtitle-speaker-color<-speaker! kleiver wastelander-male) + (set-subtitle-speaker-color<-speaker! kleiver wastelander-female) + ) + + + diff --git a/goal_src/jak3/pc/subtitle3.gc b/goal_src/jak3/pc/subtitle3.gc new file mode 100644 index 0000000000..b34c653e4a --- /dev/null +++ b/goal_src/jak3/pc/subtitle3.gc @@ -0,0 +1,885 @@ +;;-*-Lisp-*- +(in-package goal) + +#| + + Code for subtitles for the PC port. A PC actor pool is provided, and the subtitle3 process lives there. + Jak 3 has subtitles, but only for cutscenes and only for the actual spoken text. + The subtitle process automatically looks for currently-playing audio in the gui control. + It looks for specific channels there, NOT including the movie or subtitle channel. + + This updated subtitle system has a few different features than the Jak 1 subtitle system: + - you can have multiple playing subtitles at once. Additional subtitles are rendered above the older ones, + just like real subtitles. This goes for both multiple subtitles within the same scene, and also multiple scenes + playing at once. + - it can "merge" with the pre-existing subtitle system. Some code in scene.gc is changed to redirect subtitles + to here to do that. + - you supply the start AND end times as opposed to just the start time. + - the speaker names are color-coded. + Note that subtitle images are NOT supported with this! Merge mode will also NOT work with subtitle images. + + Similarly to the generic text file, only one subtitles text file is loaded at once, stored in a specific + heap. + + |# + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; constants +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defconstant PC_SUBTITLE_Y_RECALC -99.0) + +(defconstant PC_SUBTITLE_DISABLE_MOVIE_MODE #f) + +(defconstant PC_SUB_DBG_Y 60) +(defconstant PC_SUB_DBG_CHECK_GROUP_SIZE 64) +(defglobalconstant PC_SUBTITLE_DEBUG #f) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; access subtitle heap +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defmethod get-speaker ((obj subtitle3-text-info) (speaker pc-subtitle3-speaker)) + "get the translated string for that speaker" + (if (and (> speaker (pc-subtitle3-speaker none)) (< speaker (-> obj speaker-length))) + (-> obj speaker-names speaker) + (the string #f)) + ) + +(defmethod get-scene-by-name ((obj subtitle3-text-info) (name string)) + "get a subtitle scene info with the corresponding name. #f = none found" + + ;; invalid name so return invalid scene. + (if (not name) + (return (the subtitle3-scene #f))) + + ;; bounds checking + (when (> (length name) (-> *vag-temp-string* allocated-length)) + (format 0 "vag temp string is too short!! wanted: ~D chars~%" (length name))) + + ;; uppercase the string so we have a consistent name format + (string-upcase name *vag-temp-string* #f) + (dotimes (i (length obj)) + ;; bounds checking + (when (> (length (-> obj data i name)) (-> *vag-temp-string-2* allocated-length)) + (format 0 "vag temp string is too short!! wanted: ~D chars~%" (length name))) + ;; name and kind matches, return that! + (string-upcase (-> obj data i name) *vag-temp-string-2* #f) + (when (string= *vag-temp-string-2* *vag-temp-string*) + (return (-> obj data i))) + ) + + (the subtitle3-scene #f)) + + +(defmethod get-line-at-pos ((obj subtitle3-scene) (pos float) (index int)) + "return the subtitle line at that position. #f = none found + index is which line to return, since you can have multiple lines that cover the same position." + + (let ((found 0)) + + (dotimes (i (length obj)) + (when (and (>= pos (-> obj lines i start-frame)) + (< pos (-> obj lines i end-frame))) + (when (= found index) + (return (-> obj lines i))) + (1+! found) + ))) + + (the subtitle3-line #f)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; loading files +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defun load-subtitle3-text-info ((txt-name string) (curr-text symbol) (heap kheap)) + "load a subtitles text file onto a heap. + txt-name = file name suffix + curr-text = a symbol to a subtitle3-text-info to link the file to + heap = the text heap to load the file onto" + + (let ((heap-sym-heap (the-as subtitle3-text-info (-> curr-text value))) + (lang (-> *setting-control* user-current subtitle-language)) + (load-status 0) + (heap-free (&- (-> heap top) (the-as uint (-> heap base))))) + + ;; current text has nothing loaded, or language doesn't match. + (when (or (= heap-sym-heap #f) + (!= (-> heap-sym-heap lang) lang)) + ;; so reload. + + ;; reset the text heap. + (kheap-reset heap) + + ;; try to load load... + (while (not (str-load (string-format "~D~S.TXT" lang txt-name) -1 (logand -64 (&+ (-> heap current) 63)) (&- (-> heap top) (-> heap current)))) + (return 0) + ) + ;; load succeeded. check status. + + (label retry) + (let ((status (str-load-status (the-as (pointer int32) (& load-status))))) + (when (= status 'error) + (format 0 "Error loading subtitle3~%") + (return 0) + (goto loaded) + ) + (cond + ((>= load-status (+ heap-free -300)) + (format 0 "Game subtitle3 heap overrun!~%") + (return 0) + ) + ((= status 'busy) + ;; still loading. + (goto retry) + ) + ) + ) + (label loaded) + + ;; link the text file! + (let ((new-mem (logand -64 (&+ (-> heap current) 63)))) + (flush-cache 0) + (set! (-> curr-text value) (link new-mem (-> (string-format "~D~S.TXT" lang txt-name) data) load-status heap 0)) + ) + ;; if linking failed just make the text invalid. + (if (<= (the-as int (-> curr-text value)) 0) + (set! (-> curr-text value) (the-as object #f)) + ) + )) + 0) + +(defun load-level-subtitle3-files ((idx int)) + "Load the subtitle3 files needed for level idx. + This function made more sense back when text files were split up, but in the end they put everything + in a single text group and file." + + ;; just load common. + (if (or *level-text-file-load-flag* (>= idx 0)) + (load-subtitle3-text-info PC_SUBTITLE_FILE_NAME '*subtitle3-text* *subtitle3-text-heap*) + ) + + (none)) + + +(defmacro reload-subtitles () + "rebuild and reload subtitles." + `(begin + (asm-text-file subtitle-v2 :files ("game/assets/jak3/game_subtitle.gp")) + (if *subtitle3-text* + (+! (-> *subtitle3-text* lang) 1)) + (load-level-subtitle3-files 0))) + +(defmacro reload-text () + "rebuild and reload text." + `(begin + (mng) + (if *common-text* + (+! (-> *common-text* language-id) 1)) + (load-level-text-files 0))) + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; subtitle3 queue +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defun subtitle-channel? ((ch gui-channel)) + "can this gui channel be checked for subtitles?" + (and (>= ch (gui-channel jak)) (<= ch (gui-channel task))) + ) + +(defun valid-subtitle-gui? ((gui gui-connection)) + "is this gui connection valid for checking subtitles?" + (and gui (nonzero? (-> gui id)) + (subtitle-channel? (-> gui channel)) + (or (= (-> gui action) (gui-action playing)) + (= (-> gui action) (gui-action play))) + (let ((status (get-status *gui-control* (-> gui id)))) + (or (= status (gui-status ready)) + (= status (gui-status active))))) + ) + +(defun subtitle-bump-up? () + "should subtitles be moved up?" + ;; have a query or message up? + (or (= (gui-status active) (get-status *gui-control* (lookup-gui-connection-id *gui-control* (the string #f) (gui-channel query) (gui-action none)))) + (= (gui-status active) (get-status *gui-control* (lookup-gui-connection-id *gui-control* (the string #f) (gui-channel message) (gui-action none)))) + (= (gui-status active) (get-status *gui-control* (lookup-gui-connection-id *gui-control* (the string #f) (gui-channel notice-low) (gui-action none)))) + (= (gui-status active) (get-status *gui-control* (lookup-gui-connection-id *gui-control* "hud-race-final-stats" (gui-channel hud-middle-right) (gui-action none)))) + ) + ) + + +(defmethod clear-line ((obj subtitle3-queue-element)) + "make this queue element invalid" + + (set! (-> obj gui) #f) + (set! (-> obj id) (new 'static 'sound-id)) + 0) + +(defmethod clear-queue ((obj subtitle3)) + "mark all slots in the gui queue as available" + + (dotimes (i PC_SUBTITLE_QUEUE_SIZE) + (clear-line (-> obj queue i))) + 0) + +(defmethod update-gui-connections ((obj subtitle3)) + "mark all inactive slots in the gui queue as available" + + (dotimes (i PC_SUBTITLE_QUEUE_SIZE) + + (let ((gui (lookup-gui-connection *gui-control* (the process #f) (gui-channel none) (the string #f) (-> obj queue i id)))) + + (if (not (valid-subtitle-gui? gui)) + (clear-line (-> obj queue i))))) + 0) + +(defmethod gui-queued? ((obj subtitle3) (gui gui-connection)) + "return #t is the gui is in the queue" + + (dotimes (i PC_SUBTITLE_QUEUE_SIZE) + (if (= (-> gui id) (-> obj queue i id)) + (return #t))) + #f) + +(defmethod get-empty-queue ((obj subtitle3)) + "return the first available gui queue slot" + + (dotimes (i PC_SUBTITLE_QUEUE_SIZE) + (if (not (-> obj queue i gui)) + (return i))) + (format #t "ran out of subtitle queue slots!") + 0 + ) + +(defmethod add-to-queue ((obj subtitle3) (gui gui-connection)) + "add a gui connection to the first empty queue slot available" + + (let ((slot (get-empty-queue obj))) + (set! (-> obj queue slot id) (-> gui id)) + (set! (-> obj queue slot gui) gui)) + gui) + + +(defmethod set-params! ((obj subtitle3-line-queue-element) (line subtitle3-line) (y float)) + "set the parameters for this line queue element" + + (set! (-> obj line) line) + (set! (-> obj y) y) + 0) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; subtitle3 process and drawing! +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defun set-speaker-color ((speaker pc-subtitle3-speaker)) + "set the color for the speaker font color" + (let ((spk-col (-> *subtitle3-speaker-color-table* speaker))) + (set-font-color (font-color font-color-42) spk-col spk-col spk-col spk-col)) + speaker) + + +(defmethod get-active-subtitles ((obj subtitle3)) + "collect active subtitles and add them to the queue + if a gui connection is already in the queue, + it will stay in the same slot when it was first added" + + ;; todo + (-> *gui-control* engine) + (let ((current (-> *gui-control* engine alive-list-end prev0))) + (-> *gui-control* engine) + (let ((next (-> current prev0))) + (while (!= current (-> *gui-control* engine alive-list)) + (let ((gui-conn (the gui-connection current))) + (when (and (valid-subtitle-gui? gui-conn) + (not (gui-queued? obj gui-conn))) + + (add-to-queue obj gui-conn) + ) + ) + (set! current next) + (-> *gui-control* engine) + (set! next (-> next prev0)) + ) + ) + ) + 0) + + +(defmethod subtitle-format ((obj subtitle3) (line subtitle3-line)) + "format the string for a subtitle line to *temp-string*" + + (when (subtitle3-flags? line merge) + (if (and (-> obj movie-mode?) (< 0 (length (-> obj movie-line)))) + (set! (-> line text) (-> obj movie-line)) + (return (the string #f)))) + + (cond + ((= (pc-subtitle3-speaker none) (-> line speaker)) + ;; there's no speaker so who cares. + (string-format "~S" (-> line text))) + ((or (= #t (-> *pc-settings* subtitle-speaker?)) + (and (= 'auto (-> *pc-settings* subtitle-speaker?)) (subtitle3-flags? line offscreen))) + ;; there is a speaker and we do want it. + ;; we use color 42 which gets set at runtime to any color we want + (string-format "~42L~S:~0L ~S" (get-speaker *subtitle3-text* (-> line speaker)) (-> line text))) + (else + (string-format "~S" (-> line text))) + ) + *temp-string*) + +(defbehavior current-subtitle3-pos subtitle3 ((id sound-id)) + "get the str position for this sound id in a 30/sec measurement" + (if (and (-> self movie-mode?) (= id (-> self movie-gui id))) + (return (-> self movie-pos))) + (let ((pos (the float (current-str-pos id)))) + (if (< pos 0.0) -1.0 (/ pos (/ 1024.0 30))))) + + +(defbehavior setup-subtitle3-font subtitle3 ((font font-context)) + "setup a font and parameters for the subtitle3 subtitles." + + ;; set font settings. + (if (!= (language-enum japanese) (-> *setting-control* user-current subtitle-language)) + (set-scale! font (* 0.5 (-> *SUBTITLE3-bank* scale))) + (set-scale! font (* 0.5 (-> *SUBTITLE3-bank* scale) 1.2))) + (set-width! font (the int (* (-> *SUBTITLE3-bank* width) 0.91 512))) + (set-origin! font (the int (/ (- 512.0 (-> font width)) 2)) + (the int (* (if (-> self have-message?) 0.524 0.698) 416))) + (set-height! font (the int (* (-> *SUBTITLE3-bank* lines) 44))) + + ;; if we have the minimap, set the right border to 74.4% of screen width. shrink if larger than that. + ;; TODO scale this with aspect. + (when (and (-> self have-minimap?) + (< (get-screen-x 0.744) (+ (-> font width) (-> font origin x)))) + (let ((new-width (- (get-screen-x 0.744) (-> font origin x)))) + (set-scale! font (* (-> font scale) (/ (the float new-width) (-> font width)))) + (set-width! font new-width))) + ) + + +(defmethod draw-subtitles ((self subtitle3)) + "do the subtitle drawing" + + ;; check the gui queue for lines to add to the line queue + (let ((line-queue-old (if (zero? (-> self line-queue-idx)) (-> self lines 0) (-> self lines 1))) + (line-queue (if (zero? (-> self line-queue-idx)) (-> self lines 1) (-> self lines 0))) + + (find-line (lambda ((queue subtitle3-line-queue) (line subtitle3-line)) + (dotimes (i PC_SUBTITLE_MAX_LINES) + (if (= line (-> queue elts i line)) + (return i))) + -1))) + (logxor! (-> self line-queue-idx) 1) + ;; clear the queue we're writing to first + (dotimes (i PC_SUBTITLE_MAX_LINES) + (set-params! (-> line-queue elts i) (the subtitle3-line #f) PC_SUBTITLE_Y_RECALC) + ) + + ;; we won't be able to render any subtitles with no text loaded. + (when (not *subtitle3-text*) + (false! (-> self have-subtitles?)) + (return 0)) + + ;; font has already been set up in movie mode + (unless (-> self movie-mode?) + ;; set up our font to the initial parameters + (let ((map-gui (lookup-gui-connection *gui-control* (the process #f) (gui-channel hud-lower-right) "hud-map" (new 'static 'sound-id)))) + (set! (-> self have-message?) (or (subtitle-bump-up?) (and (-> self have-message?) (-> self have-subtitles?)))) + (set! (-> self have-minimap?) (and (logtest? (minimap-flag minimap) (-> *setting-control* user-current minimap)) + (!= map-gui #f) + (!= (gui-status pending) (get-status *gui-control* (-> map-gui id))) + (!= (gui-action hidden) (-> map-gui action)))) + ) + (setup-subtitle3-font (-> self font))) + + ;; do two passes - on the first one we add lines that were already being used, + ;; on the second pass we add new lines + (dotimes (q 2) + (dotimes (i PC_SUBTITLE_QUEUE_SIZE) + (when (-> self queue i gui) + (let ((pos (current-subtitle3-pos (-> self queue i id)))) + (when (and (zero? q) *debug-segment*) + (format *stdcon0* "subtitle pos: ~3L~D~0L (~S)~%" (the int pos) (-> self queue i gui name))) + + (let ((scene (get-scene-by-name *subtitle3-text* (-> self queue i gui name)))) + (when scene + (dotimes (ii PC_SUBTITLE_QUEUE_MAX_LINES) + (awhen (get-line-at-pos scene pos ii) + (case q + ((0) + (let ((index-in-old (find-line line-queue-old it))) + (when (!= -1 index-in-old) + ;; this line exists in the previous frame, put it in the new queue at the same spot + (set-params! (-> line-queue elts index-in-old) it (-> line-queue-old elts index-in-old y))))) + ((1) + (when (= -1 (find-line line-queue it)) + ;; line not in the queue. find empty spot. + (let ((index-empty (find-line line-queue (the subtitle3-line #f)))) + (if (!= -1 index-empty) + (set-params! (-> line-queue elts index-empty) it PC_SUBTITLE_Y_RECALC))) + )) + ) + ) + )) + ) + ) + ) + )) + + (let ((cur-y (-> self font origin y)) ;; the current y for the text + (start-y (-> self font origin y)) ;; the starting y for the text + (last-height 0.0) ;; the height of the previous subtitle + (this-height 0.0) ;; the height of the current subtitle + (lines-done 0) + (subtitles-drawn? #f) + ) + + (dotimes (i PC_SUBTITLE_QUEUE_MAX_LINES) + (when (and (-> line-queue elts i line) (subtitle-format self (-> line-queue elts i line))) + + (set! this-height (print-game-text *temp-string* (-> self font) #t 44 (bucket-id debug-no-zbuf2))) + + ;; push subtitle up since we are not the first one + (when (nonzero? lines-done) + (-! cur-y (/ last-height 2)) + (-! cur-y (/ this-height 2)) + ) + + ;; set the current y, it shall not be lower than the previous line! + (if (= (-> line-queue elts i y) PC_SUBTITLE_Y_RECALC) + (set! (-> line-queue elts i y) (- start-y cur-y)) + (set! cur-y (the float (min (the int cur-y) (the int (- start-y (-> line-queue elts i y))))))) + (set! (-> self font origin y) cur-y) + + ;; check if we should actually draw subtitles and do it + (when (and (if (-> self movie-mode?) (-> *setting-control* user-current subtitle) + (-> *pc-settings* hinttitles?)) + (or *gui-kick-str* (= *master-mode* 'game))) + (set-action! *gui-control* (gui-action play) (-> self gui-id) + (gui-channel none) (gui-action none) (the-as string #f) (the-as (function gui-connection symbol) #f) (the-as process #f)) + + (when (= (gui-status active) (get-status *gui-control* (-> self gui-id))) + (true! subtitles-drawn?) + (protect (*display-text-box*) + (set! *display-text-box* (or *display-text-box* PC_SUBTITLE_DEBUG)) + (set-speaker-color (-> line-queue elts i line speaker)) + (print-game-text *temp-string* (-> self font) #f 44 (bucket-id debug-no-zbuf2)))) + ) + + ;; save this for later usage + (set! last-height this-height) + (1+! lines-done) + ) + ) + + (set! (-> self have-subtitles?) subtitles-drawn?) + (when (not (-> self have-subtitles?)) + (set-action! *gui-control* (gui-action hidden) (-> self gui-id) + (gui-channel none) (gui-action none) (the-as string #f) (the-as (function gui-connection symbol) #f) (the-as process #f))) + + (set! (-> self font origin y) start-y))) + + 0) + +(when *debug-segment* +(defmethod debug-print-queue ((self subtitle3)) + "print the queue to *stdcon0*" + + (format *stdcon0* "q: ~%") + (dotimes (i PC_SUBTITLE_QUEUE_SIZE) + (if (-> self queue i gui) + (format *stdcon0* "~D: ~S ~3L~D~0L ~D ~`gui-connection`P~%" i + (-> self queue i gui name) + (the int (current-subtitle3-pos (-> self queue i id))) + (-> self queue i id) + (-> self queue i gui)))) + + (format *stdcon0* "l: ~%") + (let ((line-queue (if (zero? (-> self line-queue-idx)) (-> self lines 0) (-> self lines 1)))) + (dotimes (i PC_SUBTITLE_MAX_LINES) + (format *stdcon0* "~D: ~D ~S~%" i (the int (-> line-queue elts i y)) (aif (-> line-queue elts i line) (-> it text))))) + + 0) + +(defmethod debug-print-speakers ((self subtitle3)) + "print all speakers onscreen" + + (if (not *subtitle3-text*) + (return 0)) + + (let ((font (new 'stack 'font-context *font-default-matrix* 0 0 0.0 (font-color default) (font-flags shadow kerning large))) + (col-wid (/ 512.0 3))) + (set-width! font (the int col-wid)) + (set-height! font 44) + (set-scale! font 0.5) + + (dotimes (i (-> *subtitle3-text* speaker-length)) + (set-speaker-color (the pc-subtitle3-speaker i)) + (+! (-> font origin y) (print-game-text (string-format "~33L~S" (get-speaker *subtitle3-text* (the pc-subtitle3-speaker i))) + font #f 44 (bucket-id debug-no-zbuf2))) + (when (< 416.0 (-> font origin y)) + (set! (-> font origin y) 0.0) + (+! (-> font origin x) col-wid)) + )) + + 0) +) + +(defmethod start-gui ((self subtitle3)) + "start gui queueing" + (set! (-> self gui-id) (add-process *gui-control* self (gui-channel subtitle-pc) (gui-action hidden) "subtitle3" (meters 20) 0)) + ) + +(defmethod stop-gui ((self subtitle3)) + "stop gui queueing" + (set-action! *gui-control* (gui-action stop) (-> self gui-id) + (gui-channel none) + (gui-action none) + (the-as string #f) + (the-as (function gui-connection symbol) #f) + (the-as process #f)) + (set! (-> self gui-id) (new 'static 'sound-id)) + ) + +(defstate subtitle3-process (subtitle3) + + :event (behavior ((from process) (argc int) (msg symbol) (block event-message-block)) + (case msg + (('movie 'movie-no-subtitle) + ;; we are receiving parameters for a movie subtitle! + (when (not *subtitle3-text*) + (format 0 "movie subtitle: no text loaded~%") + (return #f)) + + (set! (-> self movie-gui) (lookup-gui-connection *gui-control* (the process #f) (gui-channel art-load) (the-as string (-> block param 0)) (new 'static 'sound-id))) + (when (not (-> self movie-gui)) + (format 0 "movie subtitle: no gui found~%") + (return #f)) + + (set! (-> self movie-mode?) #t) + (set! (-> self movie-pos) (the-as float (-> block param 2))) + + (when (!= msg 'movie-no-subtitle) + (copyn-charp<-string (-> self movie-line data) (the-as string (-> block param 1)) + (-> self movie-line allocated-length)) + (set! (-> self have-message?) #f) + (set! (-> self have-minimap?) #f) + (set! (-> self have-subtitles?) #f) + (setup-subtitle3-font (-> self font)) + ;; we're gonna use the same font as the movie subtitles + (set-origin! (-> self font) 20 290) + (set-width! (-> self font) 465) + (set-height! (-> self font) 70) + (set-scale! (-> self font) 0.5) + + (when (= (-> *setting-control* user-current subtitle-language) (language-enum korean)) + (set-scale! (-> self font) 0.6)) + ) + #t) + ) + ) + + :code (behavior () + (loop + (suspend)) + ) + + :trans (behavior () + (when *debug-segment* + (when (and (cpad-hold? 0 l3) (cpad-pressed? 0 r3)) + (cpad-clear! 0 r3) + (set! (-> self cheat-backup) *cheat-mode*) + (set! *cheat-mode* 'camera) + (set-master-mode 'pause) + (go subtitle3-debug) + ) + ) + + (load-level-subtitle3-files 0) + + ;; get subtitles + (cond + ((not (-> self movie-mode?)) + ;; get rid of invalid gui entries + (update-gui-connections self) + ;; queue up valid ones + (get-active-subtitles self) + ) + ((-> self movie-gui) + ;; wipe the queue + (clear-queue self) + ;; queue up the movie gui - this is the only one we want in movie mode + (add-to-queue self (-> self movie-gui)) + ) + (else + ;; something weird happened + (if *debug-segment* + (format #t "bad movie gui~%")) + (set! (-> self movie-mode?) #f) + (clear-queue self)) + ) + ) + + :post (behavior () + + (draw-subtitles self) + + (when *debug-segment* + (if *display-subtitle-speakers* + (debug-print-speakers self)) + (if PC_SUBTITLE_DEBUG + (debug-print-queue self)) + ) + + (when (-> self movie-mode?) + (set! (-> self movie-gui) #f) + (set! (-> self movie-mode?) #f) + (clear (-> self movie-line)) + ) + 0) + + ) + + +(defstate subtitle3-debug (subtitle3) + + :enter (behavior () + (process-mask-clear! (-> self mask) pause) + ) + :exit (behavior () + (unless (= (-> self next-state name) 'subtitle3-debug-checking-lines) + (process-mask-set! (-> self mask) pause)) + ) + + :trans (behavior () + + (with-dma-buffer-add-bucket ((buf (-> (current-frame) debug-buf)) + (bucket-id debug-no-zbuf2)) + + (draw-string-xy "~3LSUBTITLE DEBUG!~0L" buf 14 (+ PC_SUB_DBG_Y (* 0 15)) (font-color default) (font-flags shadow kerning)) + (draw-string-xy "L3+R3: exit" buf 14 (+ PC_SUB_DBG_Y (* 1 15)) (font-color default) (font-flags shadow kerning)) + (if (!= 'pause *master-mode*) + (draw-string-xy "Pause the game to continue" buf 14 (+ PC_SUB_DBG_Y (* 2 15)) (font-color default) (font-flags shadow kerning))) + + (when (= 'pause *master-mode*) + ;(draw-string-xy "L3+X: debug lines" buf 14 (+ PC_SUB_DBG_Y (* 2 15)) (font-color default) (font-flags shadow kerning)) + ;(draw-string-xy "L3+Triangle: debug box" buf 14 (+ PC_SUB_DBG_Y (* 3 15)) (font-color default) (font-flags shadow kerning)) + + (cond + ((or (not *subtitle3-text*) (zero? (-> *subtitle3-text* length))) + (draw-string-xy "NO SUBTITLES LOADED!!!" buf 14 (+ PC_SUB_DBG_Y (* 10 15)) (font-color red) (font-flags shadow kerning)) + (load-level-subtitle3-files 0) + (set! (-> self current-debug-scene) 0) + (set! (-> self current-debug-line) 0) + ) + (else + + (cond + ((cpad-pressed? 0 square) + (true! (-> self checking-lines?)) + ) + ((cpad-pressed? 0 left) + (if (> (-> self current-debug-line) 0) + (1-! (-> self current-debug-line))) + ) + ((cpad-pressed? 0 right) + (if (< (-> self current-debug-line) (1- (-> *subtitle3-text* data (-> self current-debug-scene) length))) + (1+! (-> self current-debug-line))) + ) + ((or (cpad-pressed? 0 up) (and (cpad-hold? 0 l2) (cpad-hold? 0 up))) + (when (> (-> self current-debug-scene) 0) + (1-! (-> self current-debug-scene)) + (set! (-> self current-debug-line) 0)) + ) + ((or (cpad-pressed? 0 down) (and (cpad-hold? 0 l2) (cpad-hold? 0 down))) + (when (< (-> self current-debug-scene) (1- (-> *subtitle3-text* length))) + (1+! (-> self current-debug-scene)) + (set! (-> self current-debug-line) 0)) + ) + ) + + (let ((cur-scene (-> *subtitle3-text* data (-> self current-debug-scene)))) + (if (nonzero? (-> cur-scene length)) + (set! (-> self current-debug-subtitle) (-> *subtitle3-text* data (-> self current-debug-scene) lines (-> self current-debug-line))) + (set! (-> self current-debug-subtitle) #f)) + + (draw-string-xy "Up/down: Pick scene" buf 14 (+ PC_SUB_DBG_Y (* 4 15)) (font-color default) (font-flags shadow kerning)) + (draw-string-xy "L2+Up/down: Pick scene (fast)" buf 14 (+ PC_SUB_DBG_Y (* 5 15)) (font-color default) (font-flags shadow kerning)) + (draw-string-xy "Left/right: Pick line" buf 14 (+ PC_SUB_DBG_Y (* 6 15)) (font-color default) (font-flags shadow kerning)) + (draw-string-xy "Square: Check all line heights" buf 14 (+ PC_SUB_DBG_Y (* 7 15)) (font-color default) (font-flags shadow kerning)) + (draw-string-xy (string-format "Scene: ~D/~D (~S)" (1+ (-> self current-debug-scene)) (-> *subtitle3-text* length) (-> cur-scene name)) + buf 14 (+ PC_SUB_DBG_Y (* 8 15)) (font-color default) (font-flags shadow kerning)) + (draw-string-xy (string-format "Line: ~D/~D" (1+ (-> self current-debug-line)) (-> cur-scene length)) + buf 14 (+ PC_SUB_DBG_Y (* 9 15)) (font-color default) (font-flags shadow kerning)) + ) + + ) + ) + )) + + (when (-> self checking-lines?) + (false! (-> self checking-lines?)) + (go subtitle3-debug-checking-lines) + ) + (when (and (cpad-hold? 0 l3) (cpad-pressed? 0 r3)) + (cpad-clear! 0 r3) + (set! *cheat-mode* (-> self cheat-backup)) + (set-master-mode 'game) + (go subtitle3-process) + ) + ) + + :code (-> subtitle3-process code) + :post (behavior () + (set! (-> self movie-mode?) #f) + (set! (-> self have-message?) #f) + (set! (-> self have-minimap?) #f) + (set! (-> self have-subtitles?) #f) + (setup-subtitle3-font (-> self font)) + (when (-> self current-debug-subtitle) + (set-speaker-color (-> self current-debug-subtitle speaker)) + (print-game-text (subtitle-format self (-> self current-debug-subtitle)) (-> self font) #f 44 (bucket-id debug-no-zbuf2)) + ) + 0) + + ) + +(defstate subtitle3-debug-checking-lines (subtitle3) + + :trans (behavior () + (set! (-> self movie-mode?) #f) + (set! (-> self have-message?) #f) + (set! (-> self have-minimap?) #f) + (set! (-> self have-subtitles?) #f) + (setup-subtitle3-font (-> self font)) + ) + + :code (behavior () + (protect ((-> *pc-settings* subtitle-speaker?)) + (set! (-> *pc-settings* subtitle-speaker?) #t) + (let ((lines-so-far 0) + (lines-this-frame 0) + (bad-lines 0)) + (dotimes (i (length *subtitle3-text*)) + (dotimes (ii (length (-> *subtitle3-text* data i))) + (when (= lines-this-frame PC_SUB_DBG_CHECK_GROUP_SIZE) + (set! lines-this-frame 0) + (suspend)) + + (1+! lines-this-frame) + (set! (-> self current-debug-subtitle) (-> *subtitle3-text* data i lines ii)) + (set-speaker-color (-> self current-debug-subtitle speaker)) + (when (< (* (-> *SUBTITLE3-bank* lines) 22) (print-game-text (subtitle-format self (-> self current-debug-subtitle)) (-> self font) #f 44 (bucket-id debug-no-zbuf2))) + (format 0 "ERROR: LINE ~D IN SCENE ~D IS TOO LARGE!~%" (1+ ii) (1+ i)) + (format #t "ERROR: LINE ~D IN SCENE ~D IS TOO LARGE!~%" (1+ ii) (1+ i)) + (1+! bad-lines) + ) + ) + ) + (suspend) + (if (> bad-lines 0) + (format 0 "error: ~D bad lines detected.~%" bad-lines) + (format 0 "no bad lines detected!~%" bad-lines)) + )) + (go subtitle3-debug) + ) + :post (behavior () + (with-dma-buffer-add-bucket ((buf (-> (current-frame) debug-buf)) + (bucket-id debug)) + (draw-string-xy "Checking for bad lines... See console for info" buf 14 PC_SUB_DBG_Y (font-color red) (font-flags shadow kerning)) + ) + (draw-debug-text-box (-> self font)) + 0) + + ) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; helper functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +(defmethod deactivate ((self subtitle3)) + + (stop-gui self) + ;; not sure this works... + (if (= (ppointer->process *subtitle3*) self) + (set! *subtitle3* #f)) + + ((method-of-type process deactivate) self) + (none) + ) + +(defbehavior subtitle3-init-by-other subtitle3 () + "external initializer for subtitle3 process" + + (process-mask-clear! (-> self mask) menu) + + (set! (-> self font) (new 'process 'font-context *font-default-matrix* + 0 0 0.0 (font-color default) (font-flags shadow kerning middle-vert middle large))) + (clear-queue self) + (dotimes (i PC_SUBTITLE_MAX_LINES) + (set! (-> self lines 0 elts i line) #f) + (set! (-> self lines 0 elts i y) PC_SUBTITLE_Y_RECALC) + (set! (-> self lines 1 elts i line) #f) + (set! (-> self lines 1 elts i y) PC_SUBTITLE_Y_RECALC) + ) + + (set! (-> self have-message?) #f) + (set! (-> self have-minimap?) #f) + (set! (-> self have-subtitles?) #f) + + (set! (-> self movie-mode?) #f) + (set! (-> self movie-line) (new 'process 'string (+ 7 (* 15 16)) (the string #f))) + + (set! (-> self current-debug-scene) 0) + (set! (-> self current-debug-line) 0) + (set! (-> self current-debug-subtitle) #f) + (set! (-> self checking-lines?) #f) + + (start-gui self) + + (go subtitle3-process) + ) + + +(defun subtitle3-stop () + "kill the subtitle3 process" + + (if *subtitle3* + (deactivate (ppointer->process *subtitle3*))) + *subtitle3*) + +(defun subtitle3-start () + "start the subtitle3 process" + + ;; fill the subtitle speaker table + (set-subtitle-speaker-colors) + + (if *subtitle3* + (subtitle3-stop)) + + (set! *subtitle3* (process-spawn subtitle3 :from *pc-dead-pool* :to *pc-pool*)) + ) + +;; start the subtitle3 process when this file loads. +(subtitle3-start) + + + diff --git a/goal_src/jak3/pc/util/popup-menu-h.gc b/goal_src/jak3/pc/util/popup-menu-h.gc new file mode 100644 index 0000000000..187272a672 --- /dev/null +++ b/goal_src/jak3/pc/util/popup-menu-h.gc @@ -0,0 +1,59 @@ +;;-*-Lisp-*- +(in-package goal) + +;; A debug-menu style popup menu, a lightweight way to make a context menu that doesn't involve the progress code +;; and isn't debug-only + +(define *popup-menu-open* #f) + +(deftype popup-menu-entry (basic) + ((label string) + (entry-disabled? (function symbol)) + (on-confirm (function none))) + (:methods + (draw-entry (_type_ font-context dma-buffer symbol) object))) + +;; (deftype popup-menu-label (popup-menu-entry) ()) + +(deftype popup-menu-button (popup-menu-entry) ()) + +(deftype popup-menu-flag (popup-menu-entry) + ((is-toggled? (function symbol)))) + +(deftype popup-menu-submenu (popup-menu-entry) + ((entries (array popup-menu-entry)))) + +(deftype popup-menu-dynamic-submenu (popup-menu-entry) + ((get-length (function int)) + (get-entry-label (function int string none)) + (on-entry-confirm (function int none)) + (entry-selected? (function int symbol)) + (on-reset (function none)))) + +(deftype popup-menu-state (structure) + ((title string) + (entries (array popup-menu-entry)) + (entry-index int32) + (dynamic-menu? symbol) + (get-dynamic-menu-length (function int)) + (get-dynamic-menu-entry-label (function int string none)) + (on-dynamic-menu-entry-confirm (function int none)) + (dynamic-menu-entry-selected? (function int symbol)) + (on-dynamic-menu-reset (function none)))) + +(deftype popup-menu (process) + ((title string) + (entries (array popup-menu-entry)) + (menu-states popup-menu-state 10 :inline) + (curr-state-index int32) + (draw? symbol)) + (:methods + (update-menu! (_type_) object) + (draw-menu (_type_) object) + (move-up! (_type_ int) object) + (move-down! (_type_ int) object) + (confirm! (_type_) object) + (reset! (_type_) object) + (back! (_type_) symbol)) + (:state-methods + idle)) diff --git a/goal_src/jak3/pc/util/popup-menu.gc b/goal_src/jak3/pc/util/popup-menu.gc new file mode 100644 index 0000000000..19b23223fa --- /dev/null +++ b/goal_src/jak3/pc/util/popup-menu.gc @@ -0,0 +1,289 @@ +;;-*-Lisp-*- +(in-package goal) + +(defun get-widest-entry ((entries (array popup-menu-entry)) (title string) (font-ctx font-context) (start-index int) (end-index int)) + (let ((max-len 0.0)) + (dotimes (i (- end-index start-index)) + (let ((label-len (-> (get-string-length (-> entries (+ start-index i) label) font-ctx) length))) + (when (> label-len max-len) + (set! max-len label-len)))) + (let ((title-len (-> (get-string-length title font-ctx) length))) + (when (> title-len max-len) + (set! max-len title-len))) + (the int max-len))) + +(defun get-widest-dynamic-entry ((get-entry-label (function int string none)) (title string) (font-ctx font-context) (start-index int) (end-index int)) + (let ((max-len 0.0)) + (dotimes (i (- end-index start-index)) + (get-entry-label (+ start-index i) *pc-encoded-temp-string*) + (let ((label-len (-> (get-string-length *pc-encoded-temp-string* font-ctx) length))) + (when (> label-len max-len) + (set! max-len label-len)))) + (let ((title-len (-> (get-string-length title font-ctx) length))) + (when (> title-len max-len) + (set! max-len title-len))) + (the int max-len))) + +(defmethod draw-entry ((this popup-menu-entry) (font-ctx font-context) (dma-buf dma-buffer) (hovering? symbol)) + (let ((old-x (-> font-ctx origin x)) + (old-y (-> font-ctx origin y)) + (old-color (-> font-ctx color))) + (pc-encode-utf8-string (-> this label) *pc-encoded-temp-string*) + (when hovering? + (set! (-> font-ctx color) (font-color cyan))) + (when (and (nonzero? (-> this entry-disabled?)) ((-> this entry-disabled?))) + (set! (-> font-ctx color) (font-color menu-parent))) + (draw-string-adv *pc-encoded-temp-string* dma-buf font-ctx) + (set! (-> font-ctx origin x) old-x) + (set! (-> font-ctx origin y) old-y) + (set! (-> font-ctx color) old-color))) + +(defmethod draw-entry ((this popup-menu-flag) (font-ctx font-context) (dma-buf dma-buffer) (hovering? symbol)) + (let ((old-x (-> font-ctx origin x)) + (old-y (-> font-ctx origin y)) + (old-color (-> font-ctx color))) + (when ((-> this is-toggled?)) + (set! (-> font-ctx color) (font-color green)) + (set! (-> font-ctx origin x) (- old-x 6.0)) + (draw-string-adv "\c86" dma-buf font-ctx) + (set! (-> font-ctx origin x) old-x) + (set! (-> font-ctx origin y) old-y) + (set! (-> font-ctx color) old-color)) + (pc-encode-utf8-string (-> this label) *pc-encoded-temp-string*) + (when hovering? + (set! (-> font-ctx color) (font-color cyan))) + (draw-string-adv *pc-encoded-temp-string* dma-buf font-ctx) + (set! (-> font-ctx origin x) old-x) + (set! (-> font-ctx origin y) old-y) + (set! (-> font-ctx color) old-color))) + +(defun draw-dynamic-entry ((entry-id int) (get-label (function int string none)) (entry-selected? (function int symbol)) (font-ctx font-context) (dma-buf dma-buffer) (hovering? symbol)) + (let ((old-x (-> font-ctx origin x)) + (old-y (-> font-ctx origin y)) + (old-color (-> font-ctx color))) + (when (entry-selected? entry-id) + (set! (-> font-ctx color) (font-color green)) + (set! (-> font-ctx origin x) (- old-x 6.0)) + (draw-string-adv "\c86" dma-buf font-ctx) + (set! (-> font-ctx origin x) old-x) + (set! (-> font-ctx origin y) old-y) + (set! (-> font-ctx color) old-color)) + (clear *pc-encoded-temp-string*) + (get-label entry-id *pc-encoded-temp-string*) + (pc-encode-utf8-string *pc-encoded-temp-string* *pc-encoded-temp-string*) + (when hovering? + (set! (-> font-ctx color) (font-color cyan))) + (draw-string-adv *pc-encoded-temp-string* dma-buf font-ctx) + (set! (-> font-ctx origin x) old-x) + (set! (-> font-ctx origin y) old-y) + (set! (-> font-ctx color) old-color))) + +(defmethod draw-menu ((this popup-menu)) + (let ((font-ctx (new 'debug 'font-context *font-default-matrix* 0 0 0.0 (font-color default) (font-flags shadow kerning large))) + (page-title (-> this menu-states (-> this curr-state-index) title)) + (dynamic-menu? (-> this menu-states (-> this curr-state-index) dynamic-menu?)) + (can-reset? (and (nonzero? (-> this menu-states (-> this curr-state-index) on-dynamic-menu-reset)) + (-> this menu-states (-> this curr-state-index) on-dynamic-menu-reset)))) + (set! (-> font-ctx scale) 0.25) + (set! (-> font-ctx origin x) 15.0) + (set! (-> font-ctx origin y) 75.0) + (let* ((entry-count (if dynamic-menu? + ((-> this menu-states (-> this curr-state-index) get-dynamic-menu-length)) + (-> this menu-states (-> this curr-state-index) entries length))) + (current-index (-> this menu-states (-> this curr-state-index) entry-index)) + (start-index (* (/ current-index 15) 15)) + (end-index (min (+ start-index 15) entry-count)) + (entry-count-to-render (- end-index start-index)) + (menu-rows (if (< end-index entry-count) (inc entry-count-to-render) entry-count-to-render)) + (widest-entry (if dynamic-menu? + (get-widest-dynamic-entry (-> this menu-states (-> this curr-state-index) get-dynamic-menu-entry-label) page-title font-ctx start-index end-index) + (get-widest-entry (-> this menu-states (-> this curr-state-index) entries) page-title font-ctx start-index end-index)))) + (with-dma-buffer-add-bucket ((buf (-> (current-frame) global-buf)) (bucket-id debug-no-zbuf2)) + ;; background border + (draw-sprite2d-xy buf + 6 + 64 + (+ 17 widest-entry) ;; width + (+ 17 (* 15 (inc menu-rows))) ;; height + (static-rgba 255 255 255 75) + #x3fffff) + ;; background + (draw-sprite2d-xy buf + 7 + 65 + (+ 15 widest-entry) ;; width + (+ 15 (* 15 (inc menu-rows))) ;; height + (static-rgba 0 0 0 255) + #x3fffff) + ;; title + ;; TODO - function + (pc-encode-utf8-string page-title *pc-encoded-temp-string*) + (set! (-> font-ctx color) (font-color menu-parent)) + (let ((old-x (-> font-ctx origin x)) + (old-y (-> font-ctx origin y))) + (draw-string-adv *pc-encoded-temp-string* buf font-ctx) + (set! (-> font-ctx origin x) old-x) + (set! (-> font-ctx origin y) old-y)) + (set! (-> font-ctx color) (font-color default)) + (set! (-> font-ctx origin y) (+ 15.0 (-> font-ctx origin y))) + ;; menu contents + (dotimes (i entry-count-to-render) + (if dynamic-menu? + (draw-dynamic-entry (+ i start-index) + (-> this menu-states (-> this curr-state-index) get-dynamic-menu-entry-label) + (-> this menu-states (-> this curr-state-index) dynamic-menu-entry-selected?) + font-ctx + buf + (= (+ i start-index) current-index)) + (draw-entry (-> (-> this menu-states (-> this curr-state-index) entries) i) font-ctx buf (= (+ i start-index) current-index))) + (set! (-> font-ctx origin y) (+ 15.0 (-> font-ctx origin y)))) + (when (< end-index entry-count) + (clear *pc-encoded-temp-string*) + (format *pc-encoded-temp-string* "~D more..." (- entry-count end-index)) + (pc-encode-utf8-string *pc-encoded-temp-string* *pc-encoded-temp-string*) + (set! (-> font-ctx color) (font-color menu-parent)) + (let ((old-x (-> font-ctx origin x)) + (old-y (-> font-ctx origin y))) + (draw-string-adv *pc-encoded-temp-string* buf font-ctx) + (set! (-> font-ctx origin x) old-x) + (set! (-> font-ctx origin y) old-y)) + (set! (-> font-ctx color) (font-color default)) + (set! (-> font-ctx origin y) (+ 15.0 (-> font-ctx origin y)))) + ;; button prompts + (cond + ((= (-> this curr-state-index) 0) + (pc-encode-utf8-string " Exit" *pc-encoded-temp-string*) + ) + ((and dynamic-menu? can-reset?) + (pc-encode-utf8-string " Reset / Back" *pc-encoded-temp-string*)) + (else + (pc-encode-utf8-string " Back" *pc-encoded-temp-string*)) + ) + (set! (-> font-ctx origin x) (- 25.0 (-> font-ctx origin x))) + (set! (-> font-ctx origin y) (+ 10.0 (-> font-ctx origin y))) + (let ((old-x (-> font-ctx origin x)) + (old-y (-> font-ctx origin y))) + (draw-string-adv *pc-encoded-temp-string* buf font-ctx) + (set! (-> font-ctx origin x) old-x) + (set! (-> font-ctx origin y) old-y)))))) + +(defmethod move-up! ((this popup-menu) (amount int)) + (let* ((curr-state (-> this menu-states (-> this curr-state-index))) + (new-index (max 0 (-! (-> curr-state entry-index) amount)))) + ;; dynamic menus don't have options that are disabled (just dont include them) + (when (not (-> curr-state dynamic-menu?)) + (let ((entry (-> curr-state entries new-index))) + (when (and (nonzero? (-> entry entry-disabled?)) ((-> entry entry-disabled?))) + (set! new-index (max 0 (dec new-index)))))) + (set! (-> curr-state entry-index) new-index))) + +(defmethod move-down! ((this popup-menu) (amount int)) + (let* ((curr-state (-> this menu-states (-> this curr-state-index))) + (max-entries (if (-> curr-state dynamic-menu?) + ((-> curr-state get-dynamic-menu-length)) + (-> curr-state entries length))) + (new-index (min (dec max-entries) (+! (-> curr-state entry-index) amount)))) + ;; dynamic menus don't have options that are disabled (just dont include them) + (when (not (-> curr-state dynamic-menu?)) + (let ((entry (-> curr-state entries new-index))) + (when (and (nonzero? (-> entry entry-disabled?)) ((-> entry entry-disabled?))) + (set! new-index (min (dec max-entries) (inc new-index)))))) + (set! (-> curr-state entry-index) new-index))) + +(defmethod confirm! ((this popup-menu)) + (let* ((menu-state (-> this menu-states (-> this curr-state-index))) + (dynamic-menu? (-> menu-state dynamic-menu?))) + (if dynamic-menu? + ((-> menu-state on-dynamic-menu-entry-confirm) (-> menu-state entry-index)) + (let ((entry (-> menu-state entries (-> menu-state entry-index)))) + (cond + ((type? entry popup-menu-dynamic-submenu) + ;; TODO - dont allow more than 10 nested menus + (inc! (-> this curr-state-index)) + (set! (-> this menu-states (-> this curr-state-index) entry-index) 0) + (set! (-> this menu-states (-> this curr-state-index) title) (-> entry label)) + (true! (-> this menu-states (-> this curr-state-index) dynamic-menu?)) + (set! (-> this menu-states (-> this curr-state-index) get-dynamic-menu-length) (-> (the-as popup-menu-dynamic-submenu entry) get-length)) + (set! (-> this menu-states (-> this curr-state-index) get-dynamic-menu-entry-label) (-> (the-as popup-menu-dynamic-submenu entry) get-entry-label)) + (set! (-> this menu-states (-> this curr-state-index) on-dynamic-menu-entry-confirm) (-> (the-as popup-menu-dynamic-submenu entry) on-entry-confirm)) + (set! (-> this menu-states (-> this curr-state-index) dynamic-menu-entry-selected?) (-> (the-as popup-menu-dynamic-submenu entry) entry-selected?)) + (set! (-> this menu-states (-> this curr-state-index) on-dynamic-menu-reset) (-> (the-as popup-menu-dynamic-submenu entry) on-reset))) + ((type? entry popup-menu-submenu) + ;; TODO - dont allow more than 10 nested menus + (inc! (-> this curr-state-index)) + (set! (-> this menu-states (-> this curr-state-index) entry-index) 0) + (false! (-> this menu-states (-> this curr-state-index) dynamic-menu?)) + (set! (-> this menu-states (-> this curr-state-index) title) (-> entry label)) + (set! (-> this menu-states (-> this curr-state-index) entries) (-> (the-as popup-menu-submenu entry) entries))) + (else + ((-> entry on-confirm))))))) + (sound-play "menu-pick")) + +(defmethod reset! ((this popup-menu)) + (let* ((menu-state (-> this menu-states (-> this curr-state-index)))) + (when (and (-> menu-state dynamic-menu?) + (nonzero? (-> menu-state on-dynamic-menu-reset)) + (-> menu-state on-dynamic-menu-reset)) ;; dont call if theres no function defined + ((-> menu-state on-dynamic-menu-reset)) + (sound-play "menu-pick")))) + +(defmethod back! ((this popup-menu)) + (sound-play "menu-pick") + (cond + ((<= (-> this curr-state-index) 0) + #t) + (else + (dec! (-> this curr-state-index)) + #f))) + +(defbehavior popup-menu-init-by-other popup-menu ((title string) (entries (array popup-menu-entry))) + (process-mask-clear! (-> self mask) menu pause) + (set! (-> self curr-state-index) 0) + (set! (-> self menu-states 0 title) title) + (set! (-> self menu-states 0 entries) entries) + (set! (-> self menu-states 0 entry-index) 0) + (false! (-> self menu-states 0 dynamic-menu?)) + (false! (-> self draw?)) + (go-virtual idle)) + +(defbehavior popup-menu-event-handler popup-menu ((proc process) (argc int) (message symbol) (block event-message-block)) + (case message + (('open-menu) + (set-master-mode 'menu) + (true! (-> self draw?)) + (true! *popup-menu-open*) + (sound-play "menu-pick")) + (('close-menu) + (set-master-mode 'game) + (false! (-> self draw?)) + (false! *popup-menu-open*)))) + +(defmethod update-menu! ((this popup-menu)) + (when (-> this draw?) + ;; handle input + (cond + ((cpad-pressed? 0 select) + (send-event this 'close-menu)) + ((cpad-pressed? 0 up) + (move-up! this 1)) + ((cpad-pressed? 0 down) + (move-down! this 1)) + ((cpad-pressed? 0 left) + (move-up! this 5)) + ((cpad-pressed? 0 right) + (move-down! this 5)) + ((cpad-pressed? 0 x) + (confirm! this)) + ((cpad-pressed? 0 square) + (reset! this)) + ((cpad-pressed? 0 triangle circle) + (when (back! this) + (send-event this 'close-menu)))) + (draw-menu this))) + +(defstatehandler popup-menu :event popup-menu-event-handler) + +(defstate idle (popup-menu) + :virtual #t + :trans (behavior () (update-menu! self)) + :code sleep-code) diff --git a/goalc/CMakeLists.txt b/goalc/CMakeLists.txt index 3fab9307c5..519ae15666 100644 --- a/goalc/CMakeLists.txt +++ b/goalc/CMakeLists.txt @@ -31,6 +31,7 @@ add_library(compiler build_level/jak3/LevelFile.cpp build_level/common/ResLump.cpp build_level/common/Tfrag.cpp + build_level/common/Tie.cpp build_level/jak1/ambient.cpp compiler/Compiler.cpp compiler/Env.cpp diff --git a/goalc/build_actor/common/MercExtract.cpp b/goalc/build_actor/common/MercExtract.cpp index ad67298a2c..a04132223d 100644 --- a/goalc/build_actor/common/MercExtract.cpp +++ b/goalc/build_actor/common/MercExtract.cpp @@ -1,9 +1,14 @@ #include "MercExtract.h" #include "common/log/log.h" +#include "common/util/gltf_util.h" #include "goalc/build_level/common/gltf_mesh_extract.h" +bool material_has_envmap(const tinygltf::Material& mat) { + return mat.extensions.contains("KHR_materials_specular"); +} + void extract(const std::string& name, MercExtractData& out, const tinygltf::Model& model, @@ -16,6 +21,7 @@ void extract(const std::string& name, std::map draw_by_material; int mesh_count = 0; int prim_count = 0; + bool has_envmaps = false; for (const auto& n : all_nodes) { const auto& node = model.nodes[n.node_idx]; @@ -84,40 +90,108 @@ void extract(const std::string& name, } tfrag3::MercEffect e; + tfrag3::MercEffect envmap_eff; out.new_model.name = name; - out.new_model.max_bones = 120; // idk + out.new_model.max_bones = 100; // idk out.new_model.max_draws = 200; - for (const auto& [mat_idx, d_] : draw_by_material) { - e.all_draws.push_back(d_); - auto& draw = e.all_draws.back(); + + auto process_normal_draw = [&](tfrag3::MercEffect& eff, int mat_idx, const tfrag3::MercDraw& d_) { + const auto& mat = model.materials[mat_idx]; + eff.all_draws.push_back(d_); + auto& draw = eff.all_draws.back(); draw.mode = gltf_util::make_default_draw_mode(); if (mat_idx == -1) { lg::warn("Draw had a material index of -1, using default texture."); draw.tree_tex_id = 0; - continue; + return; } - const auto& mat = model.materials[mat_idx]; int tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index; if (tex_idx == -1) { lg::warn("Material {} has no texture, using default texture.", mat.name); draw.tree_tex_id = 0; - continue; + return; } const auto& tex = model.textures[tex_idx]; ASSERT(tex.sampler >= 0); ASSERT(tex.source >= 0); - draw.mode = gltf_util::draw_mode_from_sampler(model.samplers.at(tex.sampler)); + gltf_util::setup_draw_mode_from_sampler(model.samplers.at(tex.sampler), &draw.mode); + gltf_util::setup_alpha_from_material(mat, &draw.mode); const auto& img = model.images[tex.source]; draw.tree_tex_id = tex_offset + texture_pool_add_texture(&out.tex_pool, img); + }; + + auto process_envmap_draw = [&](tfrag3::MercEffect& eff, int mat_idx, const tfrag3::MercDraw& d_) { + const auto& mat = model.materials[mat_idx]; + eff.all_draws.push_back(d_); + auto& draw = eff.all_draws.back(); + draw.mode = gltf_util::make_default_draw_mode(); + + if (mat_idx == -1) { + lg::warn("Envmap draw had a material index of -1, using default texture."); + draw.tree_tex_id = texture_pool_debug_checker(&out.tex_pool); + return; + } + int base_tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index; + if (base_tex_idx == -1) { + lg::warn("Envmap material {} has no texture, using default texture.", mat.name); + draw.tree_tex_id = texture_pool_debug_checker(&out.tex_pool); + return; + } + + int roughness_tex_idx = mat.pbrMetallicRoughness.metallicRoughnessTexture.index; + ASSERT(roughness_tex_idx >= 0); + const auto& base_tex = model.textures[base_tex_idx]; + ASSERT(base_tex.sampler >= 0); + ASSERT(base_tex.source >= 0); + gltf_util::setup_draw_mode_from_sampler(model.samplers.at(base_tex.sampler), &draw.mode); + gltf_util::setup_alpha_from_material(mat, &draw.mode); + const auto& roughness_tex = model.textures.at(roughness_tex_idx); + ASSERT(roughness_tex.sampler >= 0); + ASSERT(roughness_tex.source >= 0); + + draw.tree_tex_id = + tex_offset + gltf_util::texture_pool_add_envmap_control_texture( + &out.tex_pool, model, base_tex.source, roughness_tex.source, + !draw.mode.get_clamp_s_enable(), !draw.mode.get_clamp_t_enable()); + + // now, setup envmap draw: + auto envmap_settings = gltf_util::envmap_settings_from_gltf(mat); + const auto& envmap_tex = model.textures[envmap_settings.texture_idx]; + ASSERT(envmap_tex.sampler >= 0); + ASSERT(envmap_tex.source >= 0); + auto env_mode = gltf_util::make_default_draw_mode(); + gltf_util::setup_draw_mode_from_sampler(model.samplers.at(envmap_tex.sampler), &env_mode); + eff.envmap_texture = tex_offset + gltf_util::texture_pool_add_texture( + &out.tex_pool, model.images[envmap_tex.source]); + env_mode.set_alpha_blend(DrawMode::AlphaBlend::SRC_0_DST_DST); + env_mode.enable_ab(); + eff.envmap_mode = env_mode; + }; + + for (const auto& [mat_idx, d_] : draw_by_material) { + const auto& mat = model.materials[mat_idx]; + if (!material_has_envmap(mat)) { + process_normal_draw(e, mat_idx, d_); + } else { + has_envmaps = true; + envmap_eff.has_envmap = true; + process_envmap_draw(envmap_eff, mat_idx, d_); + } + } + + lg::info("total of {} unique materials ({} normal, {} envmap)", + e.all_draws.size() + envmap_eff.all_draws.size(), e.all_draws.size(), + envmap_eff.all_draws.size()); + // in case a model only has envmap draws, we don't push the normal merc effect + if (!e.all_draws.empty()) { + out.new_model.effects.push_back(e); + } + if (has_envmaps) { + out.new_model.effects.push_back(envmap_eff); } - lg::info("total of {} unique materials", e.all_draws.size()); - out.new_model.effects.push_back(e); - out.new_model.effects.push_back(e); - out.new_model.effects.push_back(e); - out.new_model.effects.push_back(e); lg::info("Merged {} meshes and {} prims into {} vertices", mesh_count, prim_count, out.new_vertices.size()); diff --git a/goalc/build_actor/common/animation_processing.cpp b/goalc/build_actor/common/animation_processing.cpp index 337c60f287..8f02068932 100644 --- a/goalc/build_actor/common/animation_processing.cpp +++ b/goalc/build_actor/common/animation_processing.cpp @@ -276,6 +276,9 @@ CompressedAnim compress_animation(const UncompressedJointAnim& in) { compress_scale(&out.fixed, joint_data.scale_frames[0]); } } + + lg::info("animation {} size {:.2f} kB", in.name, + (out.fixed.size_bytes() + out.frames.size() * out.frames.at(0).size_bytes()) / 1024.f); return out; } } // namespace anim \ No newline at end of file diff --git a/goalc/build_actor/jak1/build_actor.cpp b/goalc/build_actor/jak1/build_actor.cpp index 603f06505f..d7180af5c4 100644 --- a/goalc/build_actor/jak1/build_actor.cpp +++ b/goalc/build_actor/jak1/build_actor.cpp @@ -376,107 +376,25 @@ size_t ArtJointAnim::generate(DataObjectGenerator& gen) const { static size_t gen_dummy_frag_geo(DataObjectGenerator& gen) { size_t result = gen.current_offset_bytes(); - // frag geo stolen from money-lod0 + // frag geo stolen from money-lod2 static std::vector words = { - 0xa4320c04, 0x8000026, 0x302a0000, 0x604, 0xa910, 0xac16, 0x100af1c, - 0xb23d, 0x100b585, 0x100b870, 0xbb76, 0xbe52, 0x80808080, 0x80808080, + 0x51180504, 0x1000013, 0x1b150000, 0x604, 0x5225, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x0, 0x0, 0x89b78086, 0xf1a910a, 0x3a4b7000, 0x5f818086, - 0xf1a1094, 0x29347014, 0x49648186, 0x91313, 0x4e5d8024, 0x354b8186, 0xf1a6416, - 0x3a497024, 0x40538186, 0x91919, 0x647b8034, 0x24348186, 0xf1a371c, 0x647f7034, - 0x495d8186, 0x91f1f, 0x7a9c8044, 0x35498086, 0xf1a2231, 0x8eb57044, 0x5f7b8186, - 0x92525, 0x83ad8054, 0x5f7f8186, 0xf1a2828, 0x9fcc7054, 0x759c8186, 0x92b2b, - 0x7aa38064, 0x1c257f86, 0x273b2e2e, 0x94b86040, 0xe198186, 0x2737d034, 0x71936038, - 0xe188186, 0x273bcd3a, 0x57676030, 0x1c2a8186, 0x2737613d, 0x34456028, 0xe1b8086, - 0x485d40c7, 0x2e3c5028, 0x293c8186, 0x485d5b43, 0x131a5020, 0x26398186, 0x6e804646, - 0xf164020, 0x4b688186, 0x6e805549, 0x34018, 0x4c688186, 0x979f4c4c, 0x5073018, - 0x72978086, 0x979f4fc1, 0x5073010, 0x73988086, 0x6e807352, 0x34010, 0x4c698186, - 0x485d6d58, 0x5085018, 0x2f488086, 0x273b5e67, 0x21256020, 0x526d8186, 0x2737a66a, - 0x13196018, 0x72988186, 0x485da070, 0x5085010, 0x98c78086, 0x6e80767f, 0xf164008, - 0x95c48186, 0x979fc479, 0x13193008, 0xb0e68186, 0x979f7c7c, 0x2e3b3000, 0xb4ea8186, - 0x6e808282, 0x2b394000, 0x95c48186, 0x485d9d85, 0x131b5008, 0xb0e68186, 0x485d8888, - 0x2e3c5000, 0x8fbb8186, 0x2737978b, 0x212a6008, 0xa2db8186, 0x273b8e8e, 0x34486000, - 0x6c998086, 0x273b9aa3, 0x13186010, 0x87f86, 0x485dcaca, 0x51685030, 0x75a37f86, - 0x90707, 0x4e648000, 0x5f858186, 0x90d0d, 0x45538014, 0x0, 0x0, - 0xcb01005f, 0xcb00fffa, 0xcb010064, 0x5101e01, 0x0, 0x0, 0x306, - 0x60030000, 0x120, 0x0, 0x1cf02c14, 0x2008044, 0x0, 0x0, - 0x34, 0x81010000, 0x0, 0x0, 0x8, 0x6d100000, 0x44, - 0x80, 0x42, 0x30000, 0x86321604, 0x400001c, 0x2422440e, 0x4, - 0x1004f28, 0x1008b4c, 0xb225, 0xca4c, 0x1000128, 0x1000422, 0x1000a2e, - 0x10064ca, 0x6a34, 0x1006d2e, 0x70ca, 0x1007340, 0x7946, 0x7f4c, - 0x100884c, 0x8e4f, 0x9479, 0x9a7c, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x0, 0x0, 0x131a8086, - 0x215d0d9d, 0x87c45040, 0x38186, 0x4780a313, 0x65984038, 0x38186, 0x47806116, - 0x3d684030, 0x5078186, 0x709fa919, 0x3e693030, 0x13198186, 0x709f5b1c, 0x1b3c3028, - 0x21208186, 0x96bbaf1f, 0x21452028, 0x34428186, 0x96bf5522, 0xe242020, 0x3a408086, - 0xb6da252e, 0x27411024, 0x647f8186, 0xb6da4628, 0x16261014, 0x647a8186, 0xcbf1402b, - 0x32450014, 0x4e528086, 0xcbf1313a, 0x3b5b0024, 0x29268086, 0xb6da34b5, 0x51811034, - 0x45458186, 0xcbf13737, 0x51860034, 0x64808186, 0xd3ff3d3d, 0x51800040, 0x7aa58186, - 0xcbf14343, 0x3b520000, 0x8ebf8186, 0xb6dac749, 0x27401000, 0x71948186, 0x96bf854c, - 0x132010, 0x57668186, 0x96bb8252, 0x122018, 0x2e3b8186, 0x709f7c58, 0x1a3020, - 0xf168186, 0x4780765e, 0x18394028, 0x94bb8086, 0x96bb91c4, 0xe202008, 0xa7dc8086, - 0x96bf97c1, 0x21422000, 0xf167f86, 0x4780a0a0, 0x8ac74040, 0x5078186, 0x709fbea6, - 0x64983038, 0x13138186, 0x96bfb8ac, 0x446c2030, 0x13128186, 0x96bbbbbb, 0x5e9a2038, - 0x34458186, 0x370707, 0x94d66048, 0x5088186, 0x215d6710, 0x64975038, 0xcb010064, - 0xcb00ffd3, 0xcb010051, 0x5021000, 0x4088003, 0x10306060, 0x3, 0x0, - 0x8d301104, 0x300001f, 0x2624430a, 0x4, 0x910a, 0x100a928, 0xc42b, - 0x1006aa0, 0x70a6, 0x73bb, 0x9a07, 0xa00d, 0x100a3a0, 0x100a6bb, - 0xac34, 0xb237, 0xb83d, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x8ccc8186, - 0xf1a4c07, 0x16817074, 0x7bb58186, 0xf1a550a, 0x40b77064, 0x94d68186, 0x2737460d, - 0x46bb6068, 0x81b88186, 0x273b8e10, 0x59db6060, 0x87c48186, 0x485d4013, 0x67e65060, - 0x64978186, 0x485d8816, 0x75f85058, 0x65988186, 0x6e803a19, 0x7afd4058, 0x3d688186, - 0x6e80821c, 0x7afd4050, 0x3e698186, 0x979f341f, 0x75f93050, 0x1b3c8186, 0x979f7c22, - 0x67e73048, 0x21458086, 0xbdbb252e, 0x59e02048, 0xe248086, 0xbdbf2876, 0x46be2040, - 0x27418186, 0xdddaaf2b, 0x40c01044, 0x446c8186, 0xbdbfc731, 0x67ed2050, 0x64988186, - 0x979f3737, 0x75f93058, 0x8ac78186, 0x6e803d3d, 0x6bea4060, 0xa2e58186, 0x485d4343, - 0x4cc45068, 0xa2e88186, 0x273b4949, 0x23996070, 0x679c7f86, 0x95252, 0x2ca38064, - 0x517f8086, 0xf1a5894, 0x51cc7054, 0x5e938186, 0x27378b5b, 0x67e76058, 0x44678086, - 0x273b5e97, 0x67e86050, 0x3e688186, 0x485d8561, 0x75f85050, 0x1b3c8186, 0x485d9d64, - 0x67e55048, 0x18398186, 0x6e807f67, 0x6bea4048, 0x1a8186, 0x979f796d, 0x4cc53040, - 0x3b5b8086, 0xf2f1b5be, 0x2cae0044, 0x51868186, 0xf2f1bbbb, 0x35bb0054, 0x51818186, - 0xdddac1c1, 0x51da1054, 0x67a37f86, 0x90101, 0x648080, 0x70ad7f86, 0x94f04, - 0x16858074, 0x0, 0x0, 0x0, 0xcb010051, 0xcb00fffa, 0xcb010016, - 0x5021000, 0xc008003, 0x81860080, 0x0, 0x0, 0x92351604, 0x300001f, - 0x2826450f, 0x4, 0xac31, 0x100af5e, 0x100c449, 0xa01, 0x1000d07, - 0x6143, 0x100643d, 0x10079c1, 0x8537, 0x883d, 0x1008b07, 0x1008e49, - 0x100b243, 0xb549, 0x100b837, 0xbe31, 0xc1c1, 0xc7bb, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, - 0x80808080, 0x80808080, 0x0, 0x0, 0x0, 0x808186, 0x707, - 0x39800040, 0x2ab78186, 0x141a1010, 0xf4b7080, 0x51e78186, 0x2c379113, 0x2c6d6078, - 0x43db8186, 0x2c3b1616, 0x9486080, 0x5ff88186, 0x4d5d9719, 0x26695078, 0x51e68186, - 0x4d5d1c1c, 0x33c5080, 0x64fd8186, 0x73809d1f, 0x25684078, 0x55ea8186, 0x73802222, - 0x394080, 0x5ff98186, 0x9c9fa325, 0x26683078, 0x51e68186, 0x9c9f2828, 0x33b3080, - 0x51ee8186, 0xc2bba92b, 0x2c662078, 0x43dc8186, 0xc2bf2e2e, 0x9422080, 0x3bda8186, - 0xe2da4631, 0x397f1074, 0x2abf8186, 0xe2da3434, 0xf401080, 0x1fbb8086, 0xf7f13740, - 0x397a0074, 0x16a58186, 0xf7f13a3a, 0x23520080, 0x808186, 0xffffcd3d, 0x39800040, - 0x16ae8186, 0xf7f1ca43, 0x4fa50064, 0x2ac08186, 0xe2da7649, 0x63bf1064, 0x51ed8186, - 0xc2bfa64c, 0x46942070, 0x43e08186, 0xc2bb734f, 0x69bb2068, 0x5ff98186, 0x9c9fa052, - 0x4c973070, 0x51e78186, 0x9c9f6d55, 0x6fc43068, 0x64fd8186, 0x73809a58, 0x4d984070, - 0x55ea8186, 0x7380675b, 0x72c74068, 0x5ff88186, 0x4d5d945e, 0x4c985070, 0x36c58186, - 0x9c9f826a, 0x8ae63060, 0x30be8186, 0xc2bf7c70, 0x7cdc2060, 0xd9a8086, 0xc2bb7fbb, - 0x8aee2058, 0x16a37f86, 0x5090101, 0x23640000, 0x1fad7f86, 0x5090404, 0x39850074, - 0x0, 0x0, 0x0, 0xcb010000, 0xcb00ffff, 0xcb010039, 0x5021000, - 0x20001b, 0x6c00c102, 0x2, 0x0, 0x210f0904, 0x6, 0xb090b05, - 0x4, 0x101, 0x707, 0x1307, 0x1c04, 0x1f07, 0x80808080, - 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x0, 0x538186, - 0x90d0d, 0x1f7b0034, 0x95d7f86, 0x91010, 0x359c0044, 0x1f7b8186, 0x91616, - 0x3ead0054, 0x359c8186, 0x91919, 0x35a30064, 0x1f857f86, 0x90404, 0x530014, - 0x9648186, 0x90a0a, 0x95d0024, 0x0, 0x0, 0xcb01001f, 0xcb00fffa, - 0xcb01001f, 0x1021000, 0x223, 0x0, 0x0, 0x0}; + 0x80808080, 0x80808080, 0x80808080, 0xb4e48086, 0x757d3a0a, 0x1e324000, 0x1e328186, + 0x757d3410, 0x1c4020, 0x432e8186, 0x251313, 0x71a28044, 0x1c8186, 0x757d2e16, + 0x96ce4040, 0x719b8186, 0x151919, 0x71c08064, 0x96ce8186, 0x757d281c, 0xb4e44060, + 0x71d28186, 0x251f1f, 0x435e8080, 0xb4e48186, 0x757d4322, 0x1e324080, 0x71cc7f86, + 0xffdb4025, 0x71ad0064, 0x435c8186, 0xffea582b, 0x71bc0044, 0x43348186, 0xffdb5b31, + 0x43530024, 0x71a48086, 0xffea3755, 0x43440000, 0x71a47f86, 0xffea3d3d, 0x43440080, + 0x432e7f86, 0x254646, 0x71a20044, 0x43657f86, 0x154949, 0x43400024, 0x719b8186, + 0x154c4c, 0x71c00064, 0x71d28186, 0x254f4f, 0x435e0000, 0x71d27f86, 0x250707, + 0x435e8000, 0x43658186, 0x150d0d, 0x43408024, 0x0, 0x0, 0x0, + 0xcb01005a, 0xcb00fffa, 0xcb01005a, 0x2101e01, 0x0, 0x0, 0x306, + 0x4030000, 0x120, 0x0, 0x1cf02c14, 0x66c801d, 0x0, 0x0, + 0x34, 0x0, 0x0, 0x0, 0x8, 0x0, 0x44, + 0x80, 0x42, 0x0, + }; for (auto& word : words) { gen.add_word(word); } @@ -485,12 +403,8 @@ static size_t gen_dummy_frag_geo(DataObjectGenerator& gen) { size_t gen_dummy_frag_ctrl(DataObjectGenerator& gen) { size_t result = gen.current_offset_bytes(); - gen.add_word(0x1067232); - gen.add_word(0x54320603); - gen.add_word(0x5d300002); - gen.add_word(0x5d350002); - gen.add_word(0x120f0002); - gen.add_word(0x2); + gen.add_word(0x1063918); + gen.add_word(0x603); gen.add_word(0x0); gen.add_word(0x0); return result; @@ -501,11 +415,11 @@ size_t gen_dummy_frag_ctrl_for_uploads(DataObjectGenerator& gen, int n) { std::vector packed_frag_ctrls; - // this is still a bit of a hack - the dummy_frag_ctrl above has 8 fragments, so we need to + // this is still a bit of a hack - the dummy_frag_ctrl above has 4 fragments, so we need to // provide fragment controls for each. The PC merc renderer will de-duplicate bone uploads over // all effects and fragments, so we just need to have a single fragment that asks for all bones, // and everything will work out. - for (int k = 0; k < 8; k++) { + for (int k = 0; k < 4; k++) { packed_frag_ctrls.push_back(0); packed_frag_ctrls.push_back(0); packed_frag_ctrls.push_back(0); @@ -544,6 +458,32 @@ size_t gen_dummy_extra_info(DataObjectGenerator& gen) { return result; } +void generate_merc_effects(DataObjectGenerator& gen, int effect_count, int joints) { + struct EffectLocs { + size_t frag_geo; + size_t frag_ctrl; + size_t extra_info; + }; + std::vector locs; + for (int i = 0; i < effect_count; i++) { + EffectLocs loc{}; + loc.frag_geo = gen.add_word(0); // 112-140 (effect) + loc.frag_ctrl = gen.add_word(0); // 116 (frag-ctrl) + gen.add_word(0x0); // 120 (blend-data) + gen.add_word(0x0); // 124 (blend-ctrl) + gen.add_word(0x10000); // 128 + gen.add_word(0x140000); // 132 + gen.add_word(0x100001d); // 136 + loc.extra_info = gen.add_word(0); // 140 (extra-info) + locs.push_back(loc); + } + for (auto& loc : locs) { + gen.link_word_to_byte(loc.extra_info, gen_dummy_extra_info(gen)); + gen.link_word_to_byte(loc.frag_ctrl, gen_dummy_frag_ctrl_for_uploads(gen, joints + 3)); + gen.link_word_to_byte(loc.frag_geo, gen_dummy_frag_geo(gen)); + } +} + size_t generate_dummy_merc_ctrl(DataObjectGenerator& gen, const ArtGroup& ag) { gen.align_to_basic(); gen.add_type_tag("merc-ctrl"); @@ -557,37 +497,28 @@ size_t generate_dummy_merc_ctrl(DataObjectGenerator& gen, const ArtGroup& ag) { gen.add_word(joints); // 20 (num-joints) gen.add_word(0x0); // 24 (pad) gen.add_word(0x0); // 28 (pad) - gen.add_word(0x4188ee86); // 32-112 (xyz-scale) + gen.add_word(0x4181b897); // 32-112 (xyz-scale) gen.add_word(0xc780ff80); // 36 (st-magic) gen.add_word(0x40798000); // 40 (st-out-a) gen.add_word(0x40eb4000); // 44 (st-out-b) gen.add_word(0x4780ff80); // 48 (st-vif-add) gen.add_word(0x50000); // 52 ((st-int-off << 16) + st-int-scale) - gen.add_word(0x1); // 56 (effect-count) + gen.add_word(ag.merc_effect_count); // 56 (effect-count) gen.add_word(0x0); // 60 (blend-target-count) - gen.add_word(0xe00005); // 64 ((fragment-count << 16) + tri-count) - gen.add_word(0x860101); // 68 - gen.add_word(0x86011b); // 72 - gen.add_word(0x0); // 76 - gen.add_word(0x0); // 80 - gen.add_word(0x120101); // 84 - gen.add_word(0x83002c); // 88 - gen.add_word(0x3e780184); // 92 - gen.add_word(0x0); // 96 - gen.add_word(0x0); // 100 - gen.add_word(0x0); // 104 - gen.add_word(0x0); // 108 - auto frag_geo_slot = gen.add_word(0); // 112-140 (effect) - auto frag_ctrl_slot = gen.add_word(0); // 116 (frag-ctrl) - gen.add_word(0x0); // 120 (blend-data) - gen.add_word(0x0); // 124 (blend-ctrl) - gen.add_word(0x50000); // 128 - gen.add_word(0xe00000); // 132 - gen.add_word(0x100011b); // 136 - auto extra_info_slot = gen.add_word(0); // 140 (extra-info) - gen.link_word_to_byte(extra_info_slot, gen_dummy_extra_info(gen)); - gen.link_word_to_byte(frag_ctrl_slot, gen_dummy_frag_ctrl_for_uploads(gen, joints + 3)); - gen.link_word_to_byte(frag_geo_slot, gen_dummy_frag_geo(gen)); + gen.add_word((0x14 * ag.merc_effect_count << 16) + + ag.merc_effect_count); // 64 ((fragment-count << 16) + tri-count) + gen.add_word(0x130101); // 68 + gen.add_word(0x13001d); // 72 + gen.add_word(0x0); // 76 + gen.add_word(0x0); // 80 + gen.add_word(0x10101); // 84 + gen.add_word(0x130000); // 88 + gen.add_word(0x3f319ca9); // 92 + gen.add_word(0x0); // 96 + gen.add_word(0x0); // 100 + gen.add_word(0x0); // 104 + gen.add_word(0x0); // 108 + generate_merc_effects(gen, ag.merc_effect_count, joints); return result; } @@ -811,6 +742,7 @@ bool run_build_actor(const std::string& mdl_name, std::vector joints; MercExtractData extract_data; extract("test", extract_data, model, all_nodes, 0, 0, 0); + ag.merc_effect_count = extract_data.new_model.effects.size(); // MercSwapData out; // merc_convert(out, extract_data); // Set up joints: diff --git a/goalc/build_actor/jak1/build_actor.h b/goalc/build_actor/jak1/build_actor.h index 3150d5fb99..ccb347cecc 100644 --- a/goalc/build_actor/jak1/build_actor.h +++ b/goalc/build_actor/jak1/build_actor.h @@ -207,6 +207,7 @@ struct ArtGroup : Art { FileInfo info; std::vector> elts; std::map joint_map; + int merc_effect_count; explicit ArtGroup(const std::string& file_name) { info.file_type = "art-group"; diff --git a/goalc/build_level/collide/jak1/collide_bvh.cpp b/goalc/build_level/collide/jak1/collide_bvh.cpp index 8afaee51f3..a726767635 100644 --- a/goalc/build_level/collide/jak1/collide_bvh.cpp +++ b/goalc/build_level/collide/jak1/collide_bvh.cpp @@ -109,7 +109,7 @@ void split_along_dim(std::vector& faces, [=](const jak1::CollideFace& a, const jak1::CollideFace& b) { return a.bsphere[dim] < b.bsphere[dim]; }); - lg::print("splitting with size: {}\n", faces.size()); + // lg::print("splitting with size: {}\n", faces.size()); size_t split_idx = faces.size() / 2; out0->insert(out0->end(), faces.begin(), faces.begin() + split_idx); out1->insert(out1->end(), faces.begin() + split_idx, faces.end()); diff --git a/goalc/build_level/common/Entity.cpp b/goalc/build_level/common/Entity.cpp index 0659c82a27..53323a26d6 100644 --- a/goalc/build_level/common/Entity.cpp +++ b/goalc/build_level/common/Entity.cpp @@ -328,11 +328,20 @@ static std::unordered_map res_from_json_array(const std::string& name, const nlohmann::json& json_array, decompiler::DecompilerTypeSystem& dts) { - ASSERT(!json_array.empty()); - std::string array_type = json_array[0].get(); + if (json_array.empty()) { + throw std::runtime_error(fmt::format("json for {} lump was empty", name)); + } + auto& lump = json_array[0]; + if (lump.type() != nlohmann::detail::value_t::string) { + throw std::runtime_error( + fmt::format("first entry of lump \"{}\" has json type {}, but should be string", name, + lump.type_name())); + } + auto array_type = lump.get(); if (lump_map.find(array_type) != lump_map.end()) { return lump_map[array_type](name, json_array, dts); } else { - ASSERT_MSG(false, fmt::format("unsupported array type: {}\n", array_type)); + throw std::runtime_error( + fmt::format("unsupported array type for lump {}: {}\n", name, array_type)); } } \ No newline at end of file diff --git a/goalc/build_level/common/Tfrag.cpp b/goalc/build_level/common/Tfrag.cpp index 45935d5fac..d508a71e95 100644 --- a/goalc/build_level/common/Tfrag.cpp +++ b/goalc/build_level/common/Tfrag.cpp @@ -5,26 +5,33 @@ #include "gltf_mesh_extract.h" #include "common/custom_data/pack_helpers.h" +#include "common/util/gltf_util.h" #include "goalc/data_compiler/DataObjectGenerator.h" +void add_tree(std::vector& out_pc, + const gltf_mesh_extract::TfragOutput& mesh_extract_out, + const std::vector& draws, + tfrag3::TFragmentTreeKind kind) { + auto& normal = out_pc.emplace_back(); + normal.kind = kind; + normal.draws = draws; + pack_tfrag_vertices(&normal.packed_vertices, mesh_extract_out.tfrag_vertices); + normal.colors = gltf_util::pack_time_of_day(mesh_extract_out.color_palette); + normal.use_strips = false; +} + void tfrag_from_gltf(const gltf_mesh_extract::TfragOutput& mesh_extract_out, - DrawableTreeTfrag& /*out*/, - tfrag3::TfragTree& out_pc) { - out_pc.kind = tfrag3::TFragmentTreeKind::NORMAL; // todo more types? - out_pc.draws = std::move(mesh_extract_out.strip_draws); - pack_tfrag_vertices(&out_pc.packed_vertices, mesh_extract_out.vertices); - out_pc.colors.color_count = (mesh_extract_out.color_palette.size() + 3) & (~3); - out_pc.colors.data.resize(out_pc.colors.color_count * 8 * 4); - for (u32 color_index = 0; color_index < mesh_extract_out.color_palette.size(); color_index++) { - for (u32 palette = 0; palette < 8; palette++) { - for (u32 channel = 0; channel < 4; channel++) { - out_pc.colors.read(color_index, palette, channel) = - mesh_extract_out.color_palette[color_index][channel]; - } - } + std::vector& out_pc) { + if (!mesh_extract_out.normal_strip_draws.empty()) { + add_tree(out_pc, mesh_extract_out, mesh_extract_out.normal_strip_draws, + tfrag3::TFragmentTreeKind::NORMAL); + } + + if (!mesh_extract_out.trans_strip_draws.empty()) { + add_tree(out_pc, mesh_extract_out, mesh_extract_out.trans_strip_draws, + tfrag3::TFragmentTreeKind::TRANS); } - out_pc.use_strips = false; } /* @@ -88,7 +95,7 @@ size_t add_empty_dia(const std::string& name, DataObjectGenerator& gen, int tota size_t DrawableTreeTfrag::add_to_object_file(DataObjectGenerator& gen) const { gen.align_to_basic(); - gen.add_type_tag("drawable-tree-tfrag"); + gen.add_type_tag(m_type); size_t result = gen.current_offset_bytes(); gen.add_word(1 << 16); for (int i = 0; i < 6; i++) { @@ -96,7 +103,7 @@ size_t DrawableTreeTfrag::add_to_object_file(DataObjectGenerator& gen) const { } size_t slot = gen.add_word(0); ASSERT(slot * 4 - result == 28); - gen.link_word_to_byte(slot, add_empty_dia("drawable-inline-array-tfrag", gen, 0x64)); + gen.link_word_to_byte(slot, add_empty_dia(m_array_type, gen, 0x64)); return result; } \ No newline at end of file diff --git a/goalc/build_level/common/Tfrag.h b/goalc/build_level/common/Tfrag.h index 8c5c8521bc..d92d9fb5c0 100644 --- a/goalc/build_level/common/Tfrag.h +++ b/goalc/build_level/common/Tfrag.h @@ -8,10 +8,18 @@ class DataObjectGenerator; -struct DrawableTreeTfrag { +class DrawableTreeTfrag { + // "drawable-tree-tfrag" + // "drawable-inline-array-tfrag" + public: + DrawableTreeTfrag(const std::string& type, const std::string& array_type) + : m_type(type), m_array_type(array_type) {} size_t add_to_object_file(DataObjectGenerator& gen) const; + + private: + std::string m_type; + std::string m_array_type; }; void tfrag_from_gltf(const gltf_mesh_extract::TfragOutput& mesh_extract_out, - DrawableTreeTfrag& out, - tfrag3::TfragTree& out_pc); \ No newline at end of file + std::vector& out_pc); \ No newline at end of file diff --git a/goalc/build_level/common/Tie.cpp b/goalc/build_level/common/Tie.cpp new file mode 100644 index 0000000000..7893db4aca --- /dev/null +++ b/goalc/build_level/common/Tie.cpp @@ -0,0 +1,129 @@ +#include "Tie.h" + +void tie_from_gltf(const gltf_mesh_extract::TieOutput& mesh_extract_out, + std::vector& out_pc) { + auto& out = out_pc.emplace_back(); + // bvh: leave default + // draws + // categories + out.category_draw_indices[0] = 0; + for (int category_idx = 0; category_idx < tfrag3::kNumTieCategories; category_idx++) { + switch ((tfrag3::TieCategory)category_idx) { + case tfrag3::TieCategory::NORMAL_ENVMAP: + out.static_draws.insert(out.static_draws.end(), mesh_extract_out.base_draws.begin(), + mesh_extract_out.base_draws.end()); + break; + case tfrag3::TieCategory::NORMAL_ENVMAP_SECOND_DRAW: + out.static_draws.insert(out.static_draws.end(), mesh_extract_out.envmap_draws.begin(), + mesh_extract_out.envmap_draws.end()); + break; + default: + break; + } + out.category_draw_indices[category_idx + 1] = out.static_draws.size(); + } + // packed + out.packed_vertices.color_indices = mesh_extract_out.color_indices; + out.packed_vertices.vertices = mesh_extract_out.vertices; + auto& matrix_group = out.packed_vertices.matrix_groups.emplace_back(); + matrix_group.matrix_idx = -1; + matrix_group.start_vert = 0; + matrix_group.end_vert = out.packed_vertices.vertices.size(); + matrix_group.has_normals = true; + + // colors + out.colors = gltf_util::pack_time_of_day(mesh_extract_out.color_palette); + // wind (none) + // proto vis toggle + out.has_per_proto_visibility_toggle = false; + + out.use_strips = false; +} + +/* + +(deftype drawable (basic) + ((id int16 :offset-assert 4) + (bsphere vector :inline :offset-assert 16) + ) + +(deftype drawable-tree (drawable-group) + () + :flag-assert #x1200000024 + ) + +(deftype drawable-group (drawable) + ((length int16 :offset 6) + (data drawable 1 :offset-assert 32) + ) + (:methods + (new (symbol type int) _type_) + ) + :flag-assert #x1200000024 + ) + +(deftype drawable-tree-instance-tie (drawable-tree) + ((prototypes proxy-prototype-array-tie :offset 8) + ) + :method-count-assert 18 + :size-assert #x24 + :flag-assert #x1200000024 + ) + +(deftype proxy-prototype-array-tie (basic) + ((prototype-array-tie prototype-array-tie :offset-assert 4) + (wind-vectors uint32 :offset-assert 8) ; likely a pointer + ) + :method-count-assert 9 + :size-assert #xc + :flag-assert #x90000000c + ) + +(deftype prototype-array-tie (array) + ((array-data prototype-bucket-tie :dynamic :offset 16) + ) + :method-count-assert 10 + :size-assert #x10 + :flag-assert #xa00000010 + (:methods + (login (_type_) none) ;; 9 + ) + ) +*/ + +size_t add_prototype_array_tie(DataObjectGenerator& gen) { + gen.align_to_basic(); + gen.add_type_tag("prototype-array-tie"); // 0 + size_t ret = gen.current_offset_bytes(); + gen.add_word(0); // 4 length + gen.add_word(0); // 8 allocated-length + gen.add_type_tag("prototype-bucket-tie"); // 12 content type (might be wrong?) + return ret; +} + +size_t add_proxy_prototype_array_tie(DataObjectGenerator& gen) { + const size_t array_offset = add_prototype_array_tie(gen); + + gen.align_to_basic(); + gen.add_type_tag("proxy-prototype-array-tie"); // 0 + const size_t result = gen.current_offset_bytes(); + const size_t array_slot = gen.add_word(0); // 4 prototype-array-tie + gen.link_word_to_byte(array_slot, array_offset); + gen.add_word(0); // 8 wind-vectors + return result; +} + +size_t add_tie_tree_to_object_file(DataObjectGenerator& gen) { + const size_t proxy = add_proxy_prototype_array_tie(gen); + gen.align_to_basic(); + gen.add_type_tag("drawable-tree-instance-tie"); // 0 + size_t result = gen.current_offset_bytes(); + gen.add_word(0); // 4 (id = 0, length = 0) + const size_t slot = gen.add_word(0); // 8 + gen.link_word_to_byte(slot, proxy); + return result; +} + +size_t DrawableTreeInstanceTie::add_to_object_file(DataObjectGenerator& gen) const { + return add_tie_tree_to_object_file(gen); +} diff --git a/goalc/build_level/common/Tie.h b/goalc/build_level/common/Tie.h new file mode 100644 index 0000000000..f4ebf945fa --- /dev/null +++ b/goalc/build_level/common/Tie.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Tie.h" + +#include "common/custom_data/Tfrag3Data.h" +#include "common/util/gltf_util.h" + +#include "goalc/build_level/common/gltf_mesh_extract.h" +#include "goalc/data_compiler/DataObjectGenerator.h" + +void tie_from_gltf(const gltf_mesh_extract::TieOutput& mesh_extract_out, + std::vector& out_pc); + +class DrawableTreeInstanceTie { + public: + size_t add_to_object_file(DataObjectGenerator& gen) const; +}; \ No newline at end of file diff --git a/goalc/build_level/common/color_quantization.cpp b/goalc/build_level/common/color_quantization.cpp index 2be2dee523..ccedb3b88a 100644 --- a/goalc/build_level/common/color_quantization.cpp +++ b/goalc/build_level/common/color_quantization.cpp @@ -1,10 +1,12 @@ #include "color_quantization.h" #include +#include #include #include "common/log/log.h" #include "common/util/Assert.h" +#include "common/util/Timer.h" /*! * Just removes duplicate colors, which can work if there are only a few unique colors. @@ -221,3 +223,142 @@ QuantizedColors quantize_colors_octree(const std::vector>& i return out; } + +struct KdNode { + // if not a leaf + std::unique_ptr left, right; + + // if leaf + std::vector colors; +}; + +void split_kd(KdNode* in, u32 depth, int next_split_dim) { + if (!depth) { + return; + } + + if (!in->colors.empty()) { + for (int i = 0; i < 4; i++) { + bool all_same = true; + u8 same = in->colors[0][next_split_dim]; + for (auto& color : in->colors) { + if (color[next_split_dim] != same) { + all_same = false; + break; + } + } + if (all_same) { + next_split_dim = (next_split_dim + 1) % 4; + } else { + break; + } + } + } + + // sort by split dimension + std::stable_sort(in->colors.begin(), in->colors.end(), [=](const Color& a, const Color& b) { + return a[next_split_dim] < b[next_split_dim]; + }); + + in->left = std::make_unique(); + in->right = std::make_unique(); + + size_t i = 0; + size_t mid = in->colors.size() / 2; + if (depth & 1) { + while (mid > 1 && in->colors[mid][next_split_dim] == in->colors[mid - 1][next_split_dim]) { + mid--; + } + } else { + while (mid + 2 < in->colors.size() && + in->colors[mid][next_split_dim] == in->colors[mid + 1][next_split_dim]) { + mid++; + } + } + + for (; i < mid; i++) { + in->left->colors.push_back(in->colors[i]); + } + + for (; i < in->colors.size(); i++) { + in->right->colors.push_back(in->colors[i]); + } + + split_kd(in->left.get(), depth - 1, (next_split_dim + 1) % 4); + split_kd(in->right.get(), depth - 1, (next_split_dim + 1) % 4); +} + +template +void for_each_child(KdNode* node, Func&& f) { + if (node->left) { + for_each_child(node->left.get(), f); + for_each_child(node->right.get(), f); + } else { + f(node); + } +} + +u32 color_as_u32(const Color& color) { + u32 ret = 0; + memcpy(&ret, color.data(), 4); + return ret; +} + +Color u32_as_color(u32 in) { + Color ret; + memcpy(ret.data(), &in, 4); + return ret; +} + +std::vector deduplicated_colors(const std::vector& in) { + std::set unique; + for (auto& x : in) { + unique.insert(color_as_u32(x)); + } + std::vector out; + for (auto& x : unique) { + out.push_back(u32_as_color(x)); + } + return out; +} + +QuantizedColors quantize_colors_kd_tree(const std::vector>& in, + u32 target_depth) { + Timer timer; + // Build root node: + KdNode root; + root.colors = deduplicated_colors(in); + // root.colors = in; + + // Split tree: + split_kd(&root, target_depth, 0); + + // Get final colors: + std::unordered_map color_value_to_color_idx; + QuantizedColors result; + for_each_child(&root, [&](KdNode* node) { + if (node->colors.empty()) { + return; + } + + const u32 slot = result.final_colors.size(); + u32 totals[4] = {0, 0, 0, 0}; + u32 n = node->colors.size(); + for (auto& color : node->colors) { + color_value_to_color_idx[color_as_u32(color)] = slot; + for (int i = 0; i < 4; i++) { + totals[i] += color[i]; + } + } + result.final_colors.emplace_back(totals[0] / n, totals[1] / n, totals[2] / n, + totals[3] / (2 * n)); + }); + + for (auto& color : in) { + result.vtx_to_color.push_back(color_value_to_color_idx.at(color_as_u32(color))); + } + + lg::warn("Quantize colors: {} input colors -> {} output in {:.3f} ms\n", in.size(), + result.final_colors.size(), timer.getMs()); + return result; +} diff --git a/goalc/build_level/common/color_quantization.h b/goalc/build_level/common/color_quantization.h index f0b92a81de..bd302181f0 100644 --- a/goalc/build_level/common/color_quantization.h +++ b/goalc/build_level/common/color_quantization.h @@ -18,4 +18,7 @@ struct QuantizedColors { QuantizedColors quantize_colors_dumb(const std::vector>& in); QuantizedColors quantize_colors_octree(const std::vector>& in, - u32 target_count); \ No newline at end of file + u32 target_count); + +QuantizedColors quantize_colors_kd_tree(const std::vector>& in, + u32 target_depth); \ No newline at end of file diff --git a/goalc/build_level/common/gltf_mesh_extract.cpp b/goalc/build_level/common/gltf_mesh_extract.cpp index 05e5a40db5..3d84f74fda 100644 --- a/goalc/build_level/common/gltf_mesh_extract.cpp +++ b/goalc/build_level/common/gltf_mesh_extract.cpp @@ -12,23 +12,66 @@ #include "common/math/geometry.h" #include "common/util/Timer.h" #include "common/util/gltf_util.h" +#include using namespace gltf_util; namespace gltf_mesh_extract { -void dedup_vertices(TfragOutput& data) { +void dedup_tfrag_vertices(TfragOutput& data) { Timer timer; - size_t original_size = data.vertices.size(); + size_t original_size = data.tfrag_vertices.size(); std::vector new_verts; std::vector old_to_new; - gltf_util::dedup_vertices(data.vertices, new_verts, old_to_new); - data.vertices = std::move(new_verts); + gltf_util::dedup_vertices(data.tfrag_vertices, new_verts, old_to_new); + data.tfrag_vertices = std::move(new_verts); + + // TODO: properly split vertices between trees... + for (auto drawlist : {&data.normal_strip_draws, &data.trans_strip_draws}) { + for (auto& draw : *drawlist) { + ASSERT(draw.runs.empty()); // not supported yet + for (auto& idx : draw.plain_indices) { + idx = old_to_new.at(idx); + } + } + } + + lg::info("Deduplication took {:.2f} ms, {} -> {} ({:.2f} %)", timer.getMs(), original_size, + data.tfrag_vertices.size(), 100.f * data.tfrag_vertices.size() / original_size); +} + +void dedup_tie_vertices(TieOutput& data) { + Timer timer; + size_t original_size = data.vertices.size(); + + std::vector old_verts; + old_verts.reserve(data.vertices.size()); + for (size_t i = 0; i < data.vertices.size(); i++) { + auto& x = old_verts.emplace_back(); + x.color_index = data.color_indices[i]; + x.vertex = data.vertices[i]; + } + + std::vector new_verts; + std::vector old_to_new; + + gltf_util::dedup_vertices(old_verts, new_verts, old_to_new); + data.vertices.clear(); + data.color_indices.clear(); + data.vertices.reserve(new_verts.size()); + data.color_indices.reserve(new_verts.size()); + for (auto& x : new_verts) { + data.vertices.push_back(x.vertex); + data.color_indices.push_back(x.color_index); + } - for (auto& draw : data.strip_draws) { - ASSERT(draw.runs.empty()); // not supported yet - for (auto& idx : draw.plain_indices) { - idx = old_to_new.at(idx); + // TODO: properly split vertices between trees... + for (auto drawlist : {&data.base_draws, &data.envmap_draws}) { + for (auto& draw : *drawlist) { + ASSERT(draw.runs.empty()); // not supported yet + for (auto& idx : draw.plain_indices) { + idx = old_to_new.at(idx); + } } } @@ -36,13 +79,26 @@ void dedup_vertices(TfragOutput& data) { data.vertices.size(), 100.f * data.vertices.size() / original_size); } +bool prim_needs_tie(const tinygltf::Model& model, const tinygltf::Primitive& prim) { + if (prim.material >= 0) { + auto mat = model.materials.at(prim.material); + return mat.extensions.contains("KHR_materials_specular"); + } + return false; +} + void extract(const Input& in, TfragOutput& out, const tinygltf::Model& model, const std::vector& all_nodes) { std::vector> all_vtx_colors; - ASSERT(out.vertices.empty()); - std::map draw_by_material; + ASSERT(out.tfrag_vertices.empty()); + + struct MaterialInfo { + tfrag3::StripDraw draw; + bool needs_tie = false; + }; + std::map info_by_material; int mesh_count = 0; int prim_count = 0; @@ -59,85 +115,264 @@ void extract(const Input& in, model.materials[prim.material].extras.Get("set_invisible").Get()) { continue; } + + if (prim_needs_tie(model, prim)) { + continue; + } prim_count++; // extract index buffer - std::vector prim_indices = gltf_index_buffer(model, prim.indices, out.vertices.size()); + std::vector prim_indices = + gltf_index_buffer(model, prim.indices, out.tfrag_vertices.size()); ASSERT_MSG(prim.mode == TINYGLTF_MODE_TRIANGLES, "Unsupported triangle mode"); // extract vertices - auto verts = - gltf_vertices(model, prim.attributes, n.w_T_node, in.get_colors, false, mesh.name); - out.vertices.insert(out.vertices.end(), verts.vtx.begin(), verts.vtx.end()); - if (in.get_colors) { - all_vtx_colors.insert(all_vtx_colors.end(), verts.vtx_colors.begin(), - verts.vtx_colors.end()); - ASSERT(all_vtx_colors.size() == out.vertices.size()); - } - - // TODO: just putting it all in one material - auto& draw = draw_by_material[prim.material]; - draw.mode = make_default_draw_mode(); // todo rm - draw.tree_tex_id = texture_pool_debug_checker(in.tex_pool); // todo rm - draw.num_triangles += prim_indices.size() / 3; - if (draw.vis_groups.empty()) { - auto& grp = draw.vis_groups.emplace_back(); + auto verts = gltf_vertices(model, prim.attributes, n.w_T_node, true, false, mesh.name); + out.tfrag_vertices.insert(out.tfrag_vertices.end(), verts.vtx.begin(), verts.vtx.end()); + all_vtx_colors.insert(all_vtx_colors.end(), verts.vtx_colors.begin(), + verts.vtx_colors.end()); + ASSERT(all_vtx_colors.size() == out.tfrag_vertices.size()); + + auto& info = info_by_material[prim.material]; + info.draw.mode = make_default_draw_mode(); // todo rm + info.draw.tree_tex_id = texture_pool_debug_checker(in.tex_pool); // todo rm + info.draw.num_triangles += prim_indices.size() / 3; + if (info.draw.vis_groups.empty()) { + auto& grp = info.draw.vis_groups.emplace_back(); grp.num_inds += prim_indices.size(); - grp.num_tris += draw.num_triangles; + grp.num_tris += info.draw.num_triangles; grp.vis_idx_in_pc_bvh = UINT16_MAX; } else { - auto& grp = draw.vis_groups.back(); + auto& grp = info.draw.vis_groups.back(); grp.num_inds += prim_indices.size(); - grp.num_tris += draw.num_triangles; + grp.num_tris += info.draw.num_triangles; grp.vis_idx_in_pc_bvh = UINT16_MAX; } - draw.plain_indices.insert(draw.plain_indices.end(), prim_indices.begin(), - prim_indices.end()); + info.draw.plain_indices.insert(info.draw.plain_indices.end(), prim_indices.begin(), + prim_indices.end()); } } } - for (const auto& [mat_idx, d_] : draw_by_material) { - out.strip_draws.push_back(d_); - auto& draw = out.strip_draws.back(); + for (const auto& [mat_idx, d_] : info_by_material) { + // out.strip_draws.push_back(d_); + // auto& draw = out.strip_draws.back(); + tfrag3::StripDraw draw = d_.draw; draw.mode = make_default_draw_mode(); if (mat_idx == -1) { lg::warn("Draw had a material index of -1, using default texture."); draw.tree_tex_id = texture_pool_debug_checker(in.tex_pool); + out.normal_strip_draws.push_back(draw); continue; } + const auto& mat = model.materials[mat_idx]; + setup_alpha_from_material(mat, &draw.mode); int tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index; if (tex_idx == -1) { lg::warn("Material {} has no texture, using default texture.", mat.name); draw.tree_tex_id = texture_pool_debug_checker(in.tex_pool); + if (draw.mode.get_ab_enable()) { + out.trans_strip_draws.push_back(draw); + } else { + out.normal_strip_draws.push_back(draw); + } continue; } const auto& tex = model.textures[tex_idx]; ASSERT(tex.sampler >= 0); ASSERT(tex.source >= 0); - draw.mode = draw_mode_from_sampler(model.samplers.at(tex.sampler)); + setup_draw_mode_from_sampler(model.samplers.at(tex.sampler), &draw.mode); const auto& img = model.images[tex.source]; draw.tree_tex_id = texture_pool_add_texture(in.tex_pool, img); + + if (draw.mode.get_ab_enable()) { + out.trans_strip_draws.push_back(draw); + } else { + out.normal_strip_draws.push_back(draw); + } } - lg::info("total of {} unique materials", out.strip_draws.size()); + lg::info("total of {} normal, {} transparent unique materials", out.normal_strip_draws.size(), + out.trans_strip_draws.size()); lg::info("Merged {} meshes and {} prims into {} vertices", mesh_count, prim_count, - out.vertices.size()); + out.tfrag_vertices.size()); + + Timer quantize_timer; + auto quantized = quantize_colors_kd_tree(all_vtx_colors, 10); + for (size_t i = 0; i < out.tfrag_vertices.size(); i++) { + out.tfrag_vertices[i].color_index = quantized.vtx_to_color[i]; + } + out.color_palette = std::move(quantized.final_colors); + lg::info("Color palette generation took {:.2f} ms", quantize_timer.getMs()); + + dedup_tfrag_vertices(out); +} + +s8 normal_to_s8(float in) { + s32 in_s32 = in * 127.f; + ASSERT(in_s32 <= INT8_MAX); + ASSERT(in_s32 >= INT8_MIN); + return in_s32; +} + +void add_to_packed_verts(std::vector* out, + const std::vector& vtx, + const std::vector& normals) { + ASSERT(vtx.size() == normals.size()); + for (size_t i = 0; i < normals.size(); i++) { + auto& x = out->emplace_back(); + // currently not supported. + x.r = 255; + x.g = 255; + x.b = 255; + x.a = 255; + + x.x = vtx[i].x; + x.y = vtx[i].y; + x.z = vtx[i].z; + + x.s = vtx[i].s; + x.t = vtx[i].t; + + x.nx = normal_to_s8(normals[i].x()); + x.ny = normal_to_s8(normals[i].y()); + x.nz = normal_to_s8(normals[i].z()); + } +} + +void extract(const Input& in, + TieOutput& out, + const tinygltf::Model& model, + const std::vector& all_nodes) { + std::vector> all_vtx_colors; + + struct MaterialInfo { + tfrag3::StripDraw draw; + bool needs_tie = false; + }; + std::map info_by_material; + int mesh_count = 0; + int prim_count = 0; - if (in.get_colors) { - Timer quantize_timer; - auto quantized = quantize_colors_octree(all_vtx_colors, 1024); - for (size_t i = 0; i < out.vertices.size(); i++) { - out.vertices[i].color_index = quantized.vtx_to_color[i]; + for (const auto& n : all_nodes) { + const auto& node = model.nodes[n.node_idx]; + if (node.extras.Has("set_invisible") && node.extras.Get("set_invisible").Get()) { + continue; } - out.color_palette = std::move(quantized.final_colors); - lg::info("Color palette generation took {:.2f} ms", quantize_timer.getMs()); + if (node.mesh >= 0) { + const auto& mesh = model.meshes[node.mesh]; + mesh_count++; + for (const auto& prim : mesh.primitives) { + if (prim.material >= 0 && model.materials[prim.material].extras.Has("set_invisible") && + model.materials[prim.material].extras.Get("set_invisible").Get()) { + continue; + } + + if (!prim_needs_tie(model, prim)) { + continue; + } + prim_count++; + // extract index buffer + std::vector prim_indices = gltf_index_buffer(model, prim.indices, out.vertices.size()); + ASSERT_MSG(prim.mode == TINYGLTF_MODE_TRIANGLES, "Unsupported triangle mode"); + // extract vertices + auto verts = gltf_vertices(model, prim.attributes, n.w_T_node, true, true, mesh.name); + add_to_packed_verts(&out.vertices, verts.vtx, verts.normals); + all_vtx_colors.insert(all_vtx_colors.end(), verts.vtx_colors.begin(), + verts.vtx_colors.end()); + ASSERT(all_vtx_colors.size() == out.vertices.size()); + + auto& info = info_by_material[prim.material]; + info.draw.mode = make_default_draw_mode(); // todo rm + info.draw.tree_tex_id = texture_pool_debug_checker(in.tex_pool); // todo rm + info.draw.num_triangles += prim_indices.size() / 3; + if (info.draw.vis_groups.empty()) { + auto& grp = info.draw.vis_groups.emplace_back(); + grp.num_inds += prim_indices.size(); + grp.num_tris += info.draw.num_triangles; + grp.vis_idx_in_pc_bvh = UINT16_MAX; + } else { + auto& grp = info.draw.vis_groups.back(); + grp.num_inds += prim_indices.size(); + grp.num_tris += info.draw.num_triangles; + grp.vis_idx_in_pc_bvh = UINT16_MAX; + } + + info.draw.plain_indices.insert(info.draw.plain_indices.end(), prim_indices.begin(), + prim_indices.end()); + } + } + } + + for (const auto& [mat_idx, d_] : info_by_material) { + // out.strip_draws.push_back(d_); + // auto& draw = out.strip_draws.back(); + tfrag3::StripDraw draw = d_.draw; + draw.mode = make_default_draw_mode(); + + if (mat_idx == -1) { + lg::warn("Draw had a material index of -1, using default texture."); + draw.tree_tex_id = texture_pool_debug_checker(in.tex_pool); + out.base_draws.push_back(draw); + continue; + } + + const auto& mat = model.materials[mat_idx]; + setup_alpha_from_material(mat, &draw.mode); + int base_tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index; + if (base_tex_idx == -1) { + lg::warn("Material {} has no texture, using default texture.", mat.name); + draw.tree_tex_id = texture_pool_debug_checker(in.tex_pool); + out.base_draws.push_back(draw); + continue; + } + int roughness_tex_idx = mat.pbrMetallicRoughness.metallicRoughnessTexture.index; + ASSERT(roughness_tex_idx >= 0); + const auto& base_tex = model.textures[base_tex_idx]; + ASSERT(base_tex.sampler >= 0); + ASSERT(base_tex.source >= 0); + setup_draw_mode_from_sampler(model.samplers.at(base_tex.sampler), &draw.mode); + const auto& roughness_tex = model.textures.at(roughness_tex_idx); + ASSERT(roughness_tex.sampler >= 0); + ASSERT(roughness_tex.source >= 0); + + // draw.tree_tex_id = texture_pool_add_texture(in.tex_pool, model.images[base_tex.source]); + draw.tree_tex_id = texture_pool_add_envmap_control_texture( + in.tex_pool, model, base_tex.source, roughness_tex.source, !draw.mode.get_clamp_s_enable(), + !draw.mode.get_clamp_t_enable()); + out.base_draws.push_back(draw); + + // now, setup envmap draw: + auto envmap_settings = envmap_settings_from_gltf(mat); + const auto& envmap_tex = model.textures[envmap_settings.texture_idx]; + ASSERT(envmap_tex.sampler >= 0); + ASSERT(envmap_tex.source >= 0); + draw.mode = make_default_draw_mode(); + setup_draw_mode_from_sampler(model.samplers.at(envmap_tex.sampler), &draw.mode); + draw.tree_tex_id = texture_pool_add_texture(in.tex_pool, model.images[envmap_tex.source]); + draw.mode.set_alpha_blend(DrawMode::AlphaBlend::SRC_0_DST_DST); + draw.mode.enable_ab(); + + out.envmap_draws.push_back(draw); + } + lg::info("total of {} normal TIE draws, {} envmap", out.base_draws.size(), + out.envmap_draws.size()); + + lg::info("Merged {} meshes and {} prims into {} vertices", mesh_count, prim_count, + out.vertices.size()); + + Timer quantize_timer; + auto quantized = quantize_colors_kd_tree(all_vtx_colors, 10); + for (size_t i = 0; i < out.vertices.size(); i++) { + out.color_indices.push_back(quantized.vtx_to_color[i]); } + out.color_palette = std::move(quantized.final_colors); + lg::info("Color palette generation took {:.2f} ms", quantize_timer.getMs()); - dedup_vertices(out); + dedup_tie_vertices(out); } std::optional> subdivide_face_if_needed(jak1::CollideFace face_in) { @@ -386,6 +621,7 @@ void extract(const Input& in, Output& out) { auto all_nodes = flatten_nodes_from_all_scenes(model); extract(in, out.tfrag, model, all_nodes); extract(in, out.collide, model, all_nodes); + extract(in, out.tie, model, all_nodes); lg::info("GLTF total took {:.2f} ms", read_timer.getMs()); } } // namespace gltf_mesh_extract diff --git a/goalc/build_level/common/gltf_mesh_extract.h b/goalc/build_level/common/gltf_mesh_extract.h index d9f126ced6..fbba828a5a 100644 --- a/goalc/build_level/common/gltf_mesh_extract.h +++ b/goalc/build_level/common/gltf_mesh_extract.h @@ -17,15 +17,15 @@ namespace gltf_mesh_extract { struct Input { std::string filename; gltf_util::TexturePool* tex_pool = nullptr; - bool get_colors = true; bool auto_wall_enable = true; float auto_wall_angle = 30.f; bool double_sided_collide = false; }; struct TfragOutput { - std::vector strip_draws; - std::vector vertices; + std::vector normal_strip_draws; + std::vector trans_strip_draws; + std::vector tfrag_vertices; std::vector> color_palette; }; @@ -33,9 +33,18 @@ struct CollideOutput { std::vector faces; }; +struct TieOutput { + std::vector base_draws; + std::vector envmap_draws; + std::vector vertices; + std::vector color_indices; + std::vector> color_palette; +}; + struct Output { TfragOutput tfrag; CollideOutput collide; + TieOutput tie; }; struct PatResult { diff --git a/goalc/build_level/jak1/LevelFile.cpp b/goalc/build_level/jak1/LevelFile.cpp index 7393ca3f71..a49cc34e50 100644 --- a/goalc/build_level/jak1/LevelFile.cpp +++ b/goalc/build_level/jak1/LevelFile.cpp @@ -26,6 +26,7 @@ size_t DrawableTreeArray::add_to_object_file(DataObjectGenerator& gen) const { num_trees += tfrags.size(); num_trees += collides.size(); num_trees += ambients.size(); + num_trees += ties.size(); gen.add_word(num_trees << 16); gen.add_word(0); gen.add_word(0); @@ -35,8 +36,6 @@ size_t DrawableTreeArray::add_to_object_file(DataObjectGenerator& gen) const { gen.add_word(0); gen.add_word(0); - // todo add trees... - if (num_trees == 0) { gen.add_word(0); // the one at the end. } else { @@ -54,6 +53,10 @@ size_t DrawableTreeArray::add_to_object_file(DataObjectGenerator& gen) const { gen.link_word_to_byte(tree_word++, collide.add_to_object_file(gen)); } + for (auto& tie : ties) { + gen.link_word_to_byte(tree_word++, tie.add_to_object_file(gen)); + } + for (auto& ambient : ambients) { gen.link_word_to_byte(tree_word++, ambient.add_to_object_file(gen, ambient_arr_slot)); } @@ -71,6 +74,44 @@ size_t generate_u32_array(const std::vector& array, DataObjectGenerator& ge return result; } +size_t generate_adgif_shader_array(const std::vector& data, DataObjectGenerator& gen) { + gen.align_to_basic(); + gen.add_type_tag("adgif-shader-array"); + size_t result = gen.current_offset_bytes(); + for (auto& word : data) { + gen.add_word(word); + } + return result; +} + +size_t generate_adgif_shader_array(const AdgifShaderArray& adgifs, DataObjectGenerator& gen) { + gen.align_to_basic(); + gen.add_type_tag("adgif-shader-array"); + size_t result = gen.current_offset_bytes(); + gen.add_word(adgifs.adgifs.size()); + gen.add_word(adgifs.adgifs.size()); + gen.add_word(0); + for (auto& adgif : adgifs.adgifs) { + for (size_t i = 0; i < sizeof(AdGifData) / sizeof(u32); i++) { + u32 data; + memcpy(&data, (u32*)&adgif + i, sizeof(u32)); + gen.add_word(data); + } + } + return result; +} + +size_t generate_tex_remap_table(const std::vector& remap_table, + DataObjectGenerator& gen) { + gen.align(4); + size_t result = gen.current_offset_bytes(); + for (auto& entry : remap_table) { + gen.add_word(entry.orig_texid); + gen.add_word(entry.new_texid); + } + return result; +} + std::vector LevelFile::save_object_file() const { DataObjectGenerator gen; gen.add_type_tag("bsp-header"); @@ -94,9 +135,15 @@ std::vector LevelFile::save_object_file() const { //(pat pointer :offset-assert 44) //(pat-length int32 :offset-assert 48) //(texture-remap-table (pointer uint64) :offset-assert 52) + if (!texture_remap_table.empty()) + gen.link_word_to_byte(52 / 4, generate_tex_remap_table(texture_remap_table, gen)); //(texture-remap-table-len int32 :offset-assert 56) + gen.set_word(56 / 4, texture_remap_table.size()); //(texture-ids (pointer texture-id) :offset-assert 60) + if (!texture_ids.empty()) + gen.link_word_to_byte(60 / 4, generate_u32_array(texture_ids, gen)); //(texture-page-count int32 :offset-assert 64) + gen.set_word(64 / 4, texture_ids.size()); //(unk-zero-0 basic :offset-assert 68) //(name symbol :offset-assert 72) gen.link_word_to_symbol(name, 72 / 4); @@ -117,6 +164,8 @@ std::vector LevelFile::save_object_file() const { //(unk-data-4 float :offset-assert 160) //(unk-data-5 float :offset-assert 164) //(adgifs adgif-shader-array :offset-assert 168) + if (!adgifs.adgifs.empty()) + gen.link_word_to_byte(168 / 4, generate_adgif_shader_array(adgifs, gen)); //(actor-birth-order (pointer uint32) :offset-assert 172) gen.link_word_to_byte(172 / 4, generate_u32_array(actor_birth_order, gen)); //(split-box-indices (pointer uint16) :offset-assert 176) diff --git a/goalc/build_level/jak1/LevelFile.h b/goalc/build_level/jak1/LevelFile.h index 17844e9e20..3f718ec2f0 100644 --- a/goalc/build_level/jak1/LevelFile.h +++ b/goalc/build_level/jak1/LevelFile.h @@ -15,14 +15,13 @@ #include "goalc/build_level/collide/jak1/collide_drawable.h" #include "goalc/build_level/collide/jak1/collide_pack.h" #include "goalc/build_level/common/Tfrag.h" +#include "goalc/build_level/common/Tie.h" namespace jak1 { struct VisibilityString { std::vector bytes; }; -struct DrawableTreeInstanceTie {}; - struct DrawableTreeActor {}; struct DrawableTreeInstanceShrub {}; @@ -37,7 +36,10 @@ struct DrawableTreeArray { size_t add_to_object_file(DataObjectGenerator& gen) const; }; -struct TextureRemap {}; +struct TexRemap { + u32 orig_texid; + u32 new_texid; +}; struct TextureId {}; @@ -53,7 +55,9 @@ struct DrawableInlineArrayAmbient { std::vector ambients; }; -struct AdgifShaderArray {}; +struct AdgifShaderArray { + std::vector adgifs; +}; // This is a place to collect all the data that should go into the bsp-header file. struct LevelFile { @@ -73,11 +77,11 @@ struct LevelFile { // (texture-remap-table (pointer uint64) :offset-assert 52) // (texture-remap-table-len int32 :offset-assert 56) - std::vector texture_remap_table; + std::vector texture_remap_table; // (texture-ids (pointer texture-id) :offset-assert 60) // (texture-page-count int32 :offset-assert 64) - std::vector texture_ids; + std::vector texture_ids; // (unk-zero-0 basic :offset-assert 68) // "misc", seems like it can be zero and is unused. diff --git a/goalc/build_level/jak1/build_level.cpp b/goalc/build_level/jak1/build_level.cpp index 3801eb92c7..810df3e7c7 100644 --- a/goalc/build_level/jak1/build_level.cpp +++ b/goalc/build_level/jak1/build_level.cpp @@ -3,6 +3,9 @@ #include "common/util/gltf_util.h" #include "decompiler/extractor/extractor_util.h" +#include "decompiler/level_extractor/BspHeader.h" +#include "decompiler/level_extractor/extract_collide_frags.h" +#include "decompiler/level_extractor/extract_level.h" #include "decompiler/level_extractor/extract_merc.h" #include "goalc/build_level/collide/jak1/collide_bvh.h" #include "goalc/build_level/collide/jak1/collide_pack.h" @@ -17,7 +20,7 @@ bool run_build_level(const std::string& input_file, const std::string& output_prefix) { auto level_json = parse_commented_json( file_util::read_text_file(file_util::get_file_path({input_file})), input_file); - LevelFile file; // GOAL level file + LevelFile file{}; // GOAL level file tfrag3::Level pc_level; // PC level file gltf_util::TexturePool tex_pool; // pc level texture pool @@ -48,7 +51,7 @@ bool run_build_level(const std::string& input_file, // actors std::vector actors; auto dts = decompiler::DecompilerTypeSystem(GameVersion::Jak1); - dts.parse_enum_defs({"decompiler", "config", "jak1", "all-types.gc"}); + dts.parse_type_defs({"decompiler", "config", "jak1", "all-types.gc"}); add_actors_from_json(level_json.at("actors"), actors, level_json.value("base_id", 1234), dts); std::sort(actors.begin(), actors.end(), [](auto& a, auto& b) { return a.aid < b.aid; }); auto duplicates = std::adjacent_find(actors.begin(), actors.end(), @@ -80,9 +83,19 @@ bool run_build_level(const std::string& input_file, pc_level.level_name = file.name; // TFRAG - auto& tfrag_drawable_tree = file.drawable_trees.tfrags.emplace_back(); - tfrag_from_gltf(mesh_extract_out.tfrag, tfrag_drawable_tree, - pc_level.tfrag_trees[0].emplace_back()); + file.drawable_trees.tfrags.emplace_back("drawable-tree-tfrag", "drawable-inline-array-tfrag"); + file.drawable_trees.tfrags.emplace_back("drawable-tree-trans-tfrag", + "drawable-inline-array-trans-tfrag"); + + tfrag_from_gltf(mesh_extract_out.tfrag, pc_level.tfrag_trees[0]); + + // TIE + if (!mesh_extract_out.tie.base_draws.empty()) { + file.drawable_trees.ties.emplace_back(); + tie_from_gltf(mesh_extract_out.tie, pc_level.tie_trees[0]); + } + + // TEXTURE pc_level.textures = std::move(tex_pool.textures_by_idx); // COLLIDE @@ -92,15 +105,27 @@ bool run_build_level(const std::string& input_file, auto& collide_drawable_tree = file.drawable_trees.collides.emplace_back(); collide_drawable_tree.bvh = collide::construct_collide_bvh(mesh_extract_out.collide.faces); collide_drawable_tree.packed_frags = pack_collide_frags(collide_drawable_tree.bvh.frags.frags); + // for collision renderer + for (auto& face : mesh_extract_out.collide.faces) { + math::Vector4f verts[3]; + for (int i = 0; i < 3; i++) { + verts[i].x() = face.v[i].x(); + verts[i].y() = face.v[i].y(); + verts[i].z() = face.v[i].z(); + verts[i].w() = 1.f; + } + tfrag3::CollisionMesh::Vertex out_verts[3]; + decompiler::set_vertices_for_tri(out_verts, verts); + for (auto& out : out_verts) { + out.pat = face.pat.val; + pc_level.collision.vertices.push_back(out); + } + } } - // Save the GOAL level - auto result = file.save_object_file(); - lg::print("Level bsp file size {} bytes\n", result.size()); - auto save_path = file_util::get_jak_project_dir() / bsp_output_file; - file_util::create_dir_if_needed_for_file(save_path); - lg::print("Saving to {}\n", save_path.string()); - file_util::write_binary_file(save_path, result.data(), result.size()); + auto sky_name = level_json.value("sky", "none"); + auto texture_remap = level_json.value("tex_remap", "none"); + auto tpages = level_json.value("tpages", std::vector({})); // Add textures and models // TODO remove hardcoded config settings @@ -151,20 +176,64 @@ bool run_build_level(const std::string& input_file, std::vector processed_art_groups; - // find all art groups used by the custom level in other dgos - if (level_json.contains("art_groups") && !level_json.at("art_groups").empty()) { + // find all art groups used by the custom level in other dgos and extract sky and texture remap + // if desired + auto should_process_art_groups = + (level_json.contains("art_groups") && !level_json.at("art_groups").empty()) || + (sky_name != "none" || texture_remap != "none"); + if (should_process_art_groups) { for (auto& dgo : config.dgo_names) { // remove "DGO/" prefix const auto& dgo_name = dgo.substr(4); const auto& files = db.obj_files_by_dgo.at(dgo_name); auto art_groups = find_art_groups(processed_art_groups, - level_json.at("art_groups").get>(), files); - auto tex_remap = decompiler::extract_tex_remap(db, dgo_name); + level_json.value("art_groups", std::vector{}), files); + std::vector tex_remap{}; + if (auto bsp = get_bsp_file(files, dgo_name)) { + const auto& link_data = db.lookup_record(bsp.value()).linked_data; + if (is_valid_bsp(link_data)) { + level_tools::BspHeader level_file; + level_file.read_from_file(link_data, dts, GameVersion::Jak1, true); + auto bsp_name = bsp.value().name.substr(0, bsp.value().name.size() - 4); + tex_remap = level_file.texture_remap_table; + auto is_sky_bsp = bsp_name == sky_name; + auto is_tex_remap_bsp = bsp_name == texture_remap; + auto sky_and_tex_remap_same = sky_name == texture_remap; + if (is_tex_remap_bsp) { + lg::info("custom level: copying texture remap data from {}", texture_remap); + // copy texture remap data from bsp + file.texture_remap_table.resize(tex_remap.size()); + memcpy(file.texture_remap_table.data(), level_file.texture_remap_table.data(), + tex_remap.size() * sizeof(level_tools::TextureRemap)); + } + if (is_sky_bsp) { + // copy adgif data from bsp + lg::info("custom level: copying adgifs from {}", sky_name); + auto& adgifs = file.adgifs.adgifs; + adgifs.resize(level_file.adgifs.adgifs.size()); + memcpy(adgifs.data(), level_file.adgifs.adgifs.data(), + level_file.adgifs.adgifs.size() * sizeof(AdGifData)); + } + if (sky_and_tex_remap_same && is_sky_bsp && is_tex_remap_bsp && tpages.empty()) { + // if tpages json is empty and sky and tex remap are the same level, auto fill + file.texture_ids.resize(level_file.texture_page_count); + memcpy(file.texture_ids.data(), level_file.texture_ids.data(), + sizeof(u32) * level_file.texture_page_count); + std::vector tex_ids; + tex_ids.reserve(level_file.texture_page_count); + for (auto& id : level_file.texture_ids) { + tex_ids.push_back(id >> 20); + } + lg::info("custom level: login tpages automatically set to [{}]", + fmt::join(tex_ids, ", ")); + } + } + } for (const auto& ag : art_groups) { if (ag.name.length() > 3 && !ag.name.compare(ag.name.length() - 3, 3, "-ag")) { const auto& ag_file = db.lookup_record(ag); - lg::print("custom level: extracting art group {}\n", ag_file.name_in_dgo); + lg::info("custom level: extracting art group {}", ag_file.name_in_dgo); decompiler::extract_merc(ag_file, tex_db, db.dts, tex_remap, pc_level, false, db.version()); } @@ -174,31 +243,69 @@ bool run_build_level(const std::string& input_file, // add textures if (level_json.contains("textures") && !level_json.at("textures").empty()) { - std::vector processed_textures; - std::vector wanted_texs = - level_json.at("textures").get>(); + std::map> processed_textures; + auto tex_json = level_json.value("textures", std::vector>{}); + std::map> wanted_texs; + for (auto& arr : tex_json) { + auto tpage_name = arr[0]; + // we only want a select few textures + if (arr.size() > 1) { + for (size_t i = 1; i < arr.size(); i++) { + wanted_texs.insert({tpage_name, {arr.begin() + 1, arr.end()}}); + } + } else { + // we want all textures from this tpage + auto it = std::find_if(tex_db.tpage_names.begin(), tex_db.tpage_names.end(), + [tpage_name](const std::pair& t) { + return t.second == tpage_name; + }); + if (it != tex_db.tpage_names.end()) { + lg::info("custom level: adding all textures from tpage {}:", tpage_name); + std::vector tex_names; + for (auto& [id, tex] : tex_db.textures) { + if (tex_db.tpage_names.at(tex.page) == tpage_name) { + lg::info("custom level: adding texture {} (tpage {})", tex.name, tex.page); + tex_names.push_back(tex.name); + pc_level.textures.push_back(make_texture(id, tex, tpage_name, true)); + processed_textures[tpage_name].push_back(tex.name); + } + } + wanted_texs.insert({tpage_name, tex_names}); + } + } + } + // first check the texture is not already in the level for (auto& level_tex : pc_level.textures) { - if (std::find(wanted_texs.begin(), wanted_texs.end(), level_tex.debug_name) != - wanted_texs.end()) { - processed_textures.push_back(level_tex.debug_name); + auto tpage = level_tex.debug_tpage_name; + auto name = level_tex.debug_name; + auto it = std::find_if( + wanted_texs.begin(), wanted_texs.end(), + [tpage, name](const std::pair>& elt) { + return elt.first == tpage && + std::find(elt.second.begin(), elt.second.end(), name) != elt.second.end(); + }); + if (it != wanted_texs.end()) { + processed_textures[level_tex.debug_tpage_name].push_back(level_tex.debug_name); } } // then add for (auto& [id, tex] : tex_db.textures) { - for (auto& tex0 : wanted_texs) { - if (std::find(processed_textures.begin(), processed_textures.end(), tex.name) != - processed_textures.end()) { + auto db_tpage_name = tex_db.tpage_names.at(tex.page); + for (auto& [wanted_tpage_name, wanted_tex_list] : wanted_texs) { + auto processed = processed_textures[db_tpage_name]; + if (std::find(processed.begin(), processed.end(), tex.name) != processed.end()) { + // lg::info("custom level: ignoring duplicate texture {} from {}", tex.name, tex.page); continue; } - if (tex.name == tex0) { - lg::info("custom level: adding texture {} from tpage {} ({})", tex.name, tex.page, - tex_db.tpage_names.at(tex.page)); - pc_level.textures.push_back( - make_texture(id, tex, tex_db.tpage_names.at(tex.page), true)); - processed_textures.push_back(tex.name); - } + for (auto& wanted_tex : wanted_tex_list) + if (db_tpage_name == wanted_tpage_name && tex.name == wanted_tex) { + lg::info("custom level: adding texture {} from tpage {} ({})", tex.name, tex.page, + db_tpage_name); + pc_level.textures.push_back(make_texture(id, tex, db_tpage_name, true)); + processed_textures[db_tpage_name].push_back(tex.name); + } } } } @@ -212,6 +319,14 @@ bool run_build_level(const std::string& input_file, } } + // Save the GOAL level + auto result = file.save_object_file(); + lg::print("Level bsp file size {} bytes\n", result.size()); + auto save_path = file_util::get_jak_project_dir() / bsp_output_file; + file_util::create_dir_if_needed_for_file(save_path); + lg::print("Saving to {}\n", save_path.string()); + file_util::write_binary_file(save_path, result.data(), result.size()); + // Save the PC level save_pc_data(file.name, pc_level, file_util::get_jak_project_dir() / "out" / output_prefix / "fr3"); diff --git a/goalc/build_level/jak2/build_level.cpp b/goalc/build_level/jak2/build_level.cpp index e7ddfddfbc..7ab7db5bd7 100644 --- a/goalc/build_level/jak2/build_level.cpp +++ b/goalc/build_level/jak2/build_level.cpp @@ -69,9 +69,8 @@ bool run_build_level(const std::string& input_file, pc_level.level_name = file.name; // TFRAG - auto& tfrag_drawable_tree = file.drawable_trees.tfrags.emplace_back(); - tfrag_from_gltf(mesh_extract_out.tfrag, tfrag_drawable_tree, - pc_level.tfrag_trees[0].emplace_back()); + file.drawable_trees.tfrags.emplace_back("drawable-tree-tfrag", "drawable-inline-array-tfrag"); + tfrag_from_gltf(mesh_extract_out.tfrag, pc_level.tfrag_trees[0]); pc_level.textures = std::move(tex_pool.textures_by_idx); // COLLIDE diff --git a/goalc/build_level/jak3/build_level.cpp b/goalc/build_level/jak3/build_level.cpp index f90096b31d..57185b736b 100644 --- a/goalc/build_level/jak3/build_level.cpp +++ b/goalc/build_level/jak3/build_level.cpp @@ -67,9 +67,8 @@ bool run_build_level(const std::string& input_file, pc_level.level_name = file.name; // TFRAG - auto& tfrag_drawable_tree = file.drawable_trees.tfrags.emplace_back(); - tfrag_from_gltf(mesh_extract_out.tfrag, tfrag_drawable_tree, - pc_level.tfrag_trees[0].emplace_back()); + file.drawable_trees.tfrags.emplace_back("drawable-tree-tfrag", "drawable-inline-array-tfrag"); + tfrag_from_gltf(mesh_extract_out.tfrag, pc_level.tfrag_trees[0]); pc_level.textures = std::move(tex_pool.textures_by_idx); // COLLIDE diff --git a/goalc/data_compiler/game_text_common.cpp b/goalc/data_compiler/game_text_common.cpp index 6e2e015a99..1282af22a4 100644 --- a/goalc/data_compiler/game_text_common.cpp +++ b/goalc/data_compiler/game_text_common.cpp @@ -171,7 +171,11 @@ void compile_subtitles_v2(GameSubtitleDB& db, const std::string& output_prefix) for (const auto& [lang, bank] : db.m_banks) { auto font = get_font_bank(bank->m_text_version); DataObjectGenerator gen; - gen.add_type_tag("subtitle2-text-info"); // type + if (get_text_version_name(bank->m_text_version) == "jak3") { + gen.add_type_tag("subtitle3-text-info"); // type + } else { + gen.add_type_tag("subtitle2-text-info"); // type + } gen.add_word((bank->m_scenes.size() & 0xffff) | (1 << 16)); // length (lo) + version (hi) // note: we add 1 because "none" isn't included gen.add_word((lang & 0xffff) | ((bank->m_speakers.size() + 1) << 16)); // lang + speaker-length @@ -220,9 +224,10 @@ void compile_subtitles_v2(GameSubtitleDB& db, const std::string& output_prefix) auto data = gen.generate_v2(); file_util::create_dir_if_needed(file_util::get_file_path({"out", output_prefix, "iso"})); + auto file_name = get_text_version_name(bank->m_text_version) == "jak3" ? "subti3" : "subti2"; file_util::write_binary_file( file_util::get_file_path( - {"out", output_prefix, "iso", fmt::format("{}{}.TXT", lang, uppercase("subti2"))}), + {"out", output_prefix, "iso", fmt::format("{}{}.TXT", lang, uppercase(file_name))}), data.data(), data.size()); } } diff --git a/goalc/main.cpp b/goalc/main.cpp index c5ec7c8d3b..77fe79bfbd 100644 --- a/goalc/main.cpp +++ b/goalc/main.cpp @@ -37,6 +37,7 @@ int main(int argc, char** argv) { std::string game = "jak1"; int nrepl_port = -1; fs::path project_path_override; + fs::path iso_path_override; // TODO - a lot of these flags could be deprecated and moved into `repl-config.json` CLI::App app{"OpenGOAL Compiler / REPL"}; @@ -49,6 +50,7 @@ int main(int argc, char** argv) { app.add_option("-g,--game", game, "The game name: 'jak1' or 'jak2'"); app.add_option("--proj-path", project_path_override, "Specify the location of the 'data/' folder"); + app.add_option("--iso-path", iso_path_override, "Specify the location of the 'iso_data/' folder"); define_common_cli_arguments(app); app.validate_positionals(); CLI11_PARSE(app, argc, argv); @@ -84,6 +86,16 @@ int main(int argc, char** argv) { // Load the user's REPL config auto repl_config = REPL::load_repl_config(username, game_version, nrepl_port); + // Check for a custom ISO path before we instantiate the compiler. + if (!iso_path_override.empty()) { + if (!fs::exists(iso_path_override)) { + lg::error("Error: iso path override '{}' does not exist", iso_path_override.string()); + return 1; + } + file_util::set_iso_data_dir(iso_path_override); + repl_config.iso_path = iso_path_override.string(); + } + // Init Compiler std::unique_ptr compiler; std::mutex compiler_mutex; diff --git a/goalc/make/MakeSystem.cpp b/goalc/make/MakeSystem.cpp index 982e8e3dd6..dfa29b7d0e 100644 --- a/goalc/make/MakeSystem.cpp +++ b/goalc/make/MakeSystem.cpp @@ -91,8 +91,14 @@ MakeSystem::MakeSystem(const std::optional repl_config, const std: m_goos.set_global_variable_to_symbol("ASSETS", "#t"); - set_constant("*iso-data*", file_util::get_file_path({"iso_data"})); - set_constant("*use-iso-data-path*", false); + if (m_repl_config && !m_repl_config->iso_path.empty()) { + set_constant("*iso-data*", + file_util::get_iso_dir_for_game(m_repl_config->game_version).string()); + set_constant("*use-iso-data-path*", true); + } else { + set_constant("*iso-data*", file_util::get_file_path({"iso_data"})); + set_constant("*use-iso-data-path*", false); + } add_tool(); add_tool(); diff --git a/goalc/make/MakeSystem.h b/goalc/make/MakeSystem.h index cba37ebf77..1eef3174b6 100644 --- a/goalc/make/MakeSystem.h +++ b/goalc/make/MakeSystem.h @@ -1,6 +1,7 @@ #pragma once #include "common/goos/Interpreter.h" +#include "common/util/FileUtil.h" #include "goalc/make/Tool.h" diff --git a/iso_data/jak2/.gitignore b/iso_data/jak2/.gitignore new file mode 100644 index 0000000000..d6b7ef32c8 --- /dev/null +++ b/iso_data/jak2/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/iso_data/jak3/.gitignore b/iso_data/jak3/.gitignore new file mode 100644 index 0000000000..d6b7ef32c8 --- /dev/null +++ b/iso_data/jak3/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/out/build/Release/bin/decompiler.exe b/out/build/Release/bin/decompiler.exe index 9d3a75fe55..f5edef288d 100644 Binary files a/out/build/Release/bin/decompiler.exe and b/out/build/Release/bin/decompiler.exe differ diff --git a/out/build/Release/bin/extractor.exe b/out/build/Release/bin/extractor.exe index 5abf10ab5f..39c101d3b3 100644 Binary files a/out/build/Release/bin/extractor.exe and b/out/build/Release/bin/extractor.exe differ diff --git a/out/build/Release/bin/gk.exe b/out/build/Release/bin/gk.exe index 637cf6cab7..4d399bd234 100644 Binary files a/out/build/Release/bin/gk.exe and b/out/build/Release/bin/gk.exe differ diff --git a/out/build/Release/bin/goalc.exe b/out/build/Release/bin/goalc.exe index fd4eab4b16..8fbe62f2cb 100644 Binary files a/out/build/Release/bin/goalc.exe and b/out/build/Release/bin/goalc.exe differ diff --git a/scripts/ci/lint-characters.py b/scripts/ci/lint-characters.py index 9cac77b1d6..d6b47fbb07 100644 --- a/scripts/ci/lint-characters.py +++ b/scripts/ci/lint-characters.py @@ -47,7 +47,9 @@ "!": "!", "(": "(", ")": ")", - "。": "." + "。": ".", + "×": "x", + "?": "?" } # TODO - check for korean text @@ -94,7 +96,9 @@ "(": "(", ")": ")", "〜": "~", - "。": "." + "。": ".", + "×": "x", + "?": "?" } # fmt: on diff --git a/scripts/tasks/Taskfile_darwin.yml b/scripts/tasks/Taskfile_darwin.yml index 3ce6d2cab1..4982077bf9 100644 --- a/scripts/tasks/Taskfile_darwin.yml +++ b/scripts/tasks/Taskfile_darwin.yml @@ -10,3 +10,4 @@ vars: GOALCTEST_BIN_RELEASE_DIR: './build' FORMATTER_BIN_RELEASE_DIR: './build/tools' EXE_FILE_EXTENSION: '' + PYTHON: 'python3' diff --git a/scripts/tasks/Taskfile_linux.yml b/scripts/tasks/Taskfile_linux.yml index 3ce6d2cab1..4982077bf9 100644 --- a/scripts/tasks/Taskfile_linux.yml +++ b/scripts/tasks/Taskfile_linux.yml @@ -10,3 +10,4 @@ vars: GOALCTEST_BIN_RELEASE_DIR: './build' FORMATTER_BIN_RELEASE_DIR: './build/tools' EXE_FILE_EXTENSION: '' + PYTHON: 'python3' diff --git a/scripts/tasks/Taskfile_windows.yml b/scripts/tasks/Taskfile_windows.yml index f47cb37161..2aa17c3d77 100644 --- a/scripts/tasks/Taskfile_windows.yml +++ b/scripts/tasks/Taskfile_windows.yml @@ -10,3 +10,4 @@ vars: GOALCTEST_BIN_RELEASE_DIR: './out/build/Release/bin' FORMATTER_BIN_RELEASE_DIR: './out/build/Release/bin' EXE_FILE_EXTENSION: '.exe' + PYTHON: 'python' diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 112d575149..1eaf63f62c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -39,6 +39,9 @@ add_executable(goalc-test target_link_libraries(goalc-test common runtime compiler gtest decomp Zydis libzstd_static tree-sitter) +add_executable(test_image_resize ${CMAKE_CURRENT_LIST_DIR}/common/test_image_resize.cpp) +target_link_libraries(test_image_resize common) + if(WIN32) target_link_libraries(goalc-test mman) endif() diff --git a/test/common/test_image_resize.cpp b/test/common/test_image_resize.cpp new file mode 100644 index 0000000000..bbf67d48b4 --- /dev/null +++ b/test/common/test_image_resize.cpp @@ -0,0 +1,37 @@ +#include +#include + +#include "common/common_types.h" +#include "common/util/FileUtil.h" +#include "common/util/Timer.h" +#include "common/util/image_resize.h" + +int main() { + int src_h = 30; + int src_w = 30; + int check_divide = 3; + int dst_sz = 300; + + std::vector src; + for (int h = 0; h < src_h; h++) { + for (int w = 0; w < src_w; w++) { + u8 color = (((h / check_divide) & 1) ^ ((w / check_divide) & 1)) ? 0x10 : 0xd0; + src.push_back(color); + src.push_back(color); + src.push_back(color); + src.push_back(255); + } + } + + std::vector dst(dst_sz * dst_sz * 4); + Timer timer; + resize_rgba_image(dst.data(), dst_sz, dst_sz, src.data(), src_w, src_h, true, true); + printf("resized in %.3f ms\n", timer.getMs()); + file_util::write_rgba_png("test_wrap.png", dst.data(), dst_sz, dst_sz); + resize_rgba_image(dst.data(), dst_sz, dst_sz, src.data(), src_w, src_h, false, false); + printf("resized in %.3f ms\n", timer.getMs()); + file_util::write_rgba_png("test_unwrap.png", dst.data(), dst_sz, dst_sz); + file_util::write_rgba_png("src.png", src.data(), src_w, src_h); + + return 0; +} \ No newline at end of file diff --git a/test/decompiler/reference/jak1/decompiler-macros.gc b/test/decompiler/reference/jak1/decompiler-macros.gc index b8edeecb9b..928e8f7302 100644 --- a/test/decompiler/reference/jak1/decompiler-macros.gc +++ b/test/decompiler/reference/jak1/decompiler-macros.gc @@ -523,6 +523,13 @@ ) ) +(defmacro call-parent-state-handler (handler &key (type (function none)) &rest args) + "Call the parent handler for this state." + `(let ((handler (-> (find-parent-state) ,handler))) + (if handler ((the ,type handler) ,@args)) + ) + ) + (defmacro call-parent-method (&rest args) "Find the first different implementation of the current method in a parent type and call it with these arguments." `((the (current-method-function-type) (find-parent-method (current-method-type) (current-method-id))) @@ -1699,4 +1706,7 @@ (defmacro time-elapsed? (time duration) `(>= (- (current-time) ,time) ,duration) - ) \ No newline at end of file + ) + +(defmacro suspend-for (time &rest body) + `(let ((time (current-time))) (until (time-elapsed? time ,time) ,@body (suspend)))) \ No newline at end of file diff --git a/test/decompiler/reference/jak1/engine/common-obs/crates_REF.gc b/test/decompiler/reference/jak1/engine/common-obs/crates_REF.gc index b637bc02bb..297e3103b1 100644 --- a/test/decompiler/reference/jak1/engine/common-obs/crates_REF.gc +++ b/test/decompiler/reference/jak1/engine/common-obs/crates_REF.gc @@ -855,10 +855,7 @@ (logior! (-> self fact options) (fact-options instant-collect)) ) (when (not arg0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.04)) - (suspend) - ) + (suspend-for (seconds 0.04) ) (logior! (-> self draw status) (draw-status hidden)) (case (-> self look) @@ -946,10 +943,7 @@ (drop-pickup (-> self fact) #t *entity-pool* (the-as fact-info #f) arg1) (process-entity-status! self (entity-perm-status dead) #t) (process-entity-status! self (entity-perm-status complete) #t) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) ) ) diff --git a/test/decompiler/reference/jak1/engine/common-obs/generic-obs_REF.gc b/test/decompiler/reference/jak1/engine/common-obs/generic-obs_REF.gc index e0185e847c..91210935ad 100644 --- a/test/decompiler/reference/jak1/engine/common-obs/generic-obs_REF.gc +++ b/test/decompiler/reference/jak1/engine/common-obs/generic-obs_REF.gc @@ -115,10 +115,7 @@ (while (and *target* (= (handle->process (-> *target* control unknown-handle10)) self)) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (go swingpole-stance) ) @@ -641,13 +638,10 @@ ) (suspend) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (-> self linger-duration)) - (if (-> self linger-callback) - ((-> self linger-callback) self) - ) - (suspend) - ) + (suspend-for (-> self linger-duration) + (if (-> self linger-callback) + ((-> self linger-callback) self) + ) ) (if (-> self linger-callback) ((-> self linger-callback) self) @@ -1016,11 +1010,8 @@ (set! gp-0 (not (eval this (the-as pair (car s4-0))))) ) (('wait-for 'wait 'suspend) - (let ((s5-1 (command-get-time (car s4-0) 1)) - (s4-1 (current-time)) - ) - (until (time-elapsed? s4-1 s5-1) - (suspend) + (let ((s5-1 (command-get-time (car s4-0) 1))) + (suspend-for s5-1 ) ) ) diff --git a/test/decompiler/reference/jak1/engine/common-obs/nav-enemy_REF.gc b/test/decompiler/reference/jak1/engine/common-obs/nav-enemy_REF.gc index 233b60f365..3fc108d66d 100644 --- a/test/decompiler/reference/jak1/engine/common-obs/nav-enemy_REF.gc +++ b/test/decompiler/reference/jak1/engine/common-obs/nav-enemy_REF.gc @@ -1697,12 +1697,9 @@ nav-enemy-default-event-handler ) (ja-channel-push! 1 (seconds 0.1)) (nav-enemy-turn-to-face-point (-> self event-param-point) 910.2222) - (let ((gp-0 (nav-enemy-rnd-int-range 0 150)) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 gp-0) + (let ((gp-0 (nav-enemy-rnd-int-range 0 150))) + (suspend-for gp-0 (ja :num! (loop! f30-0)) - (suspend) ) ) ) diff --git a/test/decompiler/reference/jak1/engine/entity/ambient_REF.gc b/test/decompiler/reference/jak1/engine/entity/ambient_REF.gc index 4cc0f82d22..ebe3eeebc9 100644 --- a/test/decompiler/reference/jak1/engine/entity/ambient_REF.gc +++ b/test/decompiler/reference/jak1/engine/entity/ambient_REF.gc @@ -596,27 +596,24 @@ :event (-> level-hint-normal event) :code (behavior ((arg0 string) (arg1 string)) (remove-setting! 'hint) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 (seconds 1)) - (when (and *debug-segment* (not (paused?)) (not (str-is-playing?)) (bottom-hud-hidden?)) - (let ((s3-0 - (new 'stack 'font-context *font-default-matrix* 56 160 0.0 (font-color default) (font-flags shadow kerning)) - ) + (suspend-for (seconds 1) + (when (and *debug-segment* (not (paused?)) (not (str-is-playing?)) (bottom-hud-hidden?)) + (let ((s3-0 + (new 'stack 'font-context *font-default-matrix* 56 160 0.0 (font-color default) (font-flags shadow kerning)) ) - (let ((v1-7 s3-0)) - (set! (-> v1-7 width) (the float 400)) - ) - (let ((v1-8 s3-0)) - (set! (-> v1-8 height) (the float 96)) - ) - (set! (-> s3-0 flags) (font-flags shadow kerning middle)) - (let ((s2-0 print-game-text)) - (format (clear *temp-string*) "~S~S" arg0 arg1) - (s2-0 *temp-string* s3-0 #f 128 22) ) + (let ((v1-7 s3-0)) + (set! (-> v1-7 width) (the float 400)) + ) + (let ((v1-8 s3-0)) + (set! (-> v1-8 height) (the float 96)) + ) + (set! (-> s3-0 flags) (font-flags shadow kerning middle)) + (let ((s2-0 print-game-text)) + (format (clear *temp-string*) "~S~S" arg0 arg1) + (s2-0 *temp-string* s3-0 #f 128 22) ) ) - (suspend) ) ) (go level-hint-exit) diff --git a/test/decompiler/reference/jak1/engine/game/game-info_REF.gc b/test/decompiler/reference/jak1/engine/game/game-info_REF.gc index 6691a674ed..f2883a572f 100644 --- a/test/decompiler/reference/jak1/engine/game/game-info_REF.gc +++ b/test/decompiler/reference/jak1/engine/game/game-info_REF.gc @@ -637,11 +637,8 @@ (process-spawn-function process (lambda ((arg0 process-drawable)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.6)) - (send-event arg0 'effect 'eco-blue) - (suspend) - ) + (suspend-for (seconds 0.6) + (send-event arg0 'effect 'eco-blue) ) (none) ) diff --git a/test/decompiler/reference/jak1/engine/game/main_REF.gc b/test/decompiler/reference/jak1/engine/game/main_REF.gc index e065c4fc34..50385940ae 100644 --- a/test/decompiler/reference/jak1/engine/game/main_REF.gc +++ b/test/decompiler/reference/jak1/engine/game/main_REF.gc @@ -912,10 +912,7 @@ (set! (-> *setting-control* default music-volume) 0.0) (set! (-> *setting-control* default dialog-volume) 0.0) (set! (-> *setting-control* default ambient-volume) 0.0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (kernel-shutdown) (none) diff --git a/test/decompiler/reference/jak1/engine/game/powerups_REF.gc b/test/decompiler/reference/jak1/engine/game/powerups_REF.gc index 7f3e8e7135..0f4f1f6800 100644 --- a/test/decompiler/reference/jak1/engine/game/powerups_REF.gc +++ b/test/decompiler/reference/jak1/engine/game/powerups_REF.gc @@ -15,25 +15,22 @@ (let ((s1-1 (process->handle arg0)) (s2-1 (process->handle arg1)) ) - (let ((s0-0 (current-time))) - (until (time-elapsed? s0-0 (+ arg3 arg4)) - (let ((v1-8 (or (not (handle->process s1-1)) (not (handle->process s2-1))))) - (if v1-8 - (deactivate self) - ) - ) - (let* ((f0-1 (fmax 0.0 (fmin 1.0 (/ (- (the float (- (current-time) s0-0)) (the float arg3)) (the float arg4))))) - (a0-18 (process-drawable-pair-random-point! - (the-as process-drawable (-> s1-1 process 0)) - (the-as process-drawable (-> s2-1 process 0)) - (new-stack-vector0) - f0-1 - ) + (suspend-for (+ arg3 arg4) + (let ((v1-8 (or (not (handle->process s1-1)) (not (handle->process s2-1))))) + (if v1-8 + (deactivate self) + ) + ) + (let* ((f0-1 (fmax 0.0 (fmin 1.0 (/ (- (the float (- (current-time) time)) (the float arg3)) (the float arg4))))) + (a0-18 (process-drawable-pair-random-point! + (the-as process-drawable (-> s1-1 process 0)) + (the-as process-drawable (-> s2-1 process 0)) + (new-stack-vector0) + f0-1 ) - ) - (arg2 a0-18) - ) - (suspend) + ) + ) + (arg2 a0-18) ) ) (cond @@ -43,12 +40,9 @@ ) ) (else - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 arg5) - (let ((a0-21 (process-drawable-random-point! (the-as process-drawable (-> s2-1 process 0)) (new-stack-vector0)))) - (arg2 a0-21) - ) - (suspend) + (suspend-for arg5 + (let ((a0-21 (process-drawable-random-point! (the-as process-drawable (-> s2-1 process 0)) (new-stack-vector0)))) + (arg2 a0-21) ) ) ) diff --git a/test/decompiler/reference/jak1/engine/target/target-death_REF.gc b/test/decompiler/reference/jak1/engine/target/target-death_REF.gc index 8f1fc0ea5b..c3b94327da 100644 --- a/test/decompiler/reference/jak1/engine/target/target-death_REF.gc +++ b/test/decompiler/reference/jak1/engine/target/target-death_REF.gc @@ -251,10 +251,7 @@ ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (until (not v1-10) (suspend) @@ -427,10 +424,7 @@ ) ) (else - (let ((s5-7 (current-time))) - (until (time-elapsed? s5-7 (seconds 0.05)) - (suspend) - ) + (suspend-for (seconds 0.05) ) ) ) @@ -887,10 +881,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-known-safe-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (move-to-point! (-> self control) s4-1) ) @@ -1040,10 +1031,7 @@ (-> self attack-info attacker) (ja-channel-set! 0) (ja-post) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) ) (('drown 'drown-death) @@ -1118,10 +1106,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) (('endlessfall) @@ -1180,11 +1165,8 @@ (target-falling-anim (seconds 0.1) (seconds 0.33)) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! eichar-launch-jump-loop-ja :num! (loop! 0.5) :frame-num 0.0) - (let ((gp-12 (current-time))) - (until (time-elapsed? gp-12 (seconds 0.8)) - (ja :group! eichar-launch-jump-loop-ja :num! (loop! 0.5)) - (suspend) - ) + (suspend-for (seconds 0.8) + (ja :group! eichar-launch-jump-loop-ja :num! (loop! 0.5)) ) (camera-change-to (the-as string 'base) 0 #f) ) diff --git a/test/decompiler/reference/jak1/engine/target/target2_REF.gc b/test/decompiler/reference/jak1/engine/target/target2_REF.gc index 6bfab8884e..4d3f80d24c 100644 --- a/test/decompiler/reference/jak1/engine/target/target2_REF.gc +++ b/test/decompiler/reference/jak1/engine/target/target2_REF.gc @@ -28,12 +28,9 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.3)) - (suspend) - (ja :num! (seek! (ja-aframe (the-as float 19.0) 0) 0.05)) - (suspend) - ) + (suspend-for (seconds 0.3) + (suspend) + (ja :num! (seek! (ja-aframe (the-as float 19.0) 0) 0.05)) ) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! eichar-painful-land-ja :num! (seek!) :frame-num (ja-aframe (the-as float 40.0) 0)) @@ -1527,10 +1524,7 @@ :to self ) (set-time! (-> self control unknown-dword82)) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (ja-no-eval :group! eichar-yellow-jumping-blast-ja :num! (seek!) :frame-num (ja-frame-num 0)) (until (ja-done? 0) diff --git a/test/decompiler/reference/jak1/levels/beach/beach-obs_REF.gc b/test/decompiler/reference/jak1/levels/beach/beach-obs_REF.gc index 48ab1cd374..b2e6be20d9 100644 --- a/test/decompiler/reference/jak1/levels/beach/beach-obs_REF.gc +++ b/test/decompiler/reference/jak1/levels/beach/beach-obs_REF.gc @@ -663,10 +663,7 @@ (set! sv-128 (the-as symbol #f)) (apply-all (-> self link) actor-link-subtask-complete-hook (& sv-128)) (when sv-128 - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (let ((gp-1 (cond (arg0 @@ -1224,10 +1221,7 @@ ) (camera-change-to "camera-135" 0 #f) (camera-look-at (the-as pair (ppointer->process (-> self parent))) (the-as uint 9)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 4)) - (suspend) - ) + (suspend-for (seconds 4) ) (while (not (process-release? (handle->process (-> self grab-target)))) (suspend) diff --git a/test/decompiler/reference/jak1/levels/beach/lurkercrab_REF.gc b/test/decompiler/reference/jak1/levels/beach/lurkercrab_REF.gc index d27440c6c5..ea88172391 100644 --- a/test/decompiler/reference/jak1/levels/beach/lurkercrab_REF.gc +++ b/test/decompiler/reference/jak1/levels/beach/lurkercrab_REF.gc @@ -222,10 +222,7 @@ nav-enemy-default-event-handler (ja-channel-push! 1 (seconds 0.075)) (loop (ja :group! lurkercrab-idle-ja :num! (identity (ja-aframe 1.0 0))) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (ja-no-eval :group! lurkercrab-idle-ja :num! (seek! (ja-aframe 19.0 0)) :frame-num (ja-aframe 1.0 0)) (until (ja-done? 0) @@ -233,10 +230,7 @@ nav-enemy-default-event-handler (ja :num! (seek! (ja-aframe 19.0 0))) ) (ja :num-func num-func-identity :frame-num (ja-aframe 19.0 0)) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (ja-no-eval :group! lurkercrab-idle-ja :num! (seek! (ja-aframe 1.0 0)) :frame-num (ja-aframe 19.0 0)) (until (ja-done? 0) @@ -306,10 +300,7 @@ nav-enemy-default-event-handler (nav-enemy-rnd-int-range 2 6) (until (not (nav-enemy-rnd-go-idle? 0.2)) (ja :group! lurkercrab-idle-ja :num! (identity (ja-aframe 1.0 0))) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) @@ -472,15 +463,9 @@ nav-enemy-default-event-handler (suspend) (ja :num! (seek! (ja-aframe 18.0 0) 0.75)) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (go-virtual nav-enemy-chase) ) diff --git a/test/decompiler/reference/jak1/levels/beach/lurkerpuppy_REF.gc b/test/decompiler/reference/jak1/levels/beach/lurkerpuppy_REF.gc index 0745f1a0e5..69e990fe26 100644 --- a/test/decompiler/reference/jak1/levels/beach/lurkerpuppy_REF.gc +++ b/test/decompiler/reference/jak1/levels/beach/lurkerpuppy_REF.gc @@ -105,13 +105,10 @@ nav-enemy-default-event-handler (ja-channel-push! 1 (seconds 0.1)) (ja :group! lurkerpuppy-idle-ja) (ja :num-func num-func-identity :frame-num 0.0) - (let ((gp-2 (rand-vu-int-range 750 900)) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 gp-2) + (let ((gp-2 (rand-vu-int-range 750 900))) + (suspend-for gp-2 (ja :num! (loop!)) (ja-blend-eval) - (suspend) ) ) ) diff --git a/test/decompiler/reference/jak1/levels/citadel/citadel-obs_REF.gc b/test/decompiler/reference/jak1/levels/citadel/citadel-obs_REF.gc index 4a40ed1d05..cc072689b4 100644 --- a/test/decompiler/reference/jak1/levels/citadel/citadel-obs_REF.gc +++ b/test/decompiler/reference/jak1/levels/citadel/citadel-obs_REF.gc @@ -1781,11 +1781,7 @@ :virtual #t :code (behavior () (process-entity-status! self (entity-perm-status complete) #t) - (let ((t9-2 (-> (find-parent-state) code))) - (if t9-2 - ((the-as (function none :behavior battlecontroller) t9-2)) - ) - ) + (call-parent-state-handler code) ) ) diff --git a/test/decompiler/reference/jak1/levels/citadel/citb-drop-plat_REF.gc b/test/decompiler/reference/jak1/levels/citadel/citb-drop-plat_REF.gc index bc869fa9ec..58f3f6ec8e 100644 --- a/test/decompiler/reference/jak1/levels/citadel/citb-drop-plat_REF.gc +++ b/test/decompiler/reference/jak1/levels/citadel/citb-drop-plat_REF.gc @@ -448,10 +448,7 @@ ) ) ) - (let ((s2-1 (current-time))) - (until (time-elapsed? s2-1 (seconds 0.12)) - (suspend) - ) + (suspend-for (seconds 0.12) ) (+! s5-0 s4-0) ) diff --git a/test/decompiler/reference/jak1/levels/common/battlecontroller_REF.gc b/test/decompiler/reference/jak1/levels/common/battlecontroller_REF.gc index 32219a2df9..0219ba6896 100644 --- a/test/decompiler/reference/jak1/levels/common/battlecontroller_REF.gc +++ b/test/decompiler/reference/jak1/levels/common/battlecontroller_REF.gc @@ -531,10 +531,7 @@ battlecontroller-default-event-handler (go-virtual battlecontroller-die) ) (when (< gp-0 (-> self target-count)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (-> self spawn-period)) - (suspend) - ) + (suspend-for (-> self spawn-period) ) (battlecontroller-spawn-creature-random-spawner) ) diff --git a/test/decompiler/reference/jak1/levels/finalboss/final-door_REF.gc b/test/decompiler/reference/jak1/levels/finalboss/final-door_REF.gc index 00bf4a2b5e..15ba3b2c14 100644 --- a/test/decompiler/reference/jak1/levels/finalboss/final-door_REF.gc +++ b/test/decompiler/reference/jak1/levels/finalboss/final-door_REF.gc @@ -409,10 +409,7 @@ ) ) ) - (let ((s1-1 (current-time))) - (until (time-elapsed? s1-1 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (when (handle->process arg1) (let ((s1-2 (handle->process arg1)) @@ -431,17 +428,11 @@ ) ) ) - (let ((s1-3 (current-time))) - (until (time-elapsed? s1-3 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (let ((v0-22 (entity-by-name "sage-finalboss-1")) (a1-26 (new 'stack-no-clear 'event-message-block)) diff --git a/test/decompiler/reference/jak1/levels/finalboss/sage-finalboss_REF.gc b/test/decompiler/reference/jak1/levels/finalboss/sage-finalboss_REF.gc index b96cb68097..0b06890ba2 100644 --- a/test/decompiler/reference/jak1/levels/finalboss/sage-finalboss_REF.gc +++ b/test/decompiler/reference/jak1/levels/finalboss/sage-finalboss_REF.gc @@ -973,10 +973,7 @@ (remove-setting! 'music) (apply-settings *setting-control*) (set-blackout-frames (seconds 0.05)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.05)) - (suspend) - ) + (suspend-for (seconds 0.05) ) (go-virtual hidden) ) diff --git a/test/decompiler/reference/jak1/levels/flut_common/flutflut_REF.gc b/test/decompiler/reference/jak1/levels/flut_common/flutflut_REF.gc index 0b77c47f3d..e467321a17 100644 --- a/test/decompiler/reference/jak1/levels/flut_common/flutflut_REF.gc +++ b/test/decompiler/reference/jak1/levels/flut_common/flutflut_REF.gc @@ -274,11 +274,8 @@ (flutflut-effect) (suspend) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (flutflut-effect) - (suspend) - ) + (suspend-for (seconds 1) + (flutflut-effect) ) (go arg0) ) diff --git a/test/decompiler/reference/jak1/levels/flut_common/target-flut_REF.gc b/test/decompiler/reference/jak1/levels/flut_common/target-flut_REF.gc index 768cb5101b..e704258d9e 100644 --- a/test/decompiler/reference/jak1/levels/flut_common/target-flut_REF.gc +++ b/test/decompiler/reference/jak1/levels/flut_common/target-flut_REF.gc @@ -1661,10 +1661,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-known-safe-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (move-to-point! (-> self control) s4-1) ) @@ -1774,35 +1771,32 @@ ) ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 1)) - (target-flut-falling-anim-trans) - (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) - (let ((s5-2 (new-stack-vector0)) - (f30-1 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) - ) - 0.0 - (vector-! - s5-2 - (-> self control transv) - (vector-float*! s5-2 (-> self control dynam gravity-normal) (the-as float f30-1)) + (suspend-for (seconds 1) + (target-flut-falling-anim-trans) + (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) + (let ((s5-2 (new-stack-vector0)) + (f30-1 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) ) - (let* ((f0-10 (vector-length s5-2)) - (f1-4 f0-10) - ) - (if (< (the-as float (-> self control unknown-uint20)) (the-as float f30-1)) - (set! f30-1 (-> self control unknown-uint20)) - ) - (vector+! - (-> self control transv) - (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f30-1)) - (vector-float*! s5-2 s5-2 (/ f0-10 f1-4)) + 0.0 + (vector-! + s5-2 + (-> self control transv) + (vector-float*! s5-2 (-> self control dynam gravity-normal) (the-as float f30-1)) + ) + (let* ((f0-10 (vector-length s5-2)) + (f1-4 f0-10) + ) + (if (< (the-as float (-> self control unknown-uint20)) (the-as float f30-1)) + (set! f30-1 (-> self control unknown-uint20)) ) + (vector+! + (-> self control transv) + (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f30-1)) + (vector-float*! s5-2 s5-2 (/ f0-10 f1-4)) ) ) - (target-flut-post-post) - (suspend) ) + (target-flut-post-post) ) (camera-change-to (the-as string 'base) 0 #f) ) diff --git a/test/decompiler/reference/jak1/levels/jungle/darkvine_REF.gc b/test/decompiler/reference/jak1/levels/jungle/darkvine_REF.gc index 220bf176b5..e3c9a80a69 100644 --- a/test/decompiler/reference/jak1/levels/jungle/darkvine_REF.gc +++ b/test/decompiler/reference/jak1/levels/jungle/darkvine_REF.gc @@ -221,10 +221,7 @@ (ja :num! (seek!)) ) (ja-channel-set! 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (process-spawn part-tracker @@ -237,10 +234,7 @@ (-> self root trans) :to *entity-pool* ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (set! (-> self dangerous) #t) (logior! (-> self mask) (process-mask actor-pause)) diff --git a/test/decompiler/reference/jak1/levels/jungle/fisher_REF.gc b/test/decompiler/reference/jak1/levels/jungle/fisher_REF.gc index 53e5912428..8da3a8e270 100644 --- a/test/decompiler/reference/jak1/levels/jungle/fisher_REF.gc +++ b/test/decompiler/reference/jak1/levels/jungle/fisher_REF.gc @@ -1392,10 +1392,7 @@ ) (process-spawn-function process (lambda :behavior process () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (ambient-hint-spawn "st-lose" (the-as vector #f) *entity-pool* 'stinger) (none) @@ -1812,11 +1809,7 @@ (fisher-fish-water gp-0 (+ 32768.0 (vector-y-angle (-> self node-list data 80 bone transform vector 1)))) ) ) - (let ((t9-14 (-> (find-parent-state) trans))) - (if t9-14 - (t9-14) - ) - ) + (call-parent-state-handler trans) ) ) @@ -1824,11 +1817,7 @@ (defstate idle (fisher) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (when (task-complete? *game-info* (-> self entity extra perm task)) (when (nonzero? (-> *cpad-list* cpads 0 button0-rel 0)) (let ((v1-9 (-> self cheat-temp))) diff --git a/test/decompiler/reference/jak1/levels/jungle/jungle-elevator_REF.gc b/test/decompiler/reference/jak1/levels/jungle/jungle-elevator_REF.gc index c27c2f916a..56e5cf099f 100644 --- a/test/decompiler/reference/jak1/levels/jungle/jungle-elevator_REF.gc +++ b/test/decompiler/reference/jak1/levels/jungle/jungle-elevator_REF.gc @@ -52,11 +52,7 @@ (gp-0 (new 'stack-no-clear 'vector)) ) (set! (-> s5-0 quad) (-> self root trans quad)) - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (vector-! gp-0 (-> self root trans) s5-0) (when (< (-> self path-pos) 0.9) (move-by-vector! (-> *target* control) gp-0) diff --git a/test/decompiler/reference/jak1/levels/jungle/jungle-mirrors_REF.gc b/test/decompiler/reference/jak1/levels/jungle/jungle-mirrors_REF.gc index 4fa5501cad..5ff757bc31 100644 --- a/test/decompiler/reference/jak1/levels/jungle/jungle-mirrors_REF.gc +++ b/test/decompiler/reference/jak1/levels/jungle/jungle-mirrors_REF.gc @@ -1964,10 +1964,7 @@ (let ((v1-11 (manipy-spawn (-> self root trans) (-> self entity) *reflector-mirror-break-sg* #f :to self))) (send-event (ppointer->process v1-11) 'anim-mode 'play1) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (process-grab? *target*) (while (or (-> self child) (-> *setting-control* current ambient)) diff --git a/test/decompiler/reference/jak1/levels/jungleb/jungleb-obs_REF.gc b/test/decompiler/reference/jak1/levels/jungleb/jungleb-obs_REF.gc index 896ba313c3..4e9bce5b92 100644 --- a/test/decompiler/reference/jak1/levels/jungleb/jungleb-obs_REF.gc +++ b/test/decompiler/reference/jak1/levels/jungleb/jungleb-obs_REF.gc @@ -246,18 +246,12 @@ (while (not (process-grab? *target*)) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event *camera* 'blend-from-as-fixed) (camera-look-at (the-as pair "ecovent-171") (the-as uint 0)) (camera-change-to "camera-223" 0 #f) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (while (not (process-release? (handle->process (-> self grab-target)))) (suspend) diff --git a/test/decompiler/reference/jak1/levels/jungleb/plant-boss_REF.gc b/test/decompiler/reference/jak1/levels/jungleb/plant-boss_REF.gc index c6b5b07bf3..634135c0c3 100644 --- a/test/decompiler/reference/jak1/levels/jungleb/plant-boss_REF.gc +++ b/test/decompiler/reference/jak1/levels/jungleb/plant-boss_REF.gc @@ -528,12 +528,9 @@ (defstate plant-boss-vine-die (plant-boss-arm) :code (behavior ((arg0 symbol)) (when (not arg0) - (let ((f30-0 (rand-vu-float-range (the-as float 0.0) (the-as float 1.0))) - (gp-0 (current-time)) - ) - (until (time-elapsed? gp-0 (the int (* 300.0 f30-0))) + (let ((f30-0 (rand-vu-float-range (the-as float 0.0) (the-as float 1.0)))) + (suspend-for (the int (* 300.0 f30-0)) (ja :num! (loop!)) - (suspend) ) ) (ja-channel-push! 1 (seconds 0.25)) @@ -574,14 +571,11 @@ ;; failed to figure out what this is: (defstate plant-boss-root-die (plant-boss-arm) :code (behavior ((arg0 symbol)) - (when (not arg0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 4)) + (if (not arg0) + (suspend-for (seconds 4) (+! (-> self root trans z) (* -4096.0 (seconds-per-frame))) - (suspend) ) ) - ) ) :post ja-post ) @@ -1059,10 +1053,7 @@ (suspend) ) (camera-change-to "camera-222" 600 #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (while (not (process-release? (handle->process (-> self grab-target)))) (suspend) @@ -1744,12 +1735,9 @@ :code (behavior () (ja-channel-set! 1) (ja :group! plant-boss-main-die-ja :num! max) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 5)) - (transform-post) - (do-push-aways! (-> self root)) - (suspend) - ) + (suspend-for (seconds 5) + (transform-post) + (do-push-aways! (-> self root)) ) (loop (logior! (-> self mask) (process-mask sleep)) diff --git a/test/decompiler/reference/jak1/levels/maincave/baby-spider_REF.gc b/test/decompiler/reference/jak1/levels/maincave/baby-spider_REF.gc index 617886fc1b..443d8d1709 100644 --- a/test/decompiler/reference/jak1/levels/maincave/baby-spider_REF.gc +++ b/test/decompiler/reference/jak1/levels/maincave/baby-spider_REF.gc @@ -554,14 +554,11 @@ baby-spider-default-event-handler ) (ja-no-eval :num! (loop!)) (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) - (let ((gp-0 (rand-vu-int-range 300 600)) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 gp-0) + (let ((gp-0 (rand-vu-int-range 300 600))) + (suspend-for gp-0 (ja :num-func num-func-identity :frame-num 0.0) (ja-blend-eval) (suspend) - (suspend) ) ) ) diff --git a/test/decompiler/reference/jak1/levels/maincave/dark-crystal_REF.gc b/test/decompiler/reference/jak1/levels/maincave/dark-crystal_REF.gc index cfb87e9399..3f07948525 100644 --- a/test/decompiler/reference/jak1/levels/maincave/dark-crystal_REF.gc +++ b/test/decompiler/reference/jak1/levels/maincave/dark-crystal_REF.gc @@ -529,10 +529,7 @@ (-> self root trans) :to *entity-pool* ) - (let ((s5-4 (current-time))) - (until (time-elapsed? s5-4 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (if gp-1 (go dark-crystal-spawn-fuel-cell) diff --git a/test/decompiler/reference/jak1/levels/misty/babak-with-cannon_REF.gc b/test/decompiler/reference/jak1/levels/misty/babak-with-cannon_REF.gc index b14bbbb339..0487bfbf32 100644 --- a/test/decompiler/reference/jak1/levels/misty/babak-with-cannon_REF.gc +++ b/test/decompiler/reference/jak1/levels/misty/babak-with-cannon_REF.gc @@ -320,11 +320,7 @@ nav-enemy-default-event-handler (if (and *target* (= (-> *target* current-level name) 'misty)) (spool-push *art-control* "mistycam-cannon" 0 self -1.0) ) - (let ((t9-3 (-> (find-parent-state) trans))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler trans) ) ) diff --git a/test/decompiler/reference/jak1/levels/misty/balloonlurker_REF.gc b/test/decompiler/reference/jak1/levels/misty/balloonlurker_REF.gc index d5801a2522..0cbeb53c77 100644 --- a/test/decompiler/reference/jak1/levels/misty/balloonlurker_REF.gc +++ b/test/decompiler/reference/jak1/levels/misty/balloonlurker_REF.gc @@ -839,10 +839,7 @@ (apply-all (-> self link) actor-link-dead-hook (& sv-16)) (when (and sv-16 sv-24) (process-grab? *target*) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (process-release? *target*) (while (let ((a1-4 (new 'stack-no-clear 'event-message-block))) diff --git a/test/decompiler/reference/jak1/levels/misty/misty-warehouse_REF.gc b/test/decompiler/reference/jak1/levels/misty/misty-warehouse_REF.gc index ff2f770907..a40d5b34da 100644 --- a/test/decompiler/reference/jak1/levels/misty/misty-warehouse_REF.gc +++ b/test/decompiler/reference/jak1/levels/misty/misty-warehouse_REF.gc @@ -64,10 +64,7 @@ (suspend) ) (camera-change-to "camera-160" 150 #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (while (not (process-release? (handle->process (-> self grab-target)))) (suspend) @@ -92,10 +89,7 @@ (save-reminder gp-0 (logior v1-1 2) 0) ) (set-time! (-> self state-time)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (sound-play "arena-steps") (send-to-all-after (-> self link) 'trigger-rise) diff --git a/test/decompiler/reference/jak1/levels/misty/mistycannon_REF.gc b/test/decompiler/reference/jak1/levels/misty/mistycannon_REF.gc index 84bf8a6f30..bedfb1492d 100644 --- a/test/decompiler/reference/jak1/levels/misty/mistycannon_REF.gc +++ b/test/decompiler/reference/jak1/levels/misty/mistycannon_REF.gc @@ -938,11 +938,8 @@ ) (suspend) (clear-collide-with-as (-> self root)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 3)) - (spawn (-> self part2) (-> self root trans)) - (suspend) - ) + (suspend-for (seconds 3) + (spawn (-> self part2) (-> self root trans)) ) (kill-and-free-particles (-> self part2)) (deactivate self) diff --git a/test/decompiler/reference/jak1/levels/ogre/flying-lurker_REF.gc b/test/decompiler/reference/jak1/levels/ogre/flying-lurker_REF.gc index 8ed835d553..42305d13dd 100644 --- a/test/decompiler/reference/jak1/levels/ogre/flying-lurker_REF.gc +++ b/test/decompiler/reference/jak1/levels/ogre/flying-lurker_REF.gc @@ -950,10 +950,7 @@ process (lambda :behavior process () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (level-hint-spawn (text-id ogre-race-hint) "asstvb24" (the-as entity #f) *entity-pool* (game-task none)) (none) @@ -1202,10 +1199,7 @@ ) (when (and *target* (>= 172032.0 (vector-vector-xz-distance (-> self root trans) (-> *target* control trans)))) (process-grab? *target*) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (process-release? *target*) (send-event self 'saw-player) diff --git a/test/decompiler/reference/jak1/levels/ogre/ogreboss_REF.gc b/test/decompiler/reference/jak1/levels/ogre/ogreboss_REF.gc index e7dbf2e5f7..26a28259a7 100644 --- a/test/decompiler/reference/jak1/levels/ogre/ogreboss_REF.gc +++ b/test/decompiler/reference/jak1/levels/ogre/ogreboss_REF.gc @@ -1107,10 +1107,7 @@ (suspend) (ja :num! (seek! (ja-aframe (the-as float 140.0) 0))) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.167)) - (suspend) - ) + (suspend-for (seconds 0.167) ) (ja-no-eval :group! ogreboss-idle-ja :num! (seek! (ja-aframe (the-as float 168.0) 0)) @@ -1120,10 +1117,7 @@ (suspend) (ja :num! (seek! (ja-aframe (the-as float 168.0) 0))) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 0.167)) - (suspend) - ) + (suspend-for (seconds 0.167) ) (ja-no-eval :group! ogreboss-idle-ja :num! (seek!) :frame-num (ja-aframe (the-as float 168.0) 0)) (until (ja-done? 0) @@ -1405,10 +1399,7 @@ ) (logior! (-> self draw status) (draw-status hidden)) (set! (-> self submerged) #t) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 arg0) - (suspend) - ) + (suspend-for arg0 ) ) 0 diff --git a/test/decompiler/reference/jak1/levels/racer_common/racer-states_REF.gc b/test/decompiler/reference/jak1/levels/racer_common/racer-states_REF.gc index 5113f101ff..afe015bb5c 100644 --- a/test/decompiler/reference/jak1/levels/racer_common/racer-states_REF.gc +++ b/test/decompiler/reference/jak1/levels/racer_common/racer-states_REF.gc @@ -969,10 +969,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) (('endlessfall) @@ -996,29 +993,26 @@ ) ) ) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 0.75)) - (vector-seek! (-> self draw color-mult) *zero-vector* (* 1.5 (seconds-per-frame))) - (set-forward-vel (* 0.96 (-> self control unknown-float01))) - (let ((s5-3 (new-stack-vector0)) - (f28-0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv))) - ) - 0.0 - (vector-! s5-3 (-> self control transv) (vector-float*! s5-3 (-> self control dynam gravity-normal) f28-0)) - (let* ((f0-38 (vector-length s5-3)) - (f1-12 f0-38) - ) - (if (< f30-0 f28-0) - (set! f28-0 f30-0) - ) - (vector+! - (-> self control transv) - (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) f28-0) - (vector-float*! s5-3 s5-3 (/ f0-38 f1-12)) + (suspend-for (seconds 0.75) + (vector-seek! (-> self draw color-mult) *zero-vector* (* 1.5 (seconds-per-frame))) + (set-forward-vel (* 0.96 (-> self control unknown-float01))) + (let ((s5-3 (new-stack-vector0)) + (f28-0 (vector-dot (-> self control dynam gravity-normal) (-> self control transv))) + ) + 0.0 + (vector-! s5-3 (-> self control transv) (vector-float*! s5-3 (-> self control dynam gravity-normal) f28-0)) + (let* ((f0-38 (vector-length s5-3)) + (f1-12 f0-38) + ) + (if (< f30-0 f28-0) + (set! f28-0 f30-0) ) + (vector+! + (-> self control transv) + (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) f28-0) + (vector-float*! s5-3 s5-3 (/ f0-38 f1-12)) ) ) - (suspend) ) ) ) @@ -1191,16 +1185,13 @@ (ja :chan 2 :group! eichar-racer-dig-ja :num! (chan 0)) (ja :chan 3 :group! eichar-racer-dig2-ja :num! (chan 0)) ) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.5)) - (set! (-> self racer stick-lock) #t) - (set-forward-vel (* 0.9 (-> self control unknown-float01))) - (set! (-> self racer turn-anim-targ) 0.0) - (set! (-> self racer turn-anim-targ) 0.0) - (target-racing-turn-anim) - (seek! (-> self control unknown-vector11 y) 6144.0 (* 3.0 (seconds-per-frame))) - (suspend) - ) + (suspend-for (seconds 0.5) + (set! (-> self racer stick-lock) #t) + (set-forward-vel (* 0.9 (-> self control unknown-float01))) + (set! (-> self racer turn-anim-targ) 0.0) + (set! (-> self racer turn-anim-targ) 0.0) + (target-racing-turn-anim) + (seek! (-> self control unknown-vector11 y) 6144.0 (* 3.0 (seconds-per-frame))) ) (go target-racing-get-off-jump arg0) ) diff --git a/test/decompiler/reference/jak1/levels/racer_common/racer_REF.gc b/test/decompiler/reference/jak1/levels/racer_common/racer_REF.gc index 7e4717d416..bde276a61b 100644 --- a/test/decompiler/reference/jak1/levels/racer_common/racer_REF.gc +++ b/test/decompiler/reference/jak1/levels/racer_common/racer_REF.gc @@ -328,11 +328,8 @@ (racer-effect) (suspend) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (racer-effect) - (suspend) - ) + (suspend-for (seconds 1) + (racer-effect) ) (go arg0) ) diff --git a/test/decompiler/reference/jak1/levels/snow/snow-bunny_REF.gc b/test/decompiler/reference/jak1/levels/snow/snow-bunny_REF.gc index ceea651367..7332702349 100644 --- a/test/decompiler/reference/jak1/levels/snow/snow-bunny_REF.gc +++ b/test/decompiler/reference/jak1/levels/snow/snow-bunny_REF.gc @@ -464,11 +464,9 @@ :num! (identity (rand-vu-float-range 0.0 (the float (+ (-> (ja-group) data 0 length) -1)))) ) (loop - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 2.52)) - (suspend) - (ja :num! (loop!)) - ) + (suspend-for (seconds 2.52) + (suspend) + (ja :num! (loop!)) ) (cond ((zero? gp-2) diff --git a/test/decompiler/reference/jak1/levels/snow/snow-obs_REF.gc b/test/decompiler/reference/jak1/levels/snow/snow-obs_REF.gc index 668ed5e0e7..d126bd8075 100644 --- a/test/decompiler/reference/jak1/levels/snow/snow-obs_REF.gc +++ b/test/decompiler/reference/jak1/levels/snow/snow-obs_REF.gc @@ -50,10 +50,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 4.5)) - (suspend) - ) + (suspend-for (seconds 4.5) ) ) ((= v1-0 1) diff --git a/test/decompiler/reference/jak1/levels/swamp/billy_REF.gc b/test/decompiler/reference/jak1/levels/swamp/billy_REF.gc index d4d769f5df..bf247c440a 100644 --- a/test/decompiler/reference/jak1/levels/swamp/billy_REF.gc +++ b/test/decompiler/reference/jak1/levels/swamp/billy_REF.gc @@ -241,11 +241,7 @@ (defstate nav-enemy-victory (billy-rat) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (logtest? (nav-control-flags navcf19) (-> self nav flags)) (logclear! (-> self nav flags) (nav-control-flags navcf19)) (if (rat-about-to-eat? self (-> self billy 0)) diff --git a/test/decompiler/reference/jak1/levels/swamp/swamp-rat_REF.gc b/test/decompiler/reference/jak1/levels/swamp/swamp-rat_REF.gc index 5f56a46cc3..5eb8328a28 100644 --- a/test/decompiler/reference/jak1/levels/swamp/swamp-rat_REF.gc +++ b/test/decompiler/reference/jak1/levels/swamp/swamp-rat_REF.gc @@ -262,14 +262,11 @@ swamp-rat-default-event-handler ) (ja-no-eval :num! (loop!)) (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) - (let ((gp-0 (rand-vu-int-range 300 600)) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 gp-0) + (let ((gp-0 (rand-vu-int-range 300 600))) + (suspend-for gp-0 (ja :num-func num-func-identity :frame-num 0.0) (ja-blend-eval) (suspend) - (suspend) ) ) ) diff --git a/test/decompiler/reference/jak1/levels/title/title-obs_REF.gc b/test/decompiler/reference/jak1/levels/title/title-obs_REF.gc index c29b8ef3c7..1e80437b8f 100644 --- a/test/decompiler/reference/jak1/levels/title/title-obs_REF.gc +++ b/test/decompiler/reference/jak1/levels/title/title-obs_REF.gc @@ -448,11 +448,8 @@ ) (loop (when (and (none-reserved? *art-control*) (not (paused?))) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.1)) - (set! *camera-look-through-other* 2) - (suspend) - ) + (suspend-for (seconds 0.1) + (set! *camera-look-through-other* 2) ) (go-virtual idle) ) @@ -703,11 +700,8 @@ (set-blackout-frames (seconds 0.05)) (suspend) ) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.25)) - (set-blackout-frames (seconds 0.05)) - (suspend) - ) + (suspend-for (seconds 0.25) + (set-blackout-frames (seconds 0.05)) ) ) ) @@ -744,10 +738,7 @@ (while *progress-process* (suspend) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.01)) - (suspend) - ) + (suspend-for (seconds 0.01) ) (goto cfg-41) ) diff --git a/test/decompiler/reference/jak1/levels/training/training-obs_REF.gc b/test/decompiler/reference/jak1/levels/training/training-obs_REF.gc index bbfa9124ea..3823ecce49 100644 --- a/test/decompiler/reference/jak1/levels/training/training-obs_REF.gc +++ b/test/decompiler/reference/jak1/levels/training/training-obs_REF.gc @@ -186,10 +186,7 @@ (when (not (task-complete? *game-info* (game-task training-climb))) (clear-text-seen! *game-info* (text-id training-double-jump)) (level-hint-spawn (text-id training-double-jump) "sagevb27" (the-as entity #f) *entity-pool* (game-task none)) - (let ((gp-8 (current-time))) - (until (time-elapsed? gp-8 (seconds 30)) - (suspend) - ) + (suspend-for (seconds 30) ) (process-entity-status! self (entity-perm-status bit-3) #f) (go-virtual idle) diff --git a/test/decompiler/reference/jak1/levels/village1/fishermans-boat_REF.gc b/test/decompiler/reference/jak1/levels/village1/fishermans-boat_REF.gc index 622ba778a0..b473010341 100644 --- a/test/decompiler/reference/jak1/levels/village1/fishermans-boat_REF.gc +++ b/test/decompiler/reference/jak1/levels/village1/fishermans-boat_REF.gc @@ -1315,12 +1315,9 @@ ) (vector-z-quaternion! gp-0 (-> self root-overlay quat)) (vehicle-controller-method-10 (-> self controller) gp-0 (-> self controller throttle) s5-0) - (let ((s3-0 (current-time))) - (until (time-elapsed? s3-0 (seconds 1)) - (fishermans-boat-set-throttle-by-speed f30-0) - (suspend) - (suspend) - ) + (suspend-for (seconds 1) + (fishermans-boat-set-throttle-by-speed f30-0) + (suspend) ) ) (vector-z-quaternion! gp-0 (-> self root-overlay quat)) @@ -1572,10 +1569,7 @@ process (lambda :behavior fishermans-boat () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (or (-> *setting-control* current ambient) (-> *setting-control* current hint) diff --git a/test/decompiler/reference/jak1/levels/village2/sunken-elevator_REF.gc b/test/decompiler/reference/jak1/levels/village2/sunken-elevator_REF.gc index 500a447c32..2922b70d2b 100644 --- a/test/decompiler/reference/jak1/levels/village2/sunken-elevator_REF.gc +++ b/test/decompiler/reference/jak1/levels/village2/sunken-elevator_REF.gc @@ -154,11 +154,7 @@ ) (set! *teleport* #t) (set! (-> s5-0 quad) (-> self root trans quad)) - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (vector-! gp-0 (-> self root trans) s5-0) (when (< (-> self path-pos) 0.9) (move-by-vector! (-> *target* control) gp-0) diff --git a/test/decompiler/reference/jak1/levels/village2/village2-obs_REF.gc b/test/decompiler/reference/jak1/levels/village2/village2-obs_REF.gc index 96a8c33973..c7c16883c3 100644 --- a/test/decompiler/reference/jak1/levels/village2/village2-obs_REF.gc +++ b/test/decompiler/reference/jak1/levels/village2/village2-obs_REF.gc @@ -1547,10 +1547,7 @@ (suspend) (ja :num! (seek! (ja-aframe 140.0 0))) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.167)) - (suspend) - ) + (suspend-for (seconds 0.167) ) (ja-no-eval :group! ogreboss-village2-idle-ja :num! (seek! (ja-aframe 168.0 0)) @@ -1560,10 +1557,7 @@ (suspend) (ja :num! (seek! (ja-aframe 168.0 0))) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 0.167)) - (suspend) - ) + (suspend-for (seconds 0.167) ) (ja-no-eval :group! ogreboss-village2-idle-ja :num! (seek!) :frame-num (ja-aframe 168.0 0)) (until (ja-done? 0) diff --git a/test/decompiler/reference/jak1/levels/village_common/villagep-obs_REF.gc b/test/decompiler/reference/jak1/levels/village_common/villagep-obs_REF.gc index 9ffb59f48e..bfc1a1a43f 100644 --- a/test/decompiler/reference/jak1/levels/village_common/villagep-obs_REF.gc +++ b/test/decompiler/reference/jak1/levels/village_common/villagep-obs_REF.gc @@ -60,10 +60,7 @@ (ja-channel-set! 0) (vector-reset! (-> self control transv)) (move-to-point! (-> self control) (-> self control unknown-vector102)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((gp-1 (new-stack-vector0))) (let ((f0-1 (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) @@ -1150,10 +1147,7 @@ (let ((a0-70 (-> self entity extra perm))) (when (= (-> a0-70 user-uint8 0) 1) (remove-setting! 'allow-progress) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 300)) - (suspend) - ) + (suspend-for (seconds 300) ) (go-virtual idle) ) diff --git a/test/decompiler/reference/jak2/decompiler-macros.gc b/test/decompiler/reference/jak2/decompiler-macros.gc index add3b04af4..5b9e10632e 100644 --- a/test/decompiler/reference/jak2/decompiler-macros.gc +++ b/test/decompiler/reference/jak2/decompiler-macros.gc @@ -572,6 +572,13 @@ ) ) +(defmacro call-parent-state-handler (handler &key (type (function none)) &rest args) + "Call the parent handler for this state." + `(let ((handler (-> (find-parent-state) ,handler))) + (if handler ((the ,type handler) ,@args)) + ) + ) + (defmacro call-parent-method (&rest args) "Find the first different implementation of the current method in a parent type and call it with these arguments." `((the (current-method-function-type) (find-parent-method (current-method-type) (current-method-id))) @@ -1710,4 +1717,7 @@ (defmacro time-elapsed? (time duration) `(>= (- (current-time) ,time) ,duration) - ) \ No newline at end of file + ) + +(defmacro suspend-for (time &rest body) + `(let ((time (current-time))) (until (time-elapsed? time ,time) ,@body (suspend)))) \ No newline at end of file diff --git a/test/decompiler/reference/jak2/engine/ambient/ambient_REF.gc b/test/decompiler/reference/jak2/engine/ambient/ambient_REF.gc index 92204347f7..b23a499fa4 100644 --- a/test/decompiler/reference/jak2/engine/ambient/ambient_REF.gc +++ b/test/decompiler/reference/jak2/engine/ambient/ambient_REF.gc @@ -363,10 +363,7 @@ (defstate idle (talker) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (the-as time-frame (-> self message delay))) - (suspend) - ) + (suspend-for (the-as time-frame (-> self message delay)) ) (case (-> self message channel) (((gui-channel voicebox)) @@ -533,10 +530,7 @@ ) ) (when (and (logtest? (-> self message flags) 8) (not (-> self save?))) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (set! (-> self save?) #t) (auto-save-user) diff --git a/test/decompiler/reference/jak2/engine/common_objs/crates_REF.gc b/test/decompiler/reference/jak2/engine/common_objs/crates_REF.gc index f00cadff9e..a7b25d6607 100644 --- a/test/decompiler/reference/jak2/engine/common_objs/crates_REF.gc +++ b/test/decompiler/reference/jak2/engine/common_objs/crates_REF.gc @@ -901,10 +901,7 @@ ) ) (when (not arg0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.04)) - (suspend) - ) + (suspend-for (seconds 0.04) ) (logior! (-> self draw status) (draw-control-status no-draw)) (case (-> self look) @@ -1056,16 +1053,10 @@ (drop-pickup (-> self fact) #t *entity-pool* (the-as fact-info #f) arg1) (process-entity-status! self (entity-perm-status dead) #t) (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) (when (logtest? (actor-option cond-respawn) (-> self fact options)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 15)) - (suspend) - ) + (suspend-for (seconds 15) ) (go-virtual hide) ) diff --git a/test/decompiler/reference/jak2/engine/common_objs/generic-obs_REF.gc b/test/decompiler/reference/jak2/engine/common_objs/generic-obs_REF.gc index 7f9fe7fd25..4fbd1f980b 100644 --- a/test/decompiler/reference/jak2/engine/common_objs/generic-obs_REF.gc +++ b/test/decompiler/reference/jak2/engine/common_objs/generic-obs_REF.gc @@ -227,11 +227,8 @@ (move-along-path self) (suspend) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (move-along-path self) - (suspend) - ) + (suspend-for (seconds 0.5) + (move-along-path self) ) (go-virtual idle) ) @@ -1380,28 +1377,25 @@ ) (suspend) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (the-as time-frame (-> self linger-duration))) - (if (-> self linger-callback) - ((-> self linger-callback) self) - ) - (let* ((s5-0 (handle->process (-> self target))) - (v1-30 (if (type? s5-0 process-drawable) - s5-0 - ) - ) - ) - (if (and v1-30 - (nonzero? (-> (the-as process-drawable v1-30) root)) - (nonzero? (-> (the-as process-drawable v1-30) node-list)) - ) - (vector<-cspace! - (-> self root trans) - (-> (the-as process-drawable v1-30) node-list data (-> self target-joint)) - ) - ) + (suspend-for (the-as time-frame (-> self linger-duration)) + (if (-> self linger-callback) + ((-> self linger-callback) self) ) - (suspend) + (let* ((s5-0 (handle->process (-> self target))) + (v1-30 (if (type? s5-0 process-drawable) + s5-0 + ) + ) + ) + (if (and v1-30 + (nonzero? (-> (the-as process-drawable v1-30) root)) + (nonzero? (-> (the-as process-drawable v1-30) node-list)) + ) + (vector<-cspace! + (-> self root trans) + (-> (the-as process-drawable v1-30) node-list data (-> self target-joint)) + ) + ) ) ) (if (-> self linger-callback) diff --git a/test/decompiler/reference/jak2/engine/common_objs/powerups_REF.gc b/test/decompiler/reference/jak2/engine/common_objs/powerups_REF.gc index 236c577d9e..3d37bcb08c 100644 --- a/test/decompiler/reference/jak2/engine/common_objs/powerups_REF.gc +++ b/test/decompiler/reference/jak2/engine/common_objs/powerups_REF.gc @@ -16,25 +16,22 @@ (let ((s1-1 (process->handle arg0)) (s2-1 (process->handle arg1)) ) - (let ((s0-0 (current-time))) - (until (time-elapsed? s0-0 (+ arg3 arg4)) - (let ((v1-8 (or (not (handle->process s1-1)) (not (handle->process s2-1))))) - (if v1-8 - (deactivate self) - ) - ) - (let* ((f0-1 (fmax 0.0 (fmin 1.0 (/ (- (the float (- (current-time) s0-0)) (the float arg3)) (the float arg4))))) - (a0-18 (process-drawable-pair-random-point! - (the-as process-drawable (-> s1-1 process 0)) - (the-as process-drawable (-> s2-1 process 0)) - (new-stack-vector0) - f0-1 - ) + (suspend-for (+ arg3 arg4) + (let ((v1-8 (or (not (handle->process s1-1)) (not (handle->process s2-1))))) + (if v1-8 + (deactivate self) + ) + ) + (let* ((f0-1 (fmax 0.0 (fmin 1.0 (/ (- (the float (- (current-time) time)) (the float arg3)) (the float arg4))))) + (a0-18 (process-drawable-pair-random-point! + (the-as process-drawable (-> s1-1 process 0)) + (the-as process-drawable (-> s2-1 process 0)) + (new-stack-vector0) + f0-1 ) - ) - (arg2 a0-18) - ) - (suspend) + ) + ) + (arg2 a0-18) ) ) (cond @@ -45,12 +42,9 @@ #f ) (else - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 arg5) - (let ((a0-21 (process-drawable-random-point! (the-as process-drawable (-> s2-1 process 0)) (new-stack-vector0)))) - (arg2 a0-21) - ) - (suspend) + (suspend-for arg5 + (let ((a0-21 (process-drawable-random-point! (the-as process-drawable (-> s2-1 process 0)) (new-stack-vector0)))) + (arg2 a0-21) ) ) ) diff --git a/test/decompiler/reference/jak2/engine/debug/default-menu_REF.gc b/test/decompiler/reference/jak2/engine/debug/default-menu_REF.gc index 111b1dba74..c3c71c6239 100644 --- a/test/decompiler/reference/jak2/engine/debug/default-menu_REF.gc +++ b/test/decompiler/reference/jak2/engine/debug/default-menu_REF.gc @@ -4369,10 +4369,7 @@ ,(lambda () (let ((v1-1 (process-spawn-function process (lambda () (set-master-mode 'game) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.3)) - (suspend) - ) + (suspend-for (seconds 0.3) ) (until #f (format *stdcon* "press x clear map, press circle cancel~%") diff --git a/test/decompiler/reference/jak2/engine/game/game-info_REF.gc b/test/decompiler/reference/jak2/engine/game/game-info_REF.gc index 2429b5e499..2b0bd850d2 100644 --- a/test/decompiler/reference/jak2/engine/game/game-info_REF.gc +++ b/test/decompiler/reference/jak2/engine/game/game-info_REF.gc @@ -788,25 +788,19 @@ (set! (-> v1-9 origin z) (the float (/ (-> s3-0 z) 16))) ) (set! (-> s5-0 flags) (font-flags shadow kerning large)) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (+ arg2 -75)) - (+! (-> s5-0 origin y) (* -120.0 (seconds-per-frame))) - (let ((s2-0 print-game-text)) - (format (clear *temp-string*) "~4,,0f" arg1) - (s2-0 *temp-string* s5-0 #f 44 (bucket-id debug-no-zbuf1)) - ) - (suspend) + (suspend-for (+ arg2 -75) + (+! (-> s5-0 origin y) (* -120.0 (seconds-per-frame))) + (let ((s2-0 print-game-text)) + (format (clear *temp-string*) "~4,,0f" arg1) + (s2-0 *temp-string* s5-0 #f 44 (bucket-id debug-no-zbuf1)) ) ) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.25)) - (set! (-> s5-0 alpha) (lerp-scale 1.0 0.0 (the float (- (current-time) s4-1)) 0.0 150.0)) - (+! (-> s5-0 origin y) (* -120.0 (seconds-per-frame))) - (let ((s3-2 print-game-text)) - (format (clear *temp-string*) "~4,,0f" arg1) - (s3-2 *temp-string* s5-0 #f 44 (bucket-id debug-no-zbuf1)) - ) - (suspend) + (suspend-for (seconds 0.25) + (set! (-> s5-0 alpha) (lerp-scale 1.0 0.0 (the float (- (current-time) time)) 0.0 150.0)) + (+! (-> s5-0 origin y) (* -120.0 (seconds-per-frame))) + (let ((s3-2 print-game-text)) + (format (clear *temp-string*) "~4,,0f" arg1) + (s3-2 *temp-string* s5-0 #f 44 (bucket-id debug-no-zbuf1)) ) ) ) @@ -1237,11 +1231,8 @@ process (lambda :behavior process ((arg0 string)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 10)) - (format *stdcon* "~S~%" arg0) - (suspend) - ) + (suspend-for (seconds 10) + (format *stdcon* "~S~%" arg0) ) (none) ) diff --git a/test/decompiler/reference/jak2/engine/game/main_REF.gc b/test/decompiler/reference/jak2/engine/game/main_REF.gc index e9d905a565..371b8c98e4 100644 --- a/test/decompiler/reference/jak2/engine/game/main_REF.gc +++ b/test/decompiler/reference/jak2/engine/game/main_REF.gc @@ -1173,10 +1173,7 @@ (set! (-> *setting-control* user-default music-volume) 0.0) (set! (-> *setting-control* user-default dialog-volume) 0.0) (set! (-> *setting-control* user-default ambient-volume) 0.0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (kernel-shutdown (the-as runtime-exit-status arg0)) (none) diff --git a/test/decompiler/reference/jak2/engine/game/task/task-control_REF.gc b/test/decompiler/reference/jak2/engine/game/task/task-control_REF.gc index d386a108ad..0aa59df5c1 100644 --- a/test/decompiler/reference/jak2/engine/game/task/task-control_REF.gc +++ b/test/decompiler/reference/jak2/engine/game/task/task-control_REF.gc @@ -1680,27 +1680,24 @@ ) :code (behavior () (local-vars (a1-10 string)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (let ((f30-0 (lerp-scale 1.0 0.0 (the float (- (current-time) gp-0)) 0.0 270.0))) - (when *sound-player-enable* - (let ((v1-6 (the-as sound-rpc-set-param (get-sound-buffer-entry)))) - (set! (-> v1-6 command) (sound-command set-param)) - (set! (-> v1-6 id) (-> self stinger)) - (set! (-> v1-6 params volume) (the int (* 1024.0 f30-0))) - (set! (-> v1-6 params mask) (the-as uint 1)) - (-> v1-6 id) - ) + (suspend-for (seconds 1) + (let ((f30-0 (lerp-scale 1.0 0.0 (the float (- (current-time) time)) 0.0 270.0))) + (when *sound-player-enable* + (let ((v1-6 (the-as sound-rpc-set-param (get-sound-buffer-entry)))) + (set! (-> v1-6 command) (sound-command set-param)) + (set! (-> v1-6 id) (-> self stinger)) + (set! (-> v1-6 params volume) (the int (* 1024.0 f30-0))) + (set! (-> v1-6 params mask) (the-as uint 1)) + (-> v1-6 id) ) ) - (let ((f30-1 (lerp-scale 1.0 0.0 (the float (- (current-time) gp-0)) 0.0 300.0))) - (set-filter-color! - (lerp-scale 1.0 1.25 f30-1 0.0 1.0) - (lerp-scale 1.0 0.875 f30-1 0.0 1.0) - (lerp-scale 1.0 0.25 f30-1 0.0 1.0) - ) + ) + (let ((f30-1 (lerp-scale 1.0 0.0 (the float (- (current-time) time)) 0.0 300.0))) + (set-filter-color! + (lerp-scale 1.0 1.25 f30-1 0.0 1.0) + (lerp-scale 1.0 0.875 f30-1 0.0 1.0) + (lerp-scale 1.0 0.25 f30-1 0.0 1.0) ) - (suspend) ) ) (case (-> self message) diff --git a/test/decompiler/reference/jak2/engine/process-drawable/process-taskable_REF.gc b/test/decompiler/reference/jak2/engine/process-drawable/process-taskable_REF.gc index 941626a37a..dd5d2c3031 100644 --- a/test/decompiler/reference/jak2/engine/process-drawable/process-taskable_REF.gc +++ b/test/decompiler/reference/jak2/engine/process-drawable/process-taskable_REF.gc @@ -334,10 +334,7 @@ :enter (-> (method-of-type process-taskable active) enter) :exit (-> (method-of-type process-taskable active) exit) :code (behavior ((arg0 game-task-event)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (go-virtual hide) ) diff --git a/test/decompiler/reference/jak2/engine/scene/scene_REF.gc b/test/decompiler/reference/jak2/engine/scene/scene_REF.gc index 1614d9b329..996bb43b84 100644 --- a/test/decompiler/reference/jak2/engine/scene/scene_REF.gc +++ b/test/decompiler/reference/jak2/engine/scene/scene_REF.gc @@ -1144,10 +1144,7 @@ (* 30.0 (seconds-per-frame)) (bucket-id screen-filter) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.05)) - (suspend) - ) + (suspend-for (seconds 0.05) ) (set! (-> *setting-control* user-current bg-a) 0.0) (remove-setting! 'movie) diff --git a/test/decompiler/reference/jak2/engine/sound/gsound_REF.gc b/test/decompiler/reference/jak2/engine/sound/gsound_REF.gc index 8c2f46c545..b08b71fc59 100644 --- a/test/decompiler/reference/jak2/engine/sound/gsound_REF.gc +++ b/test/decompiler/reference/jak2/engine/sound/gsound_REF.gc @@ -1362,10 +1362,7 @@ (set! (-> a1-3 0) 'empty0) (want-sound-banks *load-state* a1-3) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((a1-4 (new 'stack-no-clear 'array 'symbol 4))) (set! (-> a1-4 2) (-> gp-0 2)) diff --git a/test/decompiler/reference/jak2/engine/target/board/board-states_REF.gc b/test/decompiler/reference/jak2/engine/target/board/board-states_REF.gc index 7f5b0b2340..c3e50488ab 100644 --- a/test/decompiler/reference/jak2/engine/target/board/board-states_REF.gc +++ b/test/decompiler/reference/jak2/engine/target/board/board-states_REF.gc @@ -3003,10 +3003,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (move-to-point! (-> self control) s4-1) ) diff --git a/test/decompiler/reference/jak2/engine/target/gun/gun-dark-shot_REF.gc b/test/decompiler/reference/jak2/engine/target/gun/gun-dark-shot_REF.gc index 9f62be6dd0..f3578da133 100644 --- a/test/decompiler/reference/jak2/engine/target/gun/gun-dark-shot_REF.gc +++ b/test/decompiler/reference/jak2/engine/target/gun/gun-dark-shot_REF.gc @@ -855,10 +855,7 @@ (-> self result-array (+ gp-2 -1)) :to s4-1 ) - (let ((s4-2 (current-time))) - (until (time-elapsed? s4-2 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) ) ) diff --git a/test/decompiler/reference/jak2/engine/target/mech/mech-states_REF.gc b/test/decompiler/reference/jak2/engine/target/mech/mech-states_REF.gc index 1b52e3583e..0c56e56825 100644 --- a/test/decompiler/reference/jak2/engine/target/mech/mech-states_REF.gc +++ b/test/decompiler/reference/jak2/engine/target/mech/mech-states_REF.gc @@ -1037,10 +1037,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (move-to-point! (-> self control) s4-1) ) @@ -1177,11 +1174,8 @@ ) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! jakb-mech-jump-loop-ja :num! (loop! 0.5) :frame-num 0.0) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.8)) - (ja :group! jakb-mech-jump-loop-ja :num! (loop! 0.5)) - (suspend) - ) + (suspend-for (seconds 0.8) + (ja :group! jakb-mech-jump-loop-ja :num! (loop! 0.5)) ) (remove-setting! 'mode-name) ) @@ -1302,10 +1296,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) ) diff --git a/test/decompiler/reference/jak2/engine/target/mech/mech_REF.gc b/test/decompiler/reference/jak2/engine/target/mech/mech_REF.gc index 4b14800bbb..140b01a824 100644 --- a/test/decompiler/reference/jak2/engine/target/mech/mech_REF.gc +++ b/test/decompiler/reference/jak2/engine/target/mech/mech_REF.gc @@ -264,11 +264,8 @@ (mech-method-24 self) (suspend) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (mech-method-24 self) - (suspend) - ) + (suspend-for (seconds 1) + (mech-method-24 self) ) (go arg0) ) diff --git a/test/decompiler/reference/jak2/engine/target/target-death_REF.gc b/test/decompiler/reference/jak2/engine/target/target-death_REF.gc index 9363d3661a..e995bf2c5d 100644 --- a/test/decompiler/reference/jak2/engine/target/target-death_REF.gc +++ b/test/decompiler/reference/jak2/engine/target/target-death_REF.gc @@ -292,10 +292,7 @@ ) ) ) - (let ((s5-6 (current-time))) - (until (time-elapsed? s5-6 (seconds 0.05)) - (suspend) - ) + (suspend-for (seconds 0.05) ) ) ((logtest? (-> arg0 flags) (continue-flags title)) @@ -319,10 +316,7 @@ (intro-play) ) ((logtest? (-> arg0 flags) (continue-flags warp-gate)) - (let ((s5-7 (current-time))) - (until (time-elapsed? s5-7 (seconds 0.05)) - (suspend) - ) + (suspend-for (seconds 0.05) ) (let ((s5-8 (new 'static 'vector)) (a2-26 (find-nearest-entity (-> arg0 trans) warp-gate)) @@ -354,10 +348,7 @@ (go target-grab 'stance) ) (else - (let ((s5-9 (current-time))) - (until (time-elapsed? s5-9 (seconds 0.05)) - (suspend) - ) + (suspend-for (seconds 0.05) ) ) ) @@ -1024,10 +1015,7 @@ (let ((gp-1 (new-stack-vector0))) (set! (-> gp-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (move-to-point! (-> self control) gp-1) ) @@ -1671,10 +1659,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-3 (current-time))) - (until (time-elapsed? s5-3 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (b! #t cfg-131 :delay (nop!)) (label cfg-79) @@ -1786,10 +1771,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((s5-7 (current-time))) - (until (time-elapsed? s5-7 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) (b! #t cfg-131 :delay (nop!)) @@ -1839,10 +1821,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-10 (current-time))) - (until (time-elapsed? s5-10 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) ) @@ -1859,10 +1838,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-11 (current-time))) - (until (time-elapsed? s5-11 (seconds 1.2)) - (suspend) - ) + (suspend-for (seconds 1.2) ) ) ((= v1-50 'endlessfall) @@ -1901,38 +1877,35 @@ (target-falling-anim 30 (seconds 0.33)) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! jakb-launch-jump-loop-ja :num! (loop! 0.5) :frame-num 0.0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.8)) - (when (and (logtest? (-> self control status) (collide-status on-surface)) (!= (-> self control cur-pat event) 2)) - (set! v1-24 'target-hit-ground-hard) - (goto cfg-17) + (suspend-for (seconds 0.8) + (when (and (logtest? (-> self control status) (collide-status on-surface)) (!= (-> self control cur-pat event) 2)) + (set! v1-24 'target-hit-ground-hard) + (goto cfg-17) + ) + (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) + (let ((v1-49 (new-stack-vector0)) + (f0-7 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) + ) + 0.0 + (vector-! + v1-49 + (-> self control transv) + (vector-float*! v1-49 (-> self control dynam gravity-normal) (the-as float f0-7)) ) - (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) - (let ((v1-49 (new-stack-vector0)) - (f0-7 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) + (let* ((f1-7 (vector-length v1-49)) + (f2-2 f1-7) + ) + (if (< (the-as float (-> self control unknown-word04)) (the-as float f0-7)) + (set! f0-7 (-> self control unknown-word04)) ) - 0.0 - (vector-! - v1-49 + (vector+! (-> self control transv) - (vector-float*! v1-49 (-> self control dynam gravity-normal) (the-as float f0-7)) - ) - (let* ((f1-7 (vector-length v1-49)) - (f2-2 f1-7) - ) - (if (< (the-as float (-> self control unknown-word04)) (the-as float f0-7)) - (set! f0-7 (-> self control unknown-word04)) - ) - (vector+! - (-> self control transv) - (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f0-7)) - (vector-float*! v1-49 v1-49 (/ f1-7 f2-2)) - ) + (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f0-7)) + (vector-float*! v1-49 v1-49 (/ f1-7 f2-2)) ) ) - (ja :group! jakb-launch-jump-loop-ja :num! (loop! 0.5)) - (suspend) ) + (ja :group! jakb-launch-jump-loop-ja :num! (loop! 0.5)) ) (set! v1-24 #f) (label cfg-17) @@ -1947,10 +1920,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) (remove-setting! 'mode-name) @@ -2040,10 +2010,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((s5-13 (current-time))) - (until (time-elapsed? s5-13 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) ((= v1-50 'centipede) diff --git a/test/decompiler/reference/jak2/engine/target/target-turret_REF.gc b/test/decompiler/reference/jak2/engine/target/target-turret_REF.gc index 0e15215485..1e90c6e77b 100644 --- a/test/decompiler/reference/jak2/engine/target/target-turret_REF.gc +++ b/test/decompiler/reference/jak2/engine/target/target-turret_REF.gc @@ -1670,10 +1670,7 @@ (sound-stop (-> self sound-id 1)) (sound-stop (-> self sound-id 2)) (set! (-> self focus-status) (focus-status disable ignore inactive)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.8)) - (suspend) - ) + (suspend-for (seconds 0.8) ) (send-event (handle->process (-> self rider)) diff --git a/test/decompiler/reference/jak2/engine/target/target2_REF.gc b/test/decompiler/reference/jak2/engine/target/target2_REF.gc index a976c2cc7c..9634b554da 100644 --- a/test/decompiler/reference/jak2/engine/target/target2_REF.gc +++ b/test/decompiler/reference/jak2/engine/target/target2_REF.gc @@ -43,12 +43,9 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.3)) - (suspend) - (ja :num! (seek! (ja-aframe 19.0 0) 0.05)) - (suspend) - ) + (suspend-for (seconds 0.3) + (suspend) + (ja :num! (seek! (ja-aframe 19.0 0) 0.05)) ) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! jakb-painful-land-ja :num! (seek!) :frame-num (ja-aframe 40.0 0)) @@ -1242,11 +1239,8 @@ (until #f (let ((s5-0 (rand-vu-int-range 30 600))) (ja :group! jakb-wall-hide-head-ja) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 s5-0) - (gp-0) - (suspend) - ) + (suspend-for s5-0 + (gp-0) ) ) (let ((f30-0 (rand-vu-float-range 0.5 1.5))) @@ -1284,12 +1278,9 @@ (suspend) (ja :num! (seek! max f30-0)) ) - (let ((s5-2 (rand-vu-int-range 60 300)) - (s4-2 (current-time)) - ) - (until (time-elapsed? s4-2 s5-2) + (let ((s5-2 (rand-vu-int-range 60 300))) + (suspend-for s5-2 (gp-0) - (suspend) ) ) (ja-no-eval :group! jakb-wall-hide-head-left-ja :num! (seek! 0.0 f30-0) :frame-num max) @@ -1306,12 +1297,9 @@ (suspend) (ja :num! (seek! 0.0 f30-0)) ) - (let ((s5-3 (rand-vu-int-range 60 300)) - (s4-3 (current-time)) - ) - (until (time-elapsed? s4-3 s5-3) + (let ((s5-3 (rand-vu-int-range 60 300))) + (suspend-for s5-3 (gp-0) - (suspend) ) ) (ja-no-eval :group! jakb-wall-hide-head-right-ja :num! (seek! max f30-0) :frame-num 0.0) diff --git a/test/decompiler/reference/jak2/levels/atoll/atoll-obs_REF.gc b/test/decompiler/reference/jak2/levels/atoll/atoll-obs_REF.gc index b3f565023a..7736d4adc8 100644 --- a/test/decompiler/reference/jak2/levels/atoll/atoll-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/atoll/atoll-obs_REF.gc @@ -644,42 +644,28 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (the int (-> self cycle-offset))) - (suspend) - ) + (suspend-for (the int (-> self cycle-offset)) ) (until #f - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (the int (-> self cycle-time))) - (suspend) - ) + (suspend-for (the int (-> self cycle-time)) ) (activate! (-> self smush) -1.0 60 225 1.0 1.0 (-> self clock)) (sound-play "rot-pipe-wiggle" :position (-> self root trans)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.75)) - (set! (-> self shudder-angle) (* 364.0889 (update! (-> self smush)))) - (suspend) - ) + (suspend-for (seconds 0.75) + (set! (-> self shudder-angle) (* 364.0889 (update! (-> self smush)))) ) (set! (-> self shudder-angle) 0.0) (set-zero! (-> self smush)) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (sound-play "rot-pipe-turn" :position (-> self root trans)) (let* ((f0-7 2.0) (f30-1 (* 16384.0 f0-7)) - (gp-6 (current-time)) ) - (until (time-elapsed? gp-6 (seconds 0.5)) + (suspend-for (seconds 0.5) (set! (-> self rot-angle) (the float (sar (shl (the int (+ (-> self rot-angle) (* f30-1 (seconds-per-frame)))) 48) 48)) ) - (suspend) ) ) (let ((v1-42 #x4000)) diff --git a/test/decompiler/reference/jak2/levels/atoll/juicer_REF.gc b/test/decompiler/reference/jak2/levels/atoll/juicer_REF.gc index a0526ce55e..6fe7fd6fc5 100644 --- a/test/decompiler/reference/jak2/levels/atoll/juicer_REF.gc +++ b/test/decompiler/reference/jak2/levels/atoll/juicer_REF.gc @@ -1395,57 +1395,55 @@ (s5-0 (+ (-> v1-29 attack-id) 1)) ) (set! (-> v1-29 attack-id) s5-0) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 (seconds 0.25)) - (ja-no-eval :group! juicer-attack0-ja :num! (seek!) :frame-num 0.0) - (until (ja-done? 0) - (let ((s3-0 (handle->process (-> self focus handle)))) - (when s3-0 - (when (< 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable s3-0) 0))) - (fire-projectile self (the-as process-focusable s3-0) s5-0) - (current-time) - (if (not gp-0) - (set! gp-0 #t) - ) - ) - ) - ) - (if (and (logtest? (-> self enemy-flags) (enemy-flag victory)) (-> self enemy-info use-victory)) - (go-virtual victory) + (suspend-for (seconds 0.25) + (ja-no-eval :group! juicer-attack0-ja :num! (seek!) :frame-num 0.0) + (until (ja-done? 0) + (let ((s3-0 (handle->process (-> self focus handle)))) + (when s3-0 + (when (< 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable s3-0) 0))) + (fire-projectile self (the-as process-focusable s3-0) s5-0) + (current-time) + (if (not gp-0) + (set! gp-0 #t) + ) ) - (b! - (not (and (-> self using-turn-anim) (let ((v1-73 (ja-group))) - (not (and v1-73 (= v1-73 juicer-attack-turn-ja))) - ) - ) - ) - cfg-31 - :delay (empty-form) - ) - (ja-channel-push! 1 (seconds 0.05)) - (ja :group! juicer-attack-turn-ja) - (b! #t cfg-42 :delay (nop!)) - (label cfg-31) - (when (and (not (-> self using-turn-anim)) (let ((v1-84 (ja-group))) - (not (and v1-84 (= v1-84 juicer-attack0-ja))) - ) - ) - (ja-channel-push! 1 (seconds 0.05)) - (ja :group! juicer-attack0-ja) ) - (label cfg-42) - (suspend) - (ja :num! (seek!)) ) - (send-event (handle->process (-> self current-projectile)) 'die) - (let ((a0-37 (handle->process (-> self focus handle)))) - (when a0-37 - (if (>= 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable a0-37) 0))) - (go-virtual circling) - ) + (if (and (logtest? (-> self enemy-flags) (enemy-flag victory)) (-> self enemy-info use-victory)) + (go-virtual victory) ) + (b! + (not (and (-> self using-turn-anim) (let ((v1-73 (ja-group))) + (not (and v1-73 (= v1-73 juicer-attack-turn-ja))) + ) + ) + ) + cfg-31 + :delay (empty-form) ) + (ja-channel-push! 1 (seconds 0.05)) + (ja :group! juicer-attack-turn-ja) + (b! #t cfg-42 :delay (nop!)) + (label cfg-31) + (when (and (not (-> self using-turn-anim)) (let ((v1-84 (ja-group))) + (not (and v1-84 (= v1-84 juicer-attack0-ja))) + ) + ) + (ja-channel-push! 1 (seconds 0.05)) + (ja :group! juicer-attack0-ja) + ) + (label cfg-42) (suspend) + (ja :num! (seek!)) + ) + (empty-form) + (send-event (handle->process (-> self current-projectile)) 'die) + (let ((a0-37 (handle->process (-> self focus handle)))) + (when a0-37 + (if (>= 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable a0-37) 0))) + (go-virtual circling) + ) + ) ) ) ) diff --git a/test/decompiler/reference/jak2/levels/castle/castle-obs_REF.gc b/test/decompiler/reference/jak2/levels/castle/castle-obs_REF.gc index 1e59001b78..79fc0b653f 100644 --- a/test/decompiler/reference/jak2/levels/castle/castle-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/castle/castle-obs_REF.gc @@ -555,10 +555,7 @@ (sound-play "lightning-node") (suspend) (logior! (-> self entity extra perm status) (entity-perm-status dead)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 4)) - (suspend) - ) + (suspend-for (seconds 4) ) (cleanup-for-death self) ) @@ -1846,10 +1843,7 @@ (sound-play "trapdoor") (suspend) (ja-channel-set! 0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (while (-> self child) @@ -2440,10 +2434,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (while (or (= (-> self spawn-total) -1) (< (-> self spawn-count-total) (-> self spawn-total))) (when (and (< (-> self player-dist) (+ 81920.0 (-> self notice-dist))) @@ -2480,17 +2471,11 @@ ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (the int (* 300.0 (rand-vu-float-range 0.5 1.0)))) - (suspend) - ) + (suspend-for (the int (* 300.0 (rand-vu-float-range 0.5 1.0))) ) ) (while (> (-> self spawn-count) 0) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.43)) - (suspend) - ) + (suspend-for (seconds 0.43) ) ) (process-entity-status! self (entity-perm-status subtask-complete) #t) @@ -2509,10 +2494,7 @@ (set-setting! 'entity-name a3-4 0.0 0) ) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (dotimes (gp-6 (-> self actor-group 1 length)) (let ((a1-17 (new 'stack-no-clear 'event-message-block))) @@ -2543,10 +2525,7 @@ (set-setting! 'entity-name a3-6 0.0 0) ) ) - (let ((gp-7 (current-time))) - (until (time-elapsed? gp-7 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((gp-8 (-> self actor-group 0))) (dotimes (s5-3 (-> gp-8 length)) @@ -2577,10 +2556,7 @@ (suspend) (ja :num! (seek! 0.0)) ) - (let ((gp-10 (current-time))) - (until (time-elapsed? gp-10 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (remove-setting! 'entity-name) (until (process-release? *target*) @@ -2618,10 +2594,7 @@ (label cfg-14) (not v1-28) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.51)) - (suspend) - ) + (suspend-for (seconds 0.51) ) ) (until (process-grab? *target* #f) @@ -2632,10 +2605,7 @@ (set-setting! 'entity-name a3-2 0.0 0) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (task-node-close! (game-task-node castle-break-in-resolution)) (let ((a1-7 (new 'stack-no-clear 'event-message-block))) @@ -2672,10 +2642,7 @@ ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 2.5)) - (suspend) - ) + (suspend-for (seconds 2.5) ) (remove-setting! 'entity-name) (until (process-release? *target*) diff --git a/test/decompiler/reference/jak2/levels/castle/pad/caspad-obs_REF.gc b/test/decompiler/reference/jak2/levels/castle/pad/caspad-obs_REF.gc index 17cfa08fc7..3e5af06492 100644 --- a/test/decompiler/reference/jak2/levels/castle/pad/caspad-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/castle/pad/caspad-obs_REF.gc @@ -121,10 +121,7 @@ ) ) :code (behavior () - (let ((frame-counter (current-time))) - (until (time-elapsed? frame-counter (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (logior! (-> self elevator-status) (elevator-status waiting-to-ascend)) (until #f diff --git a/test/decompiler/reference/jak2/levels/castle/pad/castle-tasks_REF.gc b/test/decompiler/reference/jak2/levels/castle/pad/castle-tasks_REF.gc index 6a65b09e0f..e67eb2deba 100644 --- a/test/decompiler/reference/jak2/levels/castle/pad/castle-tasks_REF.gc +++ b/test/decompiler/reference/jak2/levels/castle/pad/castle-tasks_REF.gc @@ -18,10 +18,7 @@ (until #f (when (< (vector-vector-distance (target-pos 0) (-> self info end-sphere)) (-> self info end-sphere r)) (send-event (handle->process (-> self arrow)) 'leave) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.007)) - (suspend) - ) + (suspend-for (seconds 0.007) ) (go-virtual complete) ) diff --git a/test/decompiler/reference/jak2/levels/castle/roboguard-level_REF.gc b/test/decompiler/reference/jak2/levels/castle/roboguard-level_REF.gc index e8d9ef027c..3198f564b3 100644 --- a/test/decompiler/reference/jak2/levels/castle/roboguard-level_REF.gc +++ b/test/decompiler/reference/jak2/levels/castle/roboguard-level_REF.gc @@ -360,11 +360,7 @@ (defstate ambush (roboguard-level) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (logand! (-> self flags) -9) (logior! (-> self flags) 4) (logior! (-> self nav flags) (nav-control-flag output-sphere-hash)) @@ -425,11 +421,7 @@ (defstate idle (roboguard-level) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (roboguard-level-method-185 self (the-as symbol 0)) ) :code (behavior () @@ -496,11 +488,7 @@ (defstate stare (roboguard-level) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (roboguard-level-method-185 self (the-as symbol 0)) ) :code (behavior () @@ -765,11 +753,7 @@ (defstate die (roboguard-level) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (roboguard-level-method-185 self (the-as symbol 0)) ) :code (behavior () diff --git a/test/decompiler/reference/jak2/levels/city/burning-bush/ctywide-bbush_REF.gc b/test/decompiler/reference/jak2/levels/city/burning-bush/ctywide-bbush_REF.gc index 9c4db27a33..87e98e54df 100644 --- a/test/decompiler/reference/jak2/levels/city/burning-bush/ctywide-bbush_REF.gc +++ b/test/decompiler/reference/jak2/levels/city/burning-bush/ctywide-bbush_REF.gc @@ -3053,10 +3053,7 @@ ) (send-event *camera* 'teleport-to-transformq gp-0) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (remove-setting! 'minimap) (set! (-> *ACTOR-bank* birth-max) 1000) diff --git a/test/decompiler/reference/jak2/levels/city/common/pilot-states_REF.gc b/test/decompiler/reference/jak2/levels/city/common/pilot-states_REF.gc index 2db49db634..07059da2de 100644 --- a/test/decompiler/reference/jak2/levels/city/common/pilot-states_REF.gc +++ b/test/decompiler/reference/jak2/levels/city/common/pilot-states_REF.gc @@ -809,10 +809,7 @@ (logior! (-> self focus-status) (focus-status dead)) (case arg0 (('melt 'grenade 'explode) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (case arg0 (('dark-eco-pool) @@ -936,10 +933,7 @@ ) 0 (ja-channel-set! 0) - (let ((s5-7 (current-time))) - (until (time-elapsed? s5-7 (seconds 1.8)) - (suspend) - ) + (suspend-for (seconds 1.8) ) ) (('endlessfall) @@ -969,10 +963,7 @@ ) ) ) - (let ((s5-9 (current-time))) - (until (time-elapsed? s5-9 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) ) (('bot) diff --git a/test/decompiler/reference/jak2/levels/city/ctywide-obs_REF.gc b/test/decompiler/reference/jak2/levels/city/ctywide-obs_REF.gc index 6e6782df10..cd9e5e5ff2 100644 --- a/test/decompiler/reference/jak2/levels/city/ctywide-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/city/ctywide-obs_REF.gc @@ -1746,10 +1746,7 @@ (suspend) (ja :num! (seek! (ja-aframe 32.0 0))) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) (set! (-> self root root-prim specific 0) (-> self root root-prim specific 1)) (setup-masks (-> self draw) 2 0) diff --git a/test/decompiler/reference/jak2/levels/city/ctywide-tasks_REF.gc b/test/decompiler/reference/jak2/levels/city/ctywide-tasks_REF.gc index 59c95c89f0..cb32053b68 100644 --- a/test/decompiler/reference/jak2/levels/city/ctywide-tasks_REF.gc +++ b/test/decompiler/reference/jak2/levels/city/ctywide-tasks_REF.gc @@ -185,10 +185,7 @@ (talker-spawn-func (-> *talker-speech* 38) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self sound-id 0)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (or (not *target*) (focus-test? *target* dead teleporting)) (suspend) @@ -240,10 +237,7 @@ (talker-spawn-func (-> *talker-speech* 31) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self sound-id 0)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (or (not *target*) (focus-test? *target* dead teleporting)) (suspend) @@ -252,10 +246,7 @@ (talker-spawn-func (-> *talker-speech* 35) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self sound-id 0)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (or (not *target*) (focus-test? *target* dead teleporting)) (suspend) @@ -277,10 +268,7 @@ ) (wait-for-speech-end (-> self sound-id 0)) (set! (-> self sub-state) (the-as uint 2)) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (go-virtual complete) (none) @@ -358,10 +346,7 @@ (talker-spawn-func (-> *talker-speech* 35) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self sound-id 0)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (set! (-> self sound-id 0) (talker-spawn-func (-> *talker-speech* 36) *entity-pool* (target-pos 0) (the-as region #f)) @@ -376,10 +361,7 @@ (talker-spawn-func (-> *talker-speech* 37) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self sound-id 0)) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (go-virtual complete) (none) diff --git a/test/decompiler/reference/jak2/levels/city/market/ctymark-obs_REF.gc b/test/decompiler/reference/jak2/levels/city/market/ctymark-obs_REF.gc index 0978aea0aa..1a0b61e201 100644 --- a/test/decompiler/reference/jak2/levels/city/market/ctymark-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/city/market/ctymark-obs_REF.gc @@ -1095,10 +1095,7 @@ :to self ) (process-entity-status! self (entity-perm-status dead) #t) - (let ((frame (current-time))) - (until (time-elapsed? frame (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) ) ) diff --git a/test/decompiler/reference/jak2/levels/city/onintent/onin-game_REF.gc b/test/decompiler/reference/jak2/levels/city/onintent/onin-game_REF.gc index e7d07943d4..948c5f92fc 100644 --- a/test/decompiler/reference/jak2/levels/city/onintent/onin-game_REF.gc +++ b/test/decompiler/reference/jak2/levels/city/onintent/onin-game_REF.gc @@ -1955,10 +1955,7 @@ (-> gp-0 ppointer) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (go-virtual fall) ) @@ -2701,10 +2698,7 @@ ) :code (behavior ((arg0 symbol)) (ja-channel-set! 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (talker-spawn-func (-> *talker-speech* 145) *entity-pool* (target-pos 0) (the-as region #f)) (sleep-code) @@ -2799,10 +2793,7 @@ (when (and (task-node-closed? (game-task-node city-play-onin-game-resolution)) (not (task-node-closed? (game-task-node city-play-onin-game-skill))) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (script-eval '(birth-pickup ("pecker-npc-1" "head") skill FACT_SUPER_SKILL_INC flags (suck-in))) (task-node-close! (game-task-node city-play-onin-game-skill)) @@ -2825,10 +2816,7 @@ (while (nonzero? (get-status *gui-control* s5-1)) (suspend) ) - (let ((s5-3 (current-time))) - (until (time-elapsed? s5-3 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (set-blackout-frames (seconds 0.1)) (send-event (handle->process gp-4) 'complete) diff --git a/test/decompiler/reference/jak2/levels/city/port/portrun/portrun_REF.gc b/test/decompiler/reference/jak2/levels/city/port/portrun/portrun_REF.gc index 66e82a03bf..a1ee113ead 100644 --- a/test/decompiler/reference/jak2/levels/city/port/portrun/portrun_REF.gc +++ b/test/decompiler/reference/jak2/levels/city/port/portrun/portrun_REF.gc @@ -1032,10 +1032,7 @@ 0 ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (cleanup-for-death self) ) @@ -1589,10 +1586,7 @@ (defstate die (ctyport-cargo) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (cleanup-for-death self) ) @@ -1999,10 +1993,7 @@ ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) (none) diff --git a/test/decompiler/reference/jak2/levels/city/traffic/citizen/metalhead-flitter_REF.gc b/test/decompiler/reference/jak2/levels/city/traffic/citizen/metalhead-flitter_REF.gc index ee2379276e..98d8022a85 100644 --- a/test/decompiler/reference/jak2/levels/city/traffic/citizen/metalhead-flitter_REF.gc +++ b/test/decompiler/reference/jak2/levels/city/traffic/citizen/metalhead-flitter_REF.gc @@ -406,17 +406,11 @@ ) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.6)) - (suspend) - ) + (suspend-for (seconds 0.6) ) (+! (-> self root trans y) -8192.0) (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6))) ) (logclear! (-> self draw status) (draw-control-status no-draw)) (go-virtual ambush-jumping) diff --git a/test/decompiler/reference/jak2/levels/common/enemy/flitter_REF.gc b/test/decompiler/reference/jak2/levels/common/enemy/flitter_REF.gc index f895c3a754..afed2ea0bf 100644 --- a/test/decompiler/reference/jak2/levels/common/enemy/flitter_REF.gc +++ b/test/decompiler/reference/jak2/levels/common/enemy/flitter_REF.gc @@ -712,10 +712,7 @@ (-> gp-0 ppointer) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.6)) - (suspend) - ) + (suspend-for (seconds 0.6) ) (+! (-> self root trans y) -8192.0) (enemy-method-129 self) @@ -734,10 +731,7 @@ ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6))) ) (logclear! (-> self draw status) (draw-control-status no-draw)) (go-virtual ambush-jumping) diff --git a/test/decompiler/reference/jak2/levels/common/enemy/grunt_REF.gc b/test/decompiler/reference/jak2/levels/common/enemy/grunt_REF.gc index 682ea04831..ec9ff8994b 100644 --- a/test/decompiler/reference/jak2/levels/common/enemy/grunt_REF.gc +++ b/test/decompiler/reference/jak2/levels/common/enemy/grunt_REF.gc @@ -515,10 +515,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (let ((v1-6 (-> self root root-prim))) (set! (-> v1-6 prim-core collide-as) (-> self root backup-collide-as)) diff --git a/test/decompiler/reference/jak2/levels/common/enemy/guards/crimson-guard-level_REF.gc b/test/decompiler/reference/jak2/levels/common/enemy/guards/crimson-guard-level_REF.gc index fd6d9fbd9d..9a33906ff8 100644 --- a/test/decompiler/reference/jak2/levels/common/enemy/guards/crimson-guard-level_REF.gc +++ b/test/decompiler/reference/jak2/levels/common/enemy/guards/crimson-guard-level_REF.gc @@ -2261,10 +2261,7 @@ (suspend) ) (when (logtest? (-> self flags) 4) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (until (crimson-guard-level-method-194 self) (suspend) @@ -2844,22 +2841,20 @@ (suspend) (ja :num! (seek! (ja-aframe 12.0 0))) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (the int (* 900.0 (you-suck-scale *game-info* #f)))) - (ja-no-eval :group! crimson-guard-grenade-attack-ja - :num! (seek! (ja-aframe 12.0 0)) - :frame-num (ja-aframe 12.0 0) - ) - (until (ja-done? 0) - (seek-toward-heading-vec! (-> self root) (-> self target-self-xz) 65536.0 (seconds 0.02)) - (suspend) - (ja :num! (seek! (ja-aframe 12.0 0))) - ) - (if (and (< (-> self target-self-xz-dist) 81920.0) (= (-> self focus aware) (enemy-aware enemy-aware-3))) - (go-hostile self) - ) + (suspend-for (the int (* 900.0 (you-suck-scale *game-info* #f))) + (ja-no-eval :group! crimson-guard-grenade-attack-ja + :num! (seek! (ja-aframe 12.0 0)) + :frame-num (ja-aframe 12.0 0) + ) + (until (ja-done? 0) + (seek-toward-heading-vec! (-> self root) (-> self target-self-xz) 65536.0 (seconds 0.02)) (suspend) + (ja :num! (seek! (ja-aframe 12.0 0))) ) + (empty-form) + (if (and (< (-> self target-self-xz-dist) 81920.0) (= (-> self focus aware) (enemy-aware enemy-aware-3))) + (go-hostile self) + ) ) (crimson-guard-level-method-192 self) (ja-no-eval :group! crimson-guard-grenade-attack-ja diff --git a/test/decompiler/reference/jak2/levels/common/enemy/hover/crimson-guard-hover_REF.gc b/test/decompiler/reference/jak2/levels/common/enemy/hover/crimson-guard-hover_REF.gc index beafef09be..e4f695984c 100644 --- a/test/decompiler/reference/jak2/levels/common/enemy/hover/crimson-guard-hover_REF.gc +++ b/test/decompiler/reference/jak2/levels/common/enemy/hover/crimson-guard-hover_REF.gc @@ -989,11 +989,7 @@ (defstate knocked (crimson-guard-hover) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) ) @@ -1051,10 +1047,7 @@ 0 (set! (-> self hit-points) 0) (do-effect (-> self skel effect) 'death-default 0.0 -1) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (cleanup-for-death self) @@ -1066,11 +1059,7 @@ (defstate flying-death (crimson-guard-hover) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (let ((gp-0 (get-process *default-dead-pool* part-tracker #x4000))) (when gp-0 (let ((t9-3 (method-of-type part-tracker activate))) @@ -1128,11 +1117,7 @@ (defstate flying-death-explode (crimson-guard-hover) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (sound-play "hover-explode") (let ((gp-1 (get-process *default-dead-pool* part-tracker #x4000))) (when gp-1 diff --git a/test/decompiler/reference/jak2/levels/common/enemy/hover/hover-enemy-battle_REF.gc b/test/decompiler/reference/jak2/levels/common/enemy/hover/hover-enemy-battle_REF.gc index 92b9fe9a2e..49b94de027 100644 --- a/test/decompiler/reference/jak2/levels/common/enemy/hover/hover-enemy-battle_REF.gc +++ b/test/decompiler/reference/jak2/levels/common/enemy/hover/hover-enemy-battle_REF.gc @@ -215,20 +215,14 @@ (('wait) ) ) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 (-> gp-0 s5-0 time)) - (suspend) - ) + (suspend-for (-> gp-0 s5-0 time) ) (while (< (-> gp-0 s5-0 alive-count) (-> self alive-count)) (suspend) ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (go-virtual die) ) diff --git a/test/decompiler/reference/jak2/levels/common/enemy/hover/wasp_REF.gc b/test/decompiler/reference/jak2/levels/common/enemy/hover/wasp_REF.gc index 101bb5ea71..3da9d22f1c 100644 --- a/test/decompiler/reference/jak2/levels/common/enemy/hover/wasp_REF.gc +++ b/test/decompiler/reference/jak2/levels/common/enemy/hover/wasp_REF.gc @@ -1111,10 +1111,7 @@ 0 (set! (-> self hit-points) 0) (do-effect (-> self skel effect) 'death-default 0.0 -1) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (cleanup-for-death self) diff --git a/test/decompiler/reference/jak2/levels/common/enemy/spyder_REF.gc b/test/decompiler/reference/jak2/levels/common/enemy/spyder_REF.gc index b5b7f2e4f2..119fb94d8a 100644 --- a/test/decompiler/reference/jak2/levels/common/enemy/spyder_REF.gc +++ b/test/decompiler/reference/jak2/levels/common/enemy/spyder_REF.gc @@ -1142,13 +1142,10 @@ (set! (-> self fire-info 0 quad) (-> s3-0 quad)) (set! (-> self fire-info 1 quad) (-> s2-1 quad)) ) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 0.2)) - (set! f30-0 (seek f30-0 (lerp-scale 0.0 1.0 (the float s4-0) 0.0 8.0) (seconds-per-frame))) - (ja :num! (loop!)) - (ja :chan 1 :num! (chan 0) :frame-interp0 f30-0 :frame-interp1 f30-0) - (suspend) - ) + (suspend-for (seconds 0.2) + (set! f30-0 (seek f30-0 (lerp-scale 0.0 1.0 (the float s4-0) 0.0 8.0) (seconds-per-frame))) + (ja :num! (loop!)) + (ja :chan 1 :num! (chan 0) :frame-interp0 f30-0 :frame-interp1 f30-0) ) (let ((f28-1 (+ 12288.0 f28-0))) (set! (-> gp-0 quad) (-> s5-0 quad)) diff --git a/test/decompiler/reference/jak2/levels/common/entities/com-elevator_REF.gc b/test/decompiler/reference/jak2/levels/common/entities/com-elevator_REF.gc index 837e4ab50b..ec99d77fcb 100644 --- a/test/decompiler/reference/jak2/levels/common/entities/com-elevator_REF.gc +++ b/test/decompiler/reference/jak2/levels/common/entities/com-elevator_REF.gc @@ -110,11 +110,7 @@ (defstate dormant (com-elevator) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (process-entity-status! self (entity-perm-status subtask-complete) #t) ) ) @@ -145,10 +141,7 @@ (remove-setting! 'allow-look-around) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (sound-play "com-elevator-s") (logior! (-> self elevator-status) (elevator-status waiting-to-ascend)) @@ -310,10 +303,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (logior! (-> self elevator-status) (elevator-status waiting-to-ascend)) (until #f diff --git a/test/decompiler/reference/jak2/levels/common/entities/gun-buoy_REF.gc b/test/decompiler/reference/jak2/levels/common/entities/gun-buoy_REF.gc index c21a2530d6..988526aca1 100644 --- a/test/decompiler/reference/jak2/levels/common/entities/gun-buoy_REF.gc +++ b/test/decompiler/reference/jak2/levels/common/entities/gun-buoy_REF.gc @@ -880,10 +880,7 @@ (gun-buoy-method-183 self a1-1) ) ) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.75)) - (suspend) - ) + (suspend-for (seconds 0.75) ) ) (go-virtual hostile) @@ -911,10 +908,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (go-virtual exit-ambush) ) diff --git a/test/decompiler/reference/jak2/levels/common/entities/spydroid_REF.gc b/test/decompiler/reference/jak2/levels/common/entities/spydroid_REF.gc index 9ef9220332..d559fa7d10 100644 --- a/test/decompiler/reference/jak2/levels/common/entities/spydroid_REF.gc +++ b/test/decompiler/reference/jak2/levels/common/entities/spydroid_REF.gc @@ -920,10 +920,7 @@ ) (suspend) (ja-channel-set! 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (while (-> self child) diff --git a/test/decompiler/reference/jak2/levels/common/race/race-obs_REF.gc b/test/decompiler/reference/jak2/levels/common/race/race-obs_REF.gc index 20a6fdf7a1..75a116ae51 100644 --- a/test/decompiler/reference/jak2/levels/common/race/race-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/common/race/race-obs_REF.gc @@ -328,10 +328,7 @@ :code (behavior () (until #f (ja :num-func num-func-identity :frame-num (ja-aframe 0.0 0)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (ja-no-eval :group! (ja-group) :num! (seek! (ja-aframe 2.0 0)) :frame-num (ja-aframe 0.0 0)) (until (ja-done? 0) @@ -339,10 +336,7 @@ (ja :num! (seek! (ja-aframe 2.0 0))) ) (process-spawn part-tracker :init part-tracker-init (-> *part-group-id-table* 196) 600 #f #f self 5 :to self) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (ja-no-eval :group! (ja-group) :num! (seek! (ja-aframe 4.0 0)) :frame-num (ja-aframe 2.0 0)) (until (ja-done? 0) @@ -350,10 +344,7 @@ (ja :num! (seek! (ja-aframe 4.0 0))) ) (process-spawn part-tracker :init part-tracker-init (-> *part-group-id-table* 195) 300 #f #f self 7 :to self) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (ja-no-eval :group! (ja-group) :num! (seek! (ja-aframe 6.0 0)) :frame-num (ja-aframe 4.0 0)) (until (ja-done? 0) @@ -361,16 +352,10 @@ (ja :num! (seek! (ja-aframe 6.0 0))) ) (process-spawn part-tracker :init part-tracker-init (-> *part-group-id-table* 194) 300 #f #f self 9 :to self) - (let ((gp-13 (current-time))) - (until (time-elapsed? gp-13 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (process-spawn part-tracker :init part-tracker-init (-> *part-group-id-table* 197) 300 #f #f self 10 :to self) - (let ((gp-15 (current-time))) - (until (time-elapsed? gp-15 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) ) #f diff --git a/test/decompiler/reference/jak2/levels/common/warp-gate_REF.gc b/test/decompiler/reference/jak2/levels/common/warp-gate_REF.gc index 0768231e80..773894464c 100644 --- a/test/decompiler/reference/jak2/levels/common/warp-gate_REF.gc +++ b/test/decompiler/reference/jak2/levels/common/warp-gate_REF.gc @@ -736,10 +736,7 @@ (set-blackout-frames (seconds 0.05)) ) (start 'play arg0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (and *target* (and (>= 81920.0 (vector-vector-distance (-> self root trans) (-> *target* control trans))) (not (logtest? (focus-status teleporting) (-> *target* focus-status))) diff --git a/test/decompiler/reference/jak2/levels/demo/demo-obs_REF.gc b/test/decompiler/reference/jak2/levels/demo/demo-obs_REF.gc index 2bff1bcc3f..db3ad1eb94 100644 --- a/test/decompiler/reference/jak2/levels/demo/demo-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/demo/demo-obs_REF.gc @@ -651,66 +651,42 @@ ) (cond ((zero? (scf-get-territory)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.38)) - (suspend) - ) + (suspend-for (seconds 0.38) ) (set! (-> self sprite-draw) (the-as uint 3)) (set-vector! (-> self sprite-pos) -512.0 40.0 0.0 1.0) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.25)) - (set! (-> self sprite-pos x) - (lerp-scale -512.0 0.0 (sin (* 218.45334 (the float (- (current-time) gp-4)))) 0.0 1.0) - ) - (suspend) - ) + (suspend-for (seconds 0.25) + (set! (-> self sprite-pos x) + (lerp-scale -512.0 0.0 (sin (* 218.45334 (the float (- (current-time) time)))) 0.0 1.0) + ) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 0.25)) - (set! (-> self sprite-pos x) - (lerp-scale 0.0 512.0 (sin (* 218.45334 (the float (- (current-time) gp-6)))) 0.0 1.0) - ) - (suspend) - ) + (suspend-for (seconds 0.25) + (set! (-> self sprite-pos x) + (lerp-scale 0.0 512.0 (sin (* 218.45334 (the float (- (current-time) time)))) 0.0 1.0) + ) ) (set! (-> self sprite-draw) (the-as uint 1)) (set-vector! (-> self sprite-pos) 30.0 -240.0 0.0 1.0) - (let ((gp-7 (current-time))) - (until (time-elapsed? gp-7 (seconds 0.25)) - (set! (-> self sprite-pos y) - (lerp-scale -240.0 270.0 (sin (* 218.45334 (the float (- (current-time) gp-7)))) 0.0 1.0) - ) - (suspend) - ) + (suspend-for (seconds 0.25) + (set! (-> self sprite-pos y) + (lerp-scale -240.0 270.0 (sin (* 218.45334 (the float (- (current-time) time)))) 0.0 1.0) + ) ) - (let ((gp-8 (current-time))) - (until (time-elapsed? gp-8 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 0.25)) - (set! (-> self sprite-pos y) - (lerp-scale 270.0 720.0 (sin (* 218.45334 (the float (- (current-time) gp-9)))) 0.0 1.0) - ) - (suspend) - ) + (suspend-for (seconds 0.25) + (set! (-> self sprite-pos y) + (lerp-scale 270.0 720.0 (sin (* 218.45334 (the float (- (current-time) time)))) 0.0 1.0) + ) ) (set! (-> self sprite-draw) (the-as uint 2)) (set-vector! (-> self sprite-pos) 20.0 40.0 0.0 1.0) - (let ((gp-10 (current-time))) - (until (time-elapsed? gp-10 (seconds 0.25)) - (set! (-> self sprite-pos y) - (lerp-scale 720.0 20.0 (sin (* 218.45334 (the float (- (current-time) gp-10)))) 0.0 1.0) - ) - (suspend) - ) + (suspend-for (seconds 0.25) + (set! (-> self sprite-pos y) + (lerp-scale 720.0 20.0 (sin (* 218.45334 (the float (- (current-time) time)))) 0.0 1.0) + ) ) (let ((a1-21 (new 'stack-no-clear 'array 'symbol 6))) (set! (-> a1-21 5) #f) @@ -721,72 +697,36 @@ (set! (-> a1-21 0) 'demo) (want-levels *load-state* a1-21) ) - (let ((gp-11 (current-time))) - (until (time-elapsed? gp-11 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) - (let ((gp-12 (current-time))) - (until (time-elapsed? gp-12 (seconds 0.25)) - (set! (-> self sprite-pos y) - (lerp-scale 20.0 -720.0 (sin (* 218.45334 (the float (- (current-time) gp-12)))) 0.0 1.0) - ) - (suspend) - ) + (suspend-for (seconds 0.25) + (set! (-> self sprite-pos y) + (lerp-scale 20.0 -720.0 (sin (* 218.45334 (the float (- (current-time) time)))) 0.0 1.0) + ) ) ) (else - (let ((gp-13 (current-time))) - (until (time-elapsed? gp-13 (seconds 0.38)) - (suspend) - ) + (suspend-for (seconds 0.38) ) - (let ((gp-14 (current-time))) - (until (time-elapsed? gp-14 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) - (let ((gp-15 (current-time))) - (until (time-elapsed? gp-15 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) - (let ((gp-16 (current-time))) - (until (time-elapsed? gp-16 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) - (let ((gp-17 (current-time))) - (until (time-elapsed? gp-17 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) - (let ((gp-18 (current-time))) - (until (time-elapsed? gp-18 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) - (let ((gp-19 (current-time))) - (until (time-elapsed? gp-19 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) - (let ((gp-20 (current-time))) - (until (time-elapsed? gp-20 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) - (let ((gp-21 (current-time))) - (until (time-elapsed? gp-21 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) ) ) - (let ((gp-22 (current-time))) - (until (time-elapsed? gp-22 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (demo-screen-change -1 -1 #f #t) (set! (-> *game-info* demo-state) (the-as uint 1)) diff --git a/test/decompiler/reference/jak2/levels/dig/dig1-obs_REF.gc b/test/decompiler/reference/jak2/levels/dig/dig1-obs_REF.gc index a9ecce2a61..f1dd062b81 100644 --- a/test/decompiler/reference/jak2/levels/dig/dig1-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/dig/dig1-obs_REF.gc @@ -505,10 +505,7 @@ (ja :num! (seek! max f30-0)) ) (ja-no-eval :group! dig-bomb-crate-cylinder-idle-ja :num! (seek!) :frame-num 0.0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (ja-no-eval :group! dig-bomb-crate-cylinder-pulse-ja :num! (seek! max f30-0) :frame-num 0.0) (until (ja-done? 0) @@ -516,10 +513,7 @@ (ja :num! (seek! max f30-0)) ) (ja-no-eval :group! dig-bomb-crate-cylinder-idle-ja :num! (seek!) :frame-num 0.0) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (ja-no-eval :group! dig-bomb-crate-cylinder-pulse-ja :num! (seek! max f30-0) :frame-num 0.0) (until (ja-done? 0) @@ -528,10 +522,7 @@ ) ) (ja-no-eval :group! dig-bomb-crate-cylinder-idle-ja :num! (seek!) :frame-num 0.0) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (ja-no-eval :group! dig-bomb-crate-cylinder-pulse-ja :num! (seek! max 0.375) :frame-num 0.0) (until (ja-done? 0) @@ -539,10 +530,7 @@ (ja :num! (seek! max 0.375)) ) (ja-no-eval :group! dig-bomb-crate-cylinder-idle-ja :num! (seek!) :frame-num 0.0) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (ja-no-eval :group! dig-bomb-crate-cylinder-pulse-ja :num! (seek! max 0.4375) :frame-num 0.0) (until (ja-done? 0) @@ -550,10 +538,7 @@ (ja :num! (seek! max 0.4375)) ) (ja-no-eval :group! dig-bomb-crate-cylinder-idle-ja :num! (seek!) :frame-num 0.0) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 0.125)) - (suspend) - ) + (suspend-for (seconds 0.125) ) (dotimes (gp-6 12) (ja-no-eval :group! dig-bomb-crate-cylinder-pulse-ja :num! (seek! max 0.437) :frame-num 0.0) @@ -562,10 +547,7 @@ (ja :num! (seek! max 0.437)) ) (ja-no-eval :group! dig-bomb-crate-cylinder-idle-ja :num! (seek!) :frame-num 0.0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.05)) - (suspend) - ) + (suspend-for (seconds 0.05) ) ) (go-virtual die) @@ -977,10 +959,7 @@ ) ) (suspend) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 4)) - (suspend) - ) + (suspend-for (seconds 4) ) (cleanup-for-death self) ) diff --git a/test/decompiler/reference/jak2/levels/dig/dig3-obs_REF.gc b/test/decompiler/reference/jak2/levels/dig/dig3-obs_REF.gc index dd74b034db..f398e34e65 100644 --- a/test/decompiler/reference/jak2/levels/dig/dig3-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/dig/dig3-obs_REF.gc @@ -285,42 +285,28 @@ :virtual #t :trans rider-trans :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (the int (-> self cycle-offset))) - (suspend) - ) + (suspend-for (the int (-> self cycle-offset)) ) (until #f - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (the int (-> self cycle-time))) - (suspend) - ) + (suspend-for (the int (-> self cycle-time)) ) (activate! (-> self smush) -1.0 60 225 1.0 1.0 (-> self clock)) (sound-play "spikey-shake" :position (-> self root trans)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.75)) - (set! (-> self shudder-angle) (* 364.0889 (update! (-> self smush)))) - (suspend) - ) + (suspend-for (seconds 0.75) + (set! (-> self shudder-angle) (* 364.0889 (update! (-> self smush)))) ) (set! (-> self shudder-angle) 0.0) (set-zero! (-> self smush)) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (sound-play "spikey-turn" :position (-> self root trans)) (let* ((f0-7 1.0) (f30-1 (* 65536.0 f0-7)) - (gp-6 (current-time)) ) - (until (time-elapsed? gp-6 (seconds 1)) + (suspend-for (seconds 1) (set! (-> self rot-angle) (the float (sar (shl (the int (+ (-> self rot-angle) (* f30-1 (seconds-per-frame)))) 48) 48)) ) - (suspend) ) ) (let ((v1-42 #x10000)) @@ -483,10 +469,7 @@ ) (sound-play "spikey-break") (suspend) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 4)) - (suspend) - ) + (suspend-for (seconds 4) ) (let ((t9-7 (-> (method-of-type projectile-bounce die) code))) (if t9-7 @@ -745,10 +728,7 @@ :virtual #t :code (behavior () (sound-play "spikey-door") - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (let ((gp-2 (new 'stack-no-clear 'vector)) (s5-1 (new 'static 'vector :x -16384.0 :y -16384.0)) diff --git a/test/decompiler/reference/jak2/levels/drill/drill-obs2_REF.gc b/test/decompiler/reference/jak2/levels/drill/drill-obs2_REF.gc index 96ce9c50d5..8d87b512ae 100644 --- a/test/decompiler/reference/jak2/levels/drill/drill-obs2_REF.gc +++ b/test/decompiler/reference/jak2/levels/drill/drill-obs2_REF.gc @@ -898,10 +898,7 @@ ) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (cleanup-for-death self) ) diff --git a/test/decompiler/reference/jak2/levels/forest/forest-obs_REF.gc b/test/decompiler/reference/jak2/levels/forest/forest-obs_REF.gc index 8995b54faa..3d7f2d920d 100644 --- a/test/decompiler/reference/jak2/levels/forest/forest-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/forest/forest-obs_REF.gc @@ -382,10 +382,7 @@ ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (send-event *camera* 'change-target #f) (cleanup-for-death self) @@ -649,10 +646,7 @@ (lambda :behavior task-manager () (set-time! (-> self start-time)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (let ((s5-0 (entity-by-name "transport-level-1")) (gp-1 (entity-by-name "transport-level-2")) @@ -722,10 +716,7 @@ ) ) ) - (let ((s3-0 (current-time))) - (until (time-elapsed? s3-0 (seconds 15)) - (suspend) - ) + (suspend-for (seconds 15) ) (let ((a1-4 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-4 from) (process->ppointer self)) @@ -760,10 +751,7 @@ ) ) (dotimes (s3-1 3) - (let ((s2-0 (current-time))) - (until (time-elapsed? s2-0 (seconds 10)) - (suspend) - ) + (suspend-for (seconds 10) ) (let ((a1-6 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-6 from) (process->ppointer self)) @@ -797,10 +785,7 @@ ) ) ) - (let ((s2-1 (current-time))) - (until (time-elapsed? s2-1 (seconds 10)) - (suspend) - ) + (suspend-for (seconds 10) ) (let ((a1-8 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-8 from) (process->ppointer self)) @@ -835,10 +820,7 @@ ) ) ) - (let ((s3-2 (current-time))) - (until (time-elapsed? s3-2 (seconds 10)) - (suspend) - ) + (suspend-for (seconds 10) ) (let ((a1-10 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-10 from) (process->ppointer self)) @@ -872,10 +854,7 @@ ) ) ) - (let ((s3-3 (current-time))) - (until (time-elapsed? s3-3 (seconds 10)) - (suspend) - ) + (suspend-for (seconds 10) ) (dotimes (s3-4 10) (let ((v1-114 s4-0)) @@ -886,10 +865,7 @@ (goto cfg-74) ) ) - (let ((s2-2 (current-time))) - (until (time-elapsed? s2-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) ) (label cfg-74) @@ -965,25 +941,16 @@ ) ) ) - (let ((s3-5 (current-time))) - (until (time-elapsed? s3-5 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) ) ) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (set-setting! 'entity-name "camera-260" 0.0 0) (set-setting! 'process-mask 'set 0.0 (process-mask movie enemy)) (process-grab? *target* #f) - (let ((s4-2 (current-time))) - (until (time-elapsed? s4-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (send-event (if s5-0 @@ -991,10 +958,7 @@ ) 'leave ) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (send-event (if gp-1 @@ -1003,18 +967,12 @@ 'leave ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (remove-setting! 'entity-name) (remove-setting! 'process-mask) (process-release? *target*) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (go-virtual complete) (while *target* diff --git a/test/decompiler/reference/jak2/levels/fortress/dump/fordumpa-obs_REF.gc b/test/decompiler/reference/jak2/levels/fortress/dump/fordumpa-obs_REF.gc index 59e2e1fff8..99d747a551 100644 --- a/test/decompiler/reference/jak2/levels/fortress/dump/fordumpa-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/fortress/dump/fordumpa-obs_REF.gc @@ -66,18 +66,12 @@ :virtual #t :event (-> (method-of-type fort-elec-switch idle) event) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 16)) - (suspend) - ) + (suspend-for (seconds 16) ) (until (logtest? (-> self draw status) (draw-control-status on-screen)) (suspend) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.4)) - (suspend) - ) + (suspend-for (seconds 0.4) ) (talker-spawn-func (-> *talker-speech* 86) *entity-pool* (target-pos 0) (the-as region #f)) (sleep-code) @@ -156,10 +150,7 @@ ) ) (sound-play "elec-switch") - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (let ((v1-22 #t)) (when (-> self switch-group) @@ -192,10 +183,7 @@ ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.75)) - (suspend) - ) + (suspend-for (seconds 0.75) ) (let ((a1-14 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-14 from) (process->ppointer self)) @@ -212,10 +200,7 @@ ) ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 1.5)) - (suspend) - ) + (suspend-for (seconds 1.5) ) (remove-setting! 'entity-name) (remove-setting! 'process-mask) diff --git a/test/decompiler/reference/jak2/levels/fortress/dump/fordumpc-obs_REF.gc b/test/decompiler/reference/jak2/levels/fortress/dump/fordumpc-obs_REF.gc index 4354599c59..b14c1c4845 100644 --- a/test/decompiler/reference/jak2/levels/fortress/dump/fordumpc-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/fortress/dump/fordumpc-obs_REF.gc @@ -150,10 +150,7 @@ ) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (cleanup-for-death self) ) @@ -392,10 +389,7 @@ (-> gp-2 ppointer) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event (ppointer->process (-> self parent)) 'died) (sleep-code) @@ -587,41 +581,26 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 8)) - (suspend) - ) + (suspend-for (seconds 8) ) (until (logtest? (-> self draw status) (draw-control-status on-screen)) (suspend) ) (when (= (-> self bomb-count) 4) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.4)) - (suspend) - ) + (suspend-for (seconds 0.4) ) (add-process *gui-control* self (gui-channel daxter) (gui-action play) "ds017" -99.0 0) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 20)) - (suspend) - ) + (suspend-for (seconds 20) ) (if (= (-> self bomb-count) 4) (add-process *gui-control* self (gui-channel daxter) (gui-action play) "ds018" -99.0 0) ) (while (> (-> self bomb-count) 0) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.8)) - (suspend) - ) + (suspend-for (seconds 0.8) ) (go-virtual missile-countdown) ) @@ -666,10 +645,7 @@ ) ) (set-fordumpc-light-flag! #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (while (not (process-grab? *target* #f)) (suspend) @@ -677,10 +653,7 @@ (set-setting! 'entity-name "camera-182" 0.0 0) (set-setting! 'process-mask 'set 0.0 (process-mask movie enemy)) (task-node-close! (game-task-node fortress-dump-missile)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.75)) - (suspend) - ) + (suspend-for (seconds 0.75) ) (let ((a1-5 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-5 from) (process->ppointer self)) @@ -712,10 +685,7 @@ ) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1.5)) - (suspend) - ) + (suspend-for (seconds 1.5) ) (remove-setting! 'entity-name) (remove-setting! 'process-mask) @@ -739,20 +709,14 @@ (set! (-> *game-info* timer) 0) (set! (-> self hud) (ppointer->handle (process-spawn hud-timer :init hud-init-by-other :to *target*))) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.4)) - (suspend) - ) + (suspend-for (seconds 0.4) ) (set! (-> self explosion-sound-id) (add-process *gui-control* self (gui-channel background) (gui-action queue) "big-xplo" -99.0 0) ) (dotimes (gp-5 10) (set! (-> *game-info* timer) (the-as time-frame (- 3000 (the int (* 300.0 (the float gp-5)))))) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) ) (go-virtual die) @@ -790,10 +754,7 @@ (remove-setting! 'allow-progress) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.4)) - (suspend) - ) + (suspend-for (seconds 0.4) ) (logior! (-> self draw status) (draw-control-status no-draw)) (when *scene-player* @@ -952,10 +913,7 @@ (suspend) ) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 10)) - (suspend) - ) + (suspend-for (seconds 10) ) (cleanup-for-death self) ) diff --git a/test/decompiler/reference/jak2/levels/fortress/dump/fort-robotank-turret_REF.gc b/test/decompiler/reference/jak2/levels/fortress/dump/fort-robotank-turret_REF.gc index 0ca2f15017..c8bd781860 100644 --- a/test/decompiler/reference/jak2/levels/fortress/dump/fort-robotank-turret_REF.gc +++ b/test/decompiler/reference/jak2/levels/fortress/dump/fort-robotank-turret_REF.gc @@ -289,12 +289,9 @@ (defstate die (fort-roboscreen) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (seek! (-> self transition) 0.0 (seconds-per-frame)) - (set-roboscreen-alpha! (-> self transition)) - (suspend) - ) + (suspend-for (seconds 1) + (seek! (-> self transition) 0.0 (seconds-per-frame)) + (set-roboscreen-alpha! (-> self transition)) ) ) ) @@ -1453,10 +1450,7 @@ (logior! (-> self flags) (robotank-turret-flags rotflags-3)) (set! (-> self firing-sight-pos quad) (-> self sight-pos quad)) (send-event (handle->process (-> self reticle)) 'lock) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (let ((gp-2 (max 2 (min 3 (rand-vu-int-range 0 3))))) 0 @@ -1483,11 +1477,8 @@ ) ) ) - (let ((f30-0 (rand-vu-float-range 0.05 0.43)) - (s4-2 (current-time)) - ) - (until (time-elapsed? s4-2 (the int (* 300.0 f30-0))) - (suspend) + (let ((f30-0 (rand-vu-float-range 0.05 0.43))) + (suspend-for (the int (* 300.0 f30-0)) ) ) ) @@ -1506,10 +1497,8 @@ 2.11 ) ) - (gp-3 (current-time)) ) - (until (time-elapsed? gp-3 (the int (* 300.0 f30-1))) - (suspend) + (suspend-for (the int (* 300.0 f30-1)) ) ) ) @@ -1524,10 +1513,7 @@ :code (behavior () (send-event (handle->process (-> self reticle)) 'die) (send-event (handle->process (-> self screen)) 'die) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (-> self child) (suspend) diff --git a/test/decompiler/reference/jak2/levels/fortress/dump/fort-robotank_REF.gc b/test/decompiler/reference/jak2/levels/fortress/dump/fort-robotank_REF.gc index 57d7168fc8..2dca4913b3 100644 --- a/test/decompiler/reference/jak2/levels/fortress/dump/fort-robotank_REF.gc +++ b/test/decompiler/reference/jak2/levels/fortress/dump/fort-robotank_REF.gc @@ -889,10 +889,7 @@ ) :code (behavior () (logclear! (-> self flags) (robotank-flags roflags-2)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (logior! (-> self flags) (robotank-flags roflags-2)) (sleep-code) @@ -1023,10 +1020,7 @@ (remove-setting! 'process-mask) (remove-setting! 'target-height) (send-event (handle->process (-> self turret)) 'die) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (while (-> self child) (suspend) diff --git a/test/decompiler/reference/jak2/levels/fortress/exit/forexita-obs_REF.gc b/test/decompiler/reference/jak2/levels/fortress/exit/forexita-obs_REF.gc index 52210fd05a..c5e68ab322 100644 --- a/test/decompiler/reference/jak2/levels/fortress/exit/forexita-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/fortress/exit/forexita-obs_REF.gc @@ -362,10 +362,7 @@ () (until #f (sound-play "fortress-alarm") - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) ) #f diff --git a/test/decompiler/reference/jak2/levels/fortress/fort-turret_REF.gc b/test/decompiler/reference/jak2/levels/fortress/fort-turret_REF.gc index 4e13026b48..f7d06a3326 100644 --- a/test/decompiler/reference/jak2/levels/fortress/fort-turret_REF.gc +++ b/test/decompiler/reference/jak2/levels/fortress/fort-turret_REF.gc @@ -795,10 +795,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (until #f (let ((gp-2 7)) @@ -816,10 +813,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.33)) - (suspend) - ) + (suspend-for (seconds 0.33) ) (if (= gp-2 7) (set! gp-2 8) @@ -828,10 +822,7 @@ ) ) (set! (-> self flash-state) #f) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 1.5)) - (suspend) - ) + (suspend-for (seconds 1.5) ) ) #f @@ -983,18 +974,12 @@ (sound-play "turret-explode") (suspend) (ja-channel-set! 0) - (let ((gp-2 (vector<-cspace! (new 'stack-no-clear 'vector) (joint-node fort-turret-lod0-jg headrotate))) - (s5-2 (current-time)) - ) - (until (time-elapsed? s5-2 (seconds 2)) + (let ((gp-2 (vector<-cspace! (new 'stack-no-clear 'vector) (joint-node fort-turret-lod0-jg headrotate)))) + (suspend-for (seconds 2) (spawn (-> self part) gp-2) - (suspend) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (while (-> self child) diff --git a/test/decompiler/reference/jak2/levels/fortress/fortress-obs_REF.gc b/test/decompiler/reference/jak2/levels/fortress/fortress-obs_REF.gc index f37bd1ab21..0d83f19545 100644 --- a/test/decompiler/reference/jak2/levels/fortress/fortress-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/fortress/fortress-obs_REF.gc @@ -140,10 +140,7 @@ ) (suspend) (ja-channel-set! 0) - (let ((frame-counter (current-time))) - (until (time-elapsed? frame-counter (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (while (-> self child) diff --git a/test/decompiler/reference/jak2/levels/fortress/rescue/forresca-obs_REF.gc b/test/decompiler/reference/jak2/levels/fortress/rescue/forresca-obs_REF.gc index 96f2046f2c..fceb62d45e 100644 --- a/test/decompiler/reference/jak2/levels/fortress/rescue/forresca-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/fortress/rescue/forresca-obs_REF.gc @@ -278,19 +278,13 @@ (let ((a0-0 *target*)) (when (and a0-0 (< 81920.0 (vector-vector-distance (get-trans a0-0 0) (-> self root trans)))) (set! (-> self quality-enabled?) #f) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (hide-hud-quick #f) (set-setting! 'entity-name "camera-243" 0.0 0) (set-setting! 'process-mask 'set 0.0 (process-mask movie enemy)) (process-grab? *target* #f) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) ) @@ -385,10 +379,7 @@ ) :code (behavior () (until (-> self all-gone?) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) ) (set-setting! 'interp-time 'abs 0.0 0) diff --git a/test/decompiler/reference/jak2/levels/gungame/gungame-obs_REF.gc b/test/decompiler/reference/jak2/levels/gungame/gungame-obs_REF.gc index 6510189e83..d3cf898bd3 100644 --- a/test/decompiler/reference/jak2/levels/gungame/gungame-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/gungame/gungame-obs_REF.gc @@ -1891,10 +1891,7 @@ t1-0 ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (auto-save-user) ) @@ -2369,11 +2366,8 @@ ) :code (behavior () (sound-play "gungame-door") - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.2)) - (suspend) - (suspend) - ) + (suspend-for (seconds 0.2) + (suspend) ) (ja-no-eval :group! fort-entry-gate-idle-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) diff --git a/test/decompiler/reference/jak2/levels/intro/intro-obs_REF.gc b/test/decompiler/reference/jak2/levels/intro/intro-obs_REF.gc index 82746da2c0..84f7ecc603 100644 --- a/test/decompiler/reference/jak2/levels/intro/intro-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/intro/intro-obs_REF.gc @@ -348,11 +348,8 @@ (-> s5-0 ppointer) ) ) - (let ((s5-1 (the int (* 300.0 (rand-vu-float-range 0.03 0.08)))) - (s4-0 (current-time)) - ) - (until (time-elapsed? s4-0 s5-1) - (suspend) + (let ((s5-1 (the int (* 300.0 (rand-vu-float-range 0.03 0.08))))) + (suspend-for s5-1 ) ) ) diff --git a/test/decompiler/reference/jak2/levels/intro/intro-scenes_REF.gc b/test/decompiler/reference/jak2/levels/intro/intro-scenes_REF.gc index 8c38a5d0ec..bde33466fe 100644 --- a/test/decompiler/reference/jak2/levels/intro/intro-scenes_REF.gc +++ b/test/decompiler/reference/jak2/levels/intro/intro-scenes_REF.gc @@ -2312,13 +2312,10 @@ (lambda :behavior scene-player () (talker-spawn-func (-> *talker-speech* 123) self (target-pos 0) (the-as region #f)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 5)) - (if (cpad-pressed? 0 square) - (return #f) - ) - (suspend) - ) + (suspend-for (seconds 5) + (if (cpad-pressed? 0 square) + (return #f) + ) ) #f ) @@ -2376,43 +2373,40 @@ (set! (-> gp-0 scale-x) 1.0) (set! (-> gp-0 scale-y) 1.0) (when (and s5-0 (-> gp-0 tex)) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 (seconds 5)) - (let ((f0-2 1.0)) - (cond - ((< f30-0 2.0) - (set! f0-2 (* 0.5 f30-0)) - ) - ((< 3.0 f30-0) - (set! f0-2 (* 0.5 (- 5.0 f30-0))) + (suspend-for (seconds 5) + (let ((f0-2 1.0)) + (cond + ((< f30-0 2.0) + (set! f0-2 (* 0.5 f30-0)) + ) + ((< 3.0 f30-0) + (set! f0-2 (* 0.5 (- 5.0 f30-0))) + ) + ) + (set! (-> gp-0 color w) (the int (* 128.0 f0-2))) + ) + (let* ((s2-0 (-> *display* frames (-> *display* on-screen) global-buf)) + (s3-0 (-> s2-0 base)) ) + (draw gp-0 s2-0 s5-0) + (let ((a3-0 (-> s2-0 base))) + (let ((v1-31 (the-as object (-> s2-0 base)))) + (set! (-> (the-as dma-packet v1-31) dma) (new 'static 'dma-tag :id (dma-tag-id next))) + (set! (-> (the-as dma-packet v1-31) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet v1-31) vif1) (new 'static 'vif-tag)) + (set! (-> s2-0 base) (&+ (the-as pointer v1-31) 16)) ) - (set! (-> gp-0 color w) (the int (* 128.0 f0-2))) - ) - (let* ((s2-0 (-> *display* frames (-> *display* on-screen) global-buf)) - (s3-0 (-> s2-0 base)) - ) - (draw gp-0 s2-0 s5-0) - (let ((a3-0 (-> s2-0 base))) - (let ((v1-31 (the-as object (-> s2-0 base)))) - (set! (-> (the-as dma-packet v1-31) dma) (new 'static 'dma-tag :id (dma-tag-id next))) - (set! (-> (the-as dma-packet v1-31) vif0) (new 'static 'vif-tag)) - (set! (-> (the-as dma-packet v1-31) vif1) (new 'static 'vif-tag)) - (set! (-> s2-0 base) (&+ (the-as pointer v1-31) 16)) - ) - (dma-bucket-insert-tag - (-> *display* frames (-> *display* on-screen) bucket-group) - (bucket-id subtitle) - s3-0 - (the-as (pointer dma-tag) a3-0) - ) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) bucket-group) + (bucket-id subtitle) + s3-0 + (the-as (pointer dma-tag) a3-0) ) ) - (if (not (paused?)) - (+! f30-0 (seconds-per-frame)) - ) - (suspend) ) + (if (not (paused?)) + (+! f30-0 (seconds-per-frame)) + ) ) #f ) @@ -2499,47 +2493,44 @@ ) ) (when (and s4-0 (-> gp-0 tex)) - (let ((s3-0 (current-time))) - (until (time-elapsed? s3-0 (seconds 8)) - (let ((f0-6 1.0)) - (cond - ((< f30-0 2.0) - (set! f0-6 (* 0.5 f30-0)) - ) - ((< 6.0 f30-0) - (set! f0-6 (* 0.5 (- 8.0 f30-0))) + (suspend-for (seconds 8) + (let ((f0-6 1.0)) + (cond + ((< f30-0 2.0) + (set! f0-6 (* 0.5 f30-0)) + ) + ((< 6.0 f30-0) + (set! f0-6 (* 0.5 (- 8.0 f30-0))) + ) + ) + (set! (-> gp-0 color w) (the int (* 128.0 f0-6))) + (set! (-> s5-0 color w) (the int (* 128.0 f0-6))) + ) + (let* ((s1-0 (-> *display* frames (-> *display* on-screen) global-buf)) + (s2-0 (-> s1-0 base)) ) + (draw gp-0 s1-0 s4-0) + (if (-> s5-0 tex) + (draw s5-0 s1-0 s4-0) ) - (set! (-> gp-0 color w) (the int (* 128.0 f0-6))) - (set! (-> s5-0 color w) (the int (* 128.0 f0-6))) - ) - (let* ((s1-0 (-> *display* frames (-> *display* on-screen) global-buf)) - (s2-0 (-> s1-0 base)) - ) - (draw gp-0 s1-0 s4-0) - (if (-> s5-0 tex) - (draw s5-0 s1-0 s4-0) - ) - (let ((a3-0 (-> s1-0 base))) - (let ((v1-59 (the-as object (-> s1-0 base)))) - (set! (-> (the-as dma-packet v1-59) dma) (new 'static 'dma-tag :id (dma-tag-id next))) - (set! (-> (the-as dma-packet v1-59) vif0) (new 'static 'vif-tag)) - (set! (-> (the-as dma-packet v1-59) vif1) (new 'static 'vif-tag)) - (set! (-> s1-0 base) (&+ (the-as pointer v1-59) 16)) - ) - (dma-bucket-insert-tag - (-> *display* frames (-> *display* on-screen) bucket-group) - (bucket-id subtitle) - s2-0 - (the-as (pointer dma-tag) a3-0) - ) + (let ((a3-0 (-> s1-0 base))) + (let ((v1-59 (the-as object (-> s1-0 base)))) + (set! (-> (the-as dma-packet v1-59) dma) (new 'static 'dma-tag :id (dma-tag-id next))) + (set! (-> (the-as dma-packet v1-59) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet v1-59) vif1) (new 'static 'vif-tag)) + (set! (-> s1-0 base) (&+ (the-as pointer v1-59) 16)) ) - ) - (if (not (paused?)) - (+! f30-0 (seconds-per-frame)) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) bucket-group) + (bucket-id subtitle) + s2-0 + (the-as (pointer dma-tag) a3-0) ) - (suspend) + ) ) + (if (not (paused?)) + (+! f30-0 (seconds-per-frame)) + ) ) #f ) diff --git a/test/decompiler/reference/jak2/levels/mountain/mountain-obs_REF.gc b/test/decompiler/reference/jak2/levels/mountain/mountain-obs_REF.gc index d70d801b2a..ca4520ee32 100644 --- a/test/decompiler/reference/jak2/levels/mountain/mountain-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/mountain/mountain-obs_REF.gc @@ -2038,20 +2038,14 @@ (suspend) ) (set-setting! 'entity-name "camera-259" 0.0 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (ja-no-eval :group! (ja-group) :num! (seek!) :frame-num 0.0) (until (ja-done? 0) (suspend) (ja :num! (seek!)) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (until (process-release? *target*) (suspend) diff --git a/test/decompiler/reference/jak2/levels/nest/boss/nestb-scenes_REF.gc b/test/decompiler/reference/jak2/levels/nest/boss/nestb-scenes_REF.gc index 2176e0c748..84d2eb72ac 100644 --- a/test/decompiler/reference/jak2/levels/nest/boss/nestb-scenes_REF.gc +++ b/test/decompiler/reference/jak2/levels/nest/boss/nestb-scenes_REF.gc @@ -15,16 +15,10 @@ (set! (-> a1-0 message) 'test-pickup) (set! (-> a1-0 param 0) (the-as uint 7)) (let ((f30-0 (send-event-function *target* a1-0))) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (send-event *target* 'change-mode 'darkjak #f (darkjak-stage no-anim)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (send-event *target* 'get-pickup (pickup-type eco-pill-dark) f30-0) ) diff --git a/test/decompiler/reference/jak2/levels/nest/mantis_REF.gc b/test/decompiler/reference/jak2/levels/nest/mantis_REF.gc index 6935dfc33e..7e3488da4d 100644 --- a/test/decompiler/reference/jak2/levels/nest/mantis_REF.gc +++ b/test/decompiler/reference/jak2/levels/nest/mantis_REF.gc @@ -568,16 +568,10 @@ ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.6)) - (suspend) - ) + (suspend-for (seconds 0.6) ) (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6))) ) (logclear! (-> self draw status) (draw-control-status no-draw)) (if (rnd-percent? self 0.5) @@ -684,13 +678,10 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (if (logtest? (-> self root status) (collide-status on-ground)) - (goto cfg-32) - ) - (suspend) - ) + (suspend-for (seconds 1) + (if (logtest? (-> self root status) (collide-status on-ground)) + (goto cfg-32) + ) ) (label cfg-32) (go-virtual hostile) diff --git a/test/decompiler/reference/jak2/levels/nest/nest-obs_REF.gc b/test/decompiler/reference/jak2/levels/nest/nest-obs_REF.gc index fca3252915..da75a91f2b 100644 --- a/test/decompiler/reference/jak2/levels/nest/nest-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/nest/nest-obs_REF.gc @@ -105,21 +105,15 @@ (set! (-> self root trans y) (+ (-> self y-start) (-> self y-delta))) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (seek! (-> self y-rot-rate) 0.0 (* 4000.0 (seconds-per-frame))) - (quaternion-rotate-y! - (-> self root quat) - (-> self root quat) - (* 182.04445 (seconds-per-frame) (-> self y-rot-rate)) - ) - (suspend) + (suspend-for (seconds 1) + (seek! (-> self y-rot-rate) 0.0 (* 4000.0 (seconds-per-frame))) + (quaternion-rotate-y! + (-> self root quat) + (-> self root quat) + (* 182.04445 (seconds-per-frame) (-> self y-rot-rate)) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (remove-setting! 'entity-name) (remove-setting! 'process-mask) @@ -238,10 +232,7 @@ :virtual #t :trans rider-trans :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (< (-> self y-offset) 16384.0) (seek! (-> self y-offset) 16384.0 (* 8192.0 (seconds-per-frame))) diff --git a/test/decompiler/reference/jak2/levels/sewer/sew-gunturret_REF.gc b/test/decompiler/reference/jak2/levels/sewer/sew-gunturret_REF.gc index c39c692e47..9e3c0ef71d 100644 --- a/test/decompiler/reference/jak2/levels/sewer/sew-gunturret_REF.gc +++ b/test/decompiler/reference/jak2/levels/sewer/sew-gunturret_REF.gc @@ -803,51 +803,42 @@ ) (update-collision! self) (sound-play "sew-gun-lock") - (let ((frame-counter (current-time))) - (until (time-elapsed? frame-counter (seconds 0.75)) - (aim-turret! self #t) - (suspend) - ) + (suspend-for (seconds 0.75) + (aim-turret! self #t) ) (ja :group! (-> self draw art-group data (-> self params shoot-anim))) (let ((frames 0) (fire-sound? #t) ) (sound-play "gturret") - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.125)) - (cond - ((not (-> self can-shoot)) - ) - ((time-elapsed? (the-as time-frame frames) (seconds 0.05)) - (fire-turret! self fire-sound?) - (set! frames (the-as int (current-time))) - (set! fire-sound? (not fire-sound?)) - ) - (else - (set! (-> self flash-state) #f) - ) + (suspend-for (seconds 0.125) + (cond + ((not (-> self can-shoot)) + ) + ((time-elapsed? (the-as time-frame frames) (seconds 0.05)) + (fire-turret! self fire-sound?) + (set! frames (the-as int (current-time))) + (set! fire-sound? (not fire-sound?)) + ) + (else + (set! (-> self flash-state) #f) ) - (ja :num! (loop!)) - (suspend) ) + (ja :num! (loop!)) ) ) (set! (-> self flash-state) #f) (ja-channel-push! 1 (seconds 0.2)) (ja :group! (-> self draw art-group data (-> self params idle-anim))) - (let ((_frame-counter (current-time))) - (until (time-elapsed? _frame-counter (seconds 0.5)) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 0))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 1))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 2))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 3))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 4))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 5))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 6))) - (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 7))) - (suspend) - ) + (suspend-for (seconds 0.5) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 0))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 1))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 2))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 3))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 4))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 5))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 6))) + (spawn-with-cspace (-> self smoke-part) (-> self node-list data (-> self params hole-joints 7))) ) ) #f @@ -938,17 +929,11 @@ (let ((vec (new 'stack-no-clear 'vector))) (set! (-> vec quad) (-> self root trans quad)) (+! (-> vec y) 10240.0) - (let ((frame-counter (current-time))) - (until (time-elapsed? frame-counter (seconds 2)) - (spawn (-> self part) vec) - (suspend) - ) + (suspend-for (seconds 2) + (spawn (-> self part) vec) ) ) - (let ((_frame-counter (current-time))) - (until (time-elapsed? _frame-counter (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (while (-> self child) diff --git a/test/decompiler/reference/jak2/levels/sewer/sewer-obs2_REF.gc b/test/decompiler/reference/jak2/levels/sewer/sewer-obs2_REF.gc index d3f3707d00..e6098c9305 100644 --- a/test/decompiler/reference/jak2/levels/sewer/sewer-obs2_REF.gc +++ b/test/decompiler/reference/jak2/levels/sewer/sewer-obs2_REF.gc @@ -1000,10 +1000,7 @@ ) ) (cleanup-for-death self) - (let ((frame-counter (current-time))) - (until (time-elapsed? frame-counter (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) ) diff --git a/test/decompiler/reference/jak2/levels/stadium/skate/skatea-obs_REF.gc b/test/decompiler/reference/jak2/levels/stadium/skate/skatea-obs_REF.gc index 174dfd17f6..d091e42374 100644 --- a/test/decompiler/reference/jak2/levels/stadium/skate/skatea-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/stadium/skate/skatea-obs_REF.gc @@ -384,10 +384,7 @@ (suspend) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #t) (set! (-> self last-sound-id) @@ -425,10 +422,7 @@ (suspend) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #t) (set! (-> self last-sound-id) @@ -499,10 +493,7 @@ (while (nonzero? (get-status *gui-control* (-> self last-sound-id))) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (set! (-> self last-sound-id) (add-process *gui-control* self (gui-channel sig) (gui-action play) "kei013" -99.0 0) @@ -565,10 +556,7 @@ (suspend) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #t) (set! (-> self last-sound-id) @@ -606,10 +594,7 @@ (suspend) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #t) (set! (-> self last-sound-id) @@ -644,10 +629,7 @@ (suspend) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #f) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event (handle->process (-> self voicebox)) 'speak-effect #t) (set! (-> self last-sound-id) @@ -1131,10 +1113,7 @@ t1-3 ) ) - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event (handle->process gp-3) 'die) ) @@ -1337,10 +1316,7 @@ t1-3 ) ) - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event (handle->process gp-2) 'die) ) diff --git a/test/decompiler/reference/jak2/levels/stadium/stadium-obs_REF.gc b/test/decompiler/reference/jak2/levels/stadium/stadium-obs_REF.gc index 5007ab614d..303fb29e69 100644 --- a/test/decompiler/reference/jak2/levels/stadium/stadium-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/stadium/stadium-obs_REF.gc @@ -955,10 +955,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.2)) - (suspend) - ) + (suspend-for (seconds 1.2) ) (rigid-body-object-method-39 self) (sleep-code) @@ -1638,10 +1635,7 @@ ) ) (set! (-> self rift-rider-actor) (entity-actor-lookup (-> self entity) 'alt-actor 0)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.31)) - (suspend) - ) + (suspend-for (seconds 0.31) ) ) (ja-no-eval :group! (-> self draw art-group data (-> self stand-anim)) :num! (seek!) :frame-num 0.0) @@ -2067,10 +2061,7 @@ ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (send-event *camera* 'change-target #f) (cleanup-for-death self) diff --git a/test/decompiler/reference/jak2/levels/title/title-obs_REF.gc b/test/decompiler/reference/jak2/levels/title/title-obs_REF.gc index e574eead32..32435c5a59 100644 --- a/test/decompiler/reference/jak2/levels/title/title-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/title/title-obs_REF.gc @@ -588,10 +588,7 @@ ;; WARN: Return type mismatch int vs none. (defun title-fade-out ((arg0 float)) (setup *screen-filter* (new 'static 'vector) (new 'static 'vector :w 128.0) arg0 (bucket-id screen-filter)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.4)) - (suspend) - ) + (suspend-for (seconds 0.4) ) (send-event (ppointer->process (-> *setting-control* user-current movie)) 'abort) (set! (-> *setting-control* user-current bg-a) 0.0) diff --git a/test/decompiler/reference/jak2/levels/tomb/target-indax_REF.gc b/test/decompiler/reference/jak2/levels/tomb/target-indax_REF.gc index 9d4fd1bf81..3e409150fb 100644 --- a/test/decompiler/reference/jak2/levels/tomb/target-indax_REF.gc +++ b/test/decompiler/reference/jak2/levels/tomb/target-indax_REF.gc @@ -1298,10 +1298,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (move-to-point! (-> self control) s4-1) ) diff --git a/test/decompiler/reference/jak2/levels/tomb/tomb-beetle_REF.gc b/test/decompiler/reference/jak2/levels/tomb/tomb-beetle_REF.gc index 2a5d06e90c..dc365ff0d7 100644 --- a/test/decompiler/reference/jak2/levels/tomb/tomb-beetle_REF.gc +++ b/test/decompiler/reference/jak2/levels/tomb/tomb-beetle_REF.gc @@ -779,10 +779,7 @@ (-> gp-1 ppointer) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) :post nav-enemy-simple-post diff --git a/test/decompiler/reference/jak2/levels/tomb/tomb-water_REF.gc b/test/decompiler/reference/jak2/levels/tomb/tomb-water_REF.gc index 162bfe7405..be62ea8612 100644 --- a/test/decompiler/reference/jak2/levels/tomb/tomb-water_REF.gc +++ b/test/decompiler/reference/jak2/levels/tomb/tomb-water_REF.gc @@ -110,10 +110,7 @@ ) ) :code (behavior ((arg0 time-frame)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 arg0) - (suspend) - ) + (suspend-for arg0 ) (ja-no-eval :group! tomb-door-open-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) @@ -1051,10 +1048,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (go-virtual show-sequence) ) @@ -1517,16 +1511,10 @@ :virtual #t :code (behavior () (set! (-> self move-rate) (* 4096.0 (rand-vu-float-range 0.5 1.5))) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (logclear! (-> self root root-prim prim-core action) (collide-action rideable)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (cleanup-for-death self) ) @@ -1976,10 +1964,7 @@ ) ) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.45)) - (suspend) - ) + (suspend-for (seconds 0.45) ) ) #f @@ -2120,10 +2105,7 @@ 0 ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (persist-with-delay *setting-control* @@ -2134,10 +2116,7 @@ 0.0 (+ (-> self pat-tbl (-> self pat-index)) 18) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (process-grab? *target* #f) (let ((gp-2 (current-time)) @@ -2456,10 +2435,8 @@ :code (behavior () (until #f (set! (-> self can-exit-running?) #f) - (let ((gp-0 0) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 (-> self on-duration)) + (let ((gp-0 0)) + (suspend-for (-> self on-duration) (when (< (-> self harmless-time) (current-time)) (tomb-water-trap-method-22 self) (dotimes (s4-0 (+ (-> self path curve num-cverts) -1)) @@ -2497,29 +2474,19 @@ (+! gp-0 1) ) ) - (suspend) ) ) (set! (-> self can-exit-running?) #t) (let ((gp-1 90)) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 gp-1) - (suspend) - ) + (suspend-for gp-1 ) - (let ((s5-2 #f) - (s4-2 (current-time)) - ) - (until (time-elapsed? - s4-2 - (the-as time-frame (- (- (-> self sync period) (the-as uint (-> self on-duration))) (the-as uint gp-1))) - ) - (when (and (not s5-2) (time-elapsed? s4-2 (seconds 0.3))) + (let ((s5-2 #f)) + (suspend-for (the-as time-frame (- (- (-> self sync period) (the-as uint (-> self on-duration))) (the-as uint gp-1))) + (when (and (not s5-2) (time-elapsed? time (seconds 0.3))) (set! s5-2 #t) (set-tombc-electricity-scale! 0.0) ) (seek! (-> self volume) 0.0 (* 2.0 (seconds-per-frame))) - (suspend) ) ) ) diff --git a/test/decompiler/reference/jak2/levels/under/under-sig-obs_REF.gc b/test/decompiler/reference/jak2/levels/under/under-sig-obs_REF.gc index 8b365f37af..0aad05ccdf 100644 --- a/test/decompiler/reference/jak2/levels/under/under-sig-obs_REF.gc +++ b/test/decompiler/reference/jak2/levels/under/under-sig-obs_REF.gc @@ -556,10 +556,7 @@ ) (suspend) (ja-channel-set! 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (while (-> self child) diff --git a/test/decompiler/reference/jak3/decompiler-macros.gc b/test/decompiler/reference/jak3/decompiler-macros.gc index 1792400728..a8875a6bbb 100644 --- a/test/decompiler/reference/jak3/decompiler-macros.gc +++ b/test/decompiler/reference/jak3/decompiler-macros.gc @@ -263,6 +263,13 @@ ) ) +(defmacro call-parent-state-handler (handler &key (type (function none)) &rest args) + "Call the parent handler for this state." + `(let ((handler (-> (find-parent-state) ,handler))) + (if handler ((the ,type handler) ,@args)) + ) + ) + (defmacro call-parent-method (&rest args) "Find the first different implementation of the current method in a parent type and call it with these arguments." `((the (current-method-function-type) (find-parent-method (current-method-type) (current-method-id))) @@ -945,6 +952,9 @@ `(set! ,time (current-time)) ) +(defmacro suspend-for (time &rest body) + `(let ((time (current-time))) (until (time-elapsed? time ,time) ,@body (suspend)))) + (defconstant *scratch-memory-top* (the pointer #x70004000)) (defconstant DPROCESS_STACK_SIZE #x8000) @@ -979,7 +989,7 @@ (with-gensyms (new-proc) `(let ((,new-proc (the-as ,proc-type (get-process ,from ,proc-type ,stack-size ,unk)))) (when ,new-proc - ((method-of-type ,proc-type activate) ,new-proc ,to ,(if name name `(symbol->string ,proc-type)) ,stack) + ((method-of-type ,proc-type activate) ,new-proc ,to ,(if name name `(symbol->string ',proc-type)) ,stack) (run-now-in-process ,new-proc ,(if init init (string->symbol (fmt #f "{}-init-by-other" proc-type))) ,@args) (the (pointer ,proc-type) (-> ,new-proc ppointer)) ) diff --git a/test/decompiler/reference/jak3/engine/ambient/ambient_REF.gc b/test/decompiler/reference/jak3/engine/ambient/ambient_REF.gc index f469836472..7183886514 100644 --- a/test/decompiler/reference/jak3/engine/ambient/ambient_REF.gc +++ b/test/decompiler/reference/jak3/engine/ambient/ambient_REF.gc @@ -399,10 +399,7 @@ (defstate idle (talker) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (the-as time-frame (-> self message delay))) - (suspend) - ) + (suspend-for (the-as time-frame (-> self message delay)) ) (while (or (not (time-elapsed? (-> self start-time) (the-as time-frame (+ (-> self message delay) 300)))) (and (logtest? (-> self message flags) (talker-flags tf8)) @@ -585,10 +582,7 @@ ) ) (when (and (logtest? (-> self message flags) (talker-flags tf3)) (not (-> self save?))) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (set! (-> self save?) #t) (auto-save-user) diff --git a/test/decompiler/reference/jak3/engine/common-obs/collectables_REF.gc b/test/decompiler/reference/jak3/engine/common-obs/collectables_REF.gc index 7e1ca3a4a4..3a91e18c44 100644 --- a/test/decompiler/reference/jak3/engine/common-obs/collectables_REF.gc +++ b/test/decompiler/reference/jak3/engine/common-obs/collectables_REF.gc @@ -1356,11 +1356,7 @@ (if (not (logtest? (-> self fact options) (actor-option no-reaction))) (send-event (handle->process arg1) 'powerup (-> self fact pickup-type) (-> self fact pickup-amount)) ) - (let ((t9-2 (-> (find-parent-state) code))) - (if t9-2 - ((the-as (function none) t9-2)) - ) - ) + (call-parent-state-handler code) ) ) diff --git a/test/decompiler/reference/jak3/engine/common-obs/crates_REF.gc b/test/decompiler/reference/jak3/engine/common-obs/crates_REF.gc index 191d10ac8a..144334993a 100644 --- a/test/decompiler/reference/jak3/engine/common-obs/crates_REF.gc +++ b/test/decompiler/reference/jak3/engine/common-obs/crates_REF.gc @@ -988,10 +988,7 @@ ) ) (when (not arg0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.04)) - (suspend) - ) + (suspend-for (seconds 0.04) ) (case (-> self look) (('iron) @@ -1084,16 +1081,10 @@ (drop-pickup (-> self fact) #t *entity-pool* (the-as fact-info #f) arg1 #t) (process-entity-status! self (entity-perm-status dead) #t) (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) (when (logtest? (actor-option cond-respawn) (-> self fact options)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 15)) - (suspend) - ) + (suspend-for (seconds 15) ) (go-virtual hide) ) diff --git a/test/decompiler/reference/jak3/engine/common-obs/enemy-states_REF.gc b/test/decompiler/reference/jak3/engine/common-obs/enemy-states_REF.gc index eba5b3c241..207cfc96ea 100644 --- a/test/decompiler/reference/jak3/engine/common-obs/enemy-states_REF.gc +++ b/test/decompiler/reference/jak3/engine/common-obs/enemy-states_REF.gc @@ -678,10 +678,7 @@ :code (behavior () (cond ((handle->process (-> self ragdoll-proc)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (until (ragdoll-settled? self) (if (or (time-elapsed? (-> self state-time) (seconds 4)) (enemy-method-109 self)) @@ -992,18 +989,12 @@ :code (behavior () (cond ((handle->process (-> self ragdoll-proc)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (if (-> self skel effect) (do-effect (-> self skel effect) "death-default" 0.0 -1) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.8)) - (suspend) - ) + (suspend-for (seconds 0.8) ) ) (else @@ -1088,18 +1079,12 @@ :code (behavior () (cond ((handle->process (-> self ragdoll-proc)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (if (-> self skel effect) (do-effect (-> self skel effect) "death-default" 0.0 -1) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (deactivate-ragdoll! self) ) diff --git a/test/decompiler/reference/jak3/engine/common-obs/generic-obs_REF.gc b/test/decompiler/reference/jak3/engine/common-obs/generic-obs_REF.gc index bd12e0812b..ddfab9654b 100644 --- a/test/decompiler/reference/jak3/engine/common-obs/generic-obs_REF.gc +++ b/test/decompiler/reference/jak3/engine/common-obs/generic-obs_REF.gc @@ -234,11 +234,8 @@ (swingpole-method-22 self) (suspend) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (swingpole-method-22 self) - (suspend) - ) + (suspend-for (seconds 0.5) + (swingpole-method-22 self) ) (go-virtual idle) ) @@ -4605,10 +4602,7 @@ (set-setting! 'mode-name 'cam-fixed 0.0 0) (set-setting! 'interp-time 'abs 450.0 0) (set-setting! 'entity-name (res-lump-struct (-> self entity) 'camera-name structure) 0.0 0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (-> self pause-time)) - (suspend) - ) + (suspend-for (-> self pause-time) ) (if (-> self blur) (set-setting! 'blur-a 'abs 0.5 0) @@ -4616,19 +4610,13 @@ (remove-setting! 'mode-name) (remove-setting! 'entity-name) (remove-setting! 'interp-time) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (while (not (process-release? *target*)) (suspend) ) (remove-setting! 'interp-time) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (remove-setting! 'blur-a) (process-entity-status! self (entity-perm-status no-kill) #f) @@ -4702,7 +4690,7 @@ :trans (behavior () (set! (-> self task-counter) (-> *game-info* task-counter)) (if *bigmap* - (bigmap-method-16 *bigmap*) + (set-map-indices! *bigmap*) ) (let ((gp-0 (res-lump-struct (-> self entity) 'on-running structure))) (cond diff --git a/test/decompiler/reference/jak3/engine/common-obs/powerups_REF.gc b/test/decompiler/reference/jak3/engine/common-obs/powerups_REF.gc index 653a5c7adc..fa04de7863 100644 --- a/test/decompiler/reference/jak3/engine/common-obs/powerups_REF.gc +++ b/test/decompiler/reference/jak3/engine/common-obs/powerups_REF.gc @@ -16,25 +16,22 @@ (let ((s1-1 (process->handle arg0)) (s2-1 (process->handle arg1)) ) - (let ((s0-0 (current-time))) - (until (time-elapsed? s0-0 (+ arg3 arg4)) - (let ((v1-8 (or (not (handle->process s1-1)) (not (handle->process s2-1))))) - (if v1-8 - (deactivate self) - ) - ) - (let* ((f0-1 (fmax 0.0 (fmin 1.0 (/ (- (the float (- (current-time) s0-0)) (the float arg3)) (the float arg4))))) - (a0-18 (process-drawable-pair-random-point! - (the-as process-drawable (-> s1-1 process 0)) - (the-as process-drawable (-> s2-1 process 0)) - (new-stack-vector0) - f0-1 - ) + (suspend-for (+ arg3 arg4) + (let ((v1-8 (or (not (handle->process s1-1)) (not (handle->process s2-1))))) + (if v1-8 + (deactivate self) + ) + ) + (let* ((f0-1 (fmax 0.0 (fmin 1.0 (/ (- (the float (- (current-time) time)) (the float arg3)) (the float arg4))))) + (a0-18 (process-drawable-pair-random-point! + (the-as process-drawable (-> s1-1 process 0)) + (the-as process-drawable (-> s2-1 process 0)) + (new-stack-vector0) + f0-1 ) - ) - (arg2 a0-18) - ) - (suspend) + ) + ) + (arg2 a0-18) ) ) (cond @@ -45,12 +42,9 @@ #f ) (else - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 arg5) - (let ((a0-21 (process-drawable-random-point! (the-as process-drawable (-> s2-1 process 0)) (new-stack-vector0)))) - (arg2 a0-21) - ) - (suspend) + (suspend-for arg5 + (let ((a0-21 (process-drawable-random-point! (the-as process-drawable (-> s2-1 process 0)) (new-stack-vector0)))) + (arg2 a0-21) ) ) ) diff --git a/test/decompiler/reference/jak3/engine/common-obs/warp-gate_REF.gc b/test/decompiler/reference/jak3/engine/common-obs/warp-gate_REF.gc index 0365032b62..7d74ee44dc 100644 --- a/test/decompiler/reference/jak3/engine/common-obs/warp-gate_REF.gc +++ b/test/decompiler/reference/jak3/engine/common-obs/warp-gate_REF.gc @@ -726,10 +726,7 @@ (set-blackout-frames (seconds 0.05)) ) (start 'play arg0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (and *target* (and (>= 81920.0 (vector-vector-distance (-> self root trans) (-> *target* control trans))) (not (logtest? (focus-status teleporting) (-> *target* focus-status))) diff --git a/test/decompiler/reference/jak3/engine/game/game-info_REF.gc b/test/decompiler/reference/jak3/engine/game/game-info_REF.gc index ac7e7b1ca7..ef71a8624a 100644 --- a/test/decompiler/reference/jak3/engine/game/game-info_REF.gc +++ b/test/decompiler/reference/jak3/engine/game/game-info_REF.gc @@ -592,7 +592,7 @@ (dotimes (v1-96 (-> this game-score length)) (set! (-> this game-score v1-96) 0.0) ) - ((method-of-object *bigmap* bigmap-method-9)) + (initialize *bigmap*) ) ) (case mode @@ -1114,25 +1114,19 @@ (set! (-> v1-9 origin z) (the float (/ (-> s3-0 z) 16))) ) (set! (-> s5-0 flags) (font-flags shadow kerning large)) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (+ arg2 -75)) - (+! (-> s5-0 origin y) (* -120.0 (seconds-per-frame))) - (let ((s2-0 print-game-text)) - (format (clear *temp-string*) "~4,,0f" arg1) - (s2-0 *temp-string* s5-0 #f 44 (bucket-id debug-no-zbuf1)) - ) - (suspend) + (suspend-for (+ arg2 -75) + (+! (-> s5-0 origin y) (* -120.0 (seconds-per-frame))) + (let ((s2-0 print-game-text)) + (format (clear *temp-string*) "~4,,0f" arg1) + (s2-0 *temp-string* s5-0 #f 44 (bucket-id debug-no-zbuf1)) ) ) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.25)) - (set! (-> s5-0 alpha) (lerp-scale 1.0 0.0 (the float (- (current-time) s4-1)) 0.0 150.0)) - (+! (-> s5-0 origin y) (* -120.0 (seconds-per-frame))) - (let ((s3-2 print-game-text)) - (format (clear *temp-string*) "~4,,0f" arg1) - (s3-2 *temp-string* s5-0 #f 44 (bucket-id debug-no-zbuf1)) - ) - (suspend) + (suspend-for (seconds 0.25) + (set! (-> s5-0 alpha) (lerp-scale 1.0 0.0 (the float (- (current-time) time)) 0.0 150.0)) + (+! (-> s5-0 origin y) (* -120.0 (seconds-per-frame))) + (let ((s3-2 print-game-text)) + (format (clear *temp-string*) "~4,,0f" arg1) + (s3-2 *temp-string* s5-0 #f 44 (bucket-id debug-no-zbuf1)) ) ) ) @@ -1610,11 +1604,8 @@ process (lambda :behavior process ((arg0 string)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 10)) - (format *stdcon* "~S~%" arg0) - (suspend) - ) + (suspend-for (seconds 10) + (format *stdcon* "~S~%" arg0) ) (none) ) @@ -2226,7 +2217,3 @@ ;; failed to figure out what this is: (kmemclose) - - - - diff --git a/test/decompiler/reference/jak3/engine/game/main_REF.gc b/test/decompiler/reference/jak3/engine/game/main_REF.gc index dc3cdea417..ba6b29cf39 100644 --- a/test/decompiler/reference/jak3/engine/game/main_REF.gc +++ b/test/decompiler/reference/jak3/engine/game/main_REF.gc @@ -475,10 +475,7 @@ (set! (-> *setting-control* user-default music-volume) 0.0) (set! (-> *setting-control* user-default dialog-volume) 0.0) (set! (-> *setting-control* user-default ambient-volume) 0.0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (kernel-shutdown arg0) (none) @@ -1745,7 +1742,7 @@ ) 0 ) - (blit-displays-work-method-19 *blit-displays-work*) + (do-blit-displays *blit-displays-work*) (when *debug-segment* (let ((s5-12 (-> *display* frames (-> *display* on-screen) profile-array data 0))) (when (and *dproc* *debug-segment*) diff --git a/test/decompiler/reference/jak3/engine/game/settings_REF.gc b/test/decompiler/reference/jak3/engine/game/settings_REF.gc index 4a5bd3a0c2..0c63088b63 100644 --- a/test/decompiler/reference/jak3/engine/game/settings_REF.gc +++ b/test/decompiler/reference/jak3/engine/game/settings_REF.gc @@ -1840,7 +1840,7 @@ (-> s4-0 blur-a) (* (-> s5-0 blur-a-speed) (-> *display* real-clock seconds-per-frame)) ) - (blit-displays-work-method-17 + (setup-zoom-blur-2d *blit-displays-work* (new 'static 'vector :x 256.0 :y 208.0 :w 1.0) s3-10 diff --git a/test/decompiler/reference/jak3/engine/game/task/task-control_REF.gc b/test/decompiler/reference/jak3/engine/game/task/task-control_REF.gc index 6535e93e3c..208f9163c9 100644 --- a/test/decompiler/reference/jak3/engine/game/task/task-control_REF.gc +++ b/test/decompiler/reference/jak3/engine/game/task/task-control_REF.gc @@ -2622,16 +2622,13 @@ (process-release? *target*) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (let ((f30-0 (lerp-scale 1.0 0.0 (the float (- (current-time) gp-0)) 0.0 300.0))) - (set-filter-color! - (lerp-scale 1.0 1.25 f30-0 0.0 1.0) - (lerp-scale 1.0 0.875 f30-0 0.0 1.0) - (lerp-scale 1.0 0.25 f30-0 0.0 1.0) - ) + (suspend-for (seconds 1) + (let ((f30-0 (lerp-scale 1.0 0.0 (the float (- (current-time) time)) 0.0 300.0))) + (set-filter-color! + (lerp-scale 1.0 1.25 f30-0 0.0 1.0) + (lerp-scale 1.0 0.875 f30-0 0.0 1.0) + (lerp-scale 1.0 0.25 f30-0 0.0 1.0) ) - (suspend) ) ) (let ((gp-1 (if (-> self retry?) diff --git a/test/decompiler/reference/jak3/engine/gfx/blit-displays-h_REF.gc b/test/decompiler/reference/jak3/engine/gfx/blit-displays-h_REF.gc index 44600e6774..39d5fff9c7 100644 --- a/test/decompiler/reference/jak3/engine/gfx/blit-displays-h_REF.gc +++ b/test/decompiler/reference/jak3/engine/gfx/blit-displays-h_REF.gc @@ -18,7 +18,7 @@ (zoom-blur-texels int32) (zoom-blur-alpha-target float) (zoom-blur-alpha-current float) - (zoom-blur-2d basic) + (zoom-blur-2d symbol) (menu-mode symbol) (screen-copied symbol) (vu1-enable-user-menu vu1-renderer-mask) @@ -33,18 +33,18 @@ (slow-time float) ) (:methods - (blit-displays-work-method-9 () none) - (blit-displays-work-method-10 () none) - (blit-displays-work-method-11 () none) - (blit-displays-work-method-12 () none) - (blit-displays-work-method-13 () none) - (blit-displays-work-method-14 () none) - (blit-displays-work-method-15 () none) - (blit-displays-work-method-16 () none) - (blit-displays-work-method-17 (_type_ vector int float symbol) none) - (blit-displays-work-method-18 () none) - (blit-displays-work-method-19 (_type_) none) - (blit-displays-work-method-20 (_type_) none) + (blit-displays-work-method-9 (_type_ dma-buffer int int int) none) + (blit-displays-work-method-10 (_type_ dma-buffer int int int) none) + (blit-displays-work-method-11 (_type_ dma-buffer int) none) + (draw-letterbox (_type_ dma-buffer float int float) none) + (blit-displays-work-method-13 (_type_ dma-buffer int int int) none) + (blit-displays-work-method-14 (_type_ dma-buffer vector) none) + (blit-displays-work-method-15 (_type_ dma-buffer) none) + (draw-zoom-blur (_type_ dma-buffer int) none) + (setup-zoom-blur-2d (_type_ vector int float symbol) none) + (setup-brightness-and-contrast (_type_ dma-buffer float float) none) + (do-blit-displays (_type_) none) + (draw-sky (_type_ dma-buffer) none) (get-menu-mode (_type_) symbol) (get-screen-copied (_type_) symbol) (get-horizontal-flip-flag (_type_) symbol) @@ -128,3 +128,7 @@ ;; failed to figure out what this is: 0 + + + + diff --git a/test/decompiler/reference/jak3/engine/gfx/blit-displays_REF.gc b/test/decompiler/reference/jak3/engine/gfx/blit-displays_REF.gc new file mode 100644 index 0000000000..6f271d85ff --- /dev/null +++ b/test/decompiler/reference/jak3/engine/gfx/blit-displays_REF.gc @@ -0,0 +1,940 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition for symbol *blit-displays-work*, type blit-displays-work +(define *blit-displays-work* (new 'static 'blit-displays-work + :adgif-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x6 :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x6 :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x1000000000008005 #xe) + ) + :sprite-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x41 :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x41 :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x408b400000008010 #x5353) + ) + :contrast-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x41 :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x41 :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x40ab400000008010 #x5353) + ) + :sprite-slow-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x6 :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x6 :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x50ab400000008001 #x53531) + ) + :draw-slow-time-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x13 :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x13 :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x30aec00000008006 #x531) + ) + :line-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x41 :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x41 :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x2020c00000008020 #x55) + ) + :scan-tmpl (new 'static 'dma-gif-packet + :dma-vif (new 'static 'dma-packet + :dma (new 'static 'dma-tag :qwc #x4c :id (dma-tag-id cnt)) + :vif1 (new 'static 'vif-tag :imm #x4c :cmd (vif-cmd direct) :msk #x1) + ) + :gif (new 'static 'array uint64 2 #x5020c0000000800f #x55551) + ) + :color (new 'static 'vector4w :x #x80 :y #x80 :z #x80 :w #x80) + :line-color #x3f80000000000000 + :scan-colors (new 'static 'inline-array vector4w 15 + (new 'static 'vector4w :y 1 :z 1) + (new 'static 'vector4w :y 1 :z 1) + (new 'static 'vector4w :y 1 :z 1) + (new 'static 'vector4w :y 1 :z 1) + (new 'static 'vector4w :x 1 :y 3 :z 2) + (new 'static 'vector4w :x 1 :y 4 :z 3) + (new 'static 'vector4w :x 2 :y 6 :z 5) + (new 'static 'vector4w :x 3 :y 8 :z 7) + (new 'static 'vector4w :x 5 :y 11 :z 10) + (new 'static 'vector4w :x 6 :y 14 :z 13) + (new 'static 'vector4w :x 9 :y 20 :z 17) + (new 'static 'vector4w :x 13 :y 27 :z 21) + (new 'static 'vector4w :x 17 :y 36 :z 24) + (new 'static 'vector4w :x 22 :y 45 :z 28) + (new 'static 'vector4w :x 32 :y 63 :z 32) + ) + :menu-mode #f + :screen-copied #f + :horizontal-flip-flag #f + ) + ) + +;; definition for method 9 of type blit-displays-work +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod blit-displays-work-method-9 ((this blit-displays-work) (arg0 dma-buffer) (arg1 int) (arg2 int) (arg3 int)) + (let ((v1-0 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-0) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-0) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 2) 128 128 128 arg3) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 3) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 4) 0 0 #xffffff 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 5) 8184 (+ (* (+ arg1 -1) 16) 8) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 6) #x2800 (* arg2 16) #xffffff #x10000) + ) + (&+! (-> arg0 base) 112) + 0 + (none) + ) + +;; definition for method 10 of type blit-displays-work +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod blit-displays-work-method-10 ((this blit-displays-work) (arg0 dma-buffer) (arg1 int) (arg2 int) (arg3 int)) + (let ((v1-0 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-0) 0 quad) (-> this draw-slow-time-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-0) 1 quad) (-> this draw-slow-time-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 2) 96 96 96 192) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 3) 4088 3320 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 4) 5120 (* arg2 8) #xffffff #x10000) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 5) 128 128 128 arg3) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 6) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 7) 0 0 #xffffff 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 8) 128 128 128 arg3) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 9) 8184 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 10) #x2800 0 #xffffff #x10000) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 11) 128 128 128 arg3) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 12) 8184 (+ (* (+ arg1 -1) 16) 8) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 13) #x2800 (* arg2 16) #xffffff #x10000) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 14) 128 128 128 arg3) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 15) 8 (+ (* (+ arg1 -1) 16) 8) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 16) 0 (* arg2 16) #xffffff #x10000) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 17) 128 128 128 arg3) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 18) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 19) 0 0 #xffffff 0) + ) + (&+! (-> arg0 base) 320) + 0 + (none) + ) + +;; definition for method 11 of type blit-displays-work +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod blit-displays-work-method-11 ((this blit-displays-work) (arg0 dma-buffer) (arg1 int)) + (let ((v1-0 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-0) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-0) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) v1-0) 2 quad) (-> this color quad)) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 3) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 4) 0 0 #xffffff 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 5) #x27f8 (+ (* (+ arg1 -1) 16) 8) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 6) 8192 6656 #xffffff #x10000) + ) + (&+! (-> arg0 base) 112) + 0 + (none) + ) + +;; definition for method 12 of type blit-displays-work +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod draw-letterbox ((this blit-displays-work) (arg0 dma-buffer) (arg1 float) (arg2 int) (arg3 float)) + (let ((v1-0 (the-as object (-> arg0 base)))) + (set! (-> (the-as (pointer uint128) v1-0)) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-0) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 2) 128 128 128 128) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 3) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 4) 0 0 #xffffff 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 5) 8184 (+ (the int (* 736.0 arg1)) 8) 0 0) + (set-vector! + (-> (the-as (inline-array vector4w) v1-0) 6) + #x2800 + (the int (* 736.0 arg3 arg1)) + #xffffff + #x10000 + ) + ) + (&+! (-> arg0 base) 112) + (let ((v1-4 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-4) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-4) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) v1-4) 2) 128 128 128 128) + (set-vector! (-> (the-as (inline-array vector4w) v1-4) 3) 8 (+ (* (- 416 (the int (* 46.0 arg1))) 16) 8) 0 0) + (set-vector! + (-> (the-as (inline-array vector4w) v1-4) 4) + 0 + (* (- arg2 (the int (* 46.0 arg3 arg1))) 16) + #xffffff + 0 + ) + (set-vector! (-> (the-as (inline-array vector4w) v1-4) 5) 8184 6648 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-4) 6) #x2800 (* arg2 16) #xffffff #x10000) + ) + (&+! (-> arg0 base) 112) + 0 + (none) + ) + +;; definition for method 13 of type blit-displays-work +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod blit-displays-work-method-13 ((this blit-displays-work) (arg0 dma-buffer) (arg1 int) (arg2 int) (arg3 int)) + (set-display-gs-state arg0 408 512 416 0 0) + (dma-buffer-add-gs-set arg0 (rgbaq (new 'static 'gs-rgbaq :r #x80 :g #x80 :b #x80 :a #x80 :q 1.0))) + (let ((v1-3 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-3) 0 quad) (-> this sprite-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-3) 1 quad) (-> this sprite-tmpl quad 1)) + ) + (&+! (-> arg0 base) 32) + (dotimes (v1-6 16) + (let ((a0-10 (the-as object (-> arg0 base))) + (a2-2 (* v1-6 512)) + (a1-10 (* (+ v1-6 1) 512)) + ) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 0) (+ a2-2 arg3) arg1 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 1) a2-2 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 2) (+ a1-10 arg3) arg2 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 3) a1-10 6656 0 #x10000) + ) + (&+! (-> arg0 base) 64) + ) + 0 + (none) + ) + +;; definition for method 14 of type blit-displays-work +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod blit-displays-work-method-14 ((this blit-displays-work) (arg0 dma-buffer) (arg1 vector)) + (set-display-gs-state arg0 408 512 416 0 0) + (dma-buffer-add-gs-set arg0 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x3300 :tbw #x8 :tw #x9 :th #x9 :tcc #x1)) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (rgbaq (new 'static 'gs-rgbaq + :a #x80 + :q 1.0 + :b (the int (* 128.0 (-> arg1 z))) + :g (the int (* 128.0 (-> arg1 y))) + :r (the int (* 128.0 (-> arg1 x))) + ) + ) + (texflush 0) + ) + (let ((v1-3 (the-as object (-> arg0 base)))) + (set! (-> (the-as dma-gif-packet v1-3) dma-vif quad) (-> this sprite-tmpl dma-vif quad)) + (set! (-> (the-as dma-gif-packet v1-3) quad 1) (-> this sprite-tmpl quad 1)) + ) + (&+! (-> arg0 base) 32) + (dotimes (v1-6 16) + (let ((a0-10 (the-as object (-> arg0 base))) + (a2-14 (* v1-6 512)) + (a1-23 (* (+ v1-6 1) 512)) + ) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 0) (+ a2-14 8) 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 1) a2-14 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 2) (+ a1-23 8) 6664 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 3) a1-23 6656 0 0) + ) + (&+! (-> arg0 base) 64) + ) + 0 + (none) + ) + +;; definition for method 15 of type blit-displays-work +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod blit-displays-work-method-15 ((this blit-displays-work) (arg0 dma-buffer)) + (set-display-gs-state arg0 408 512 416 0 0) + (dma-buffer-add-gs-set arg0 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x4c0 :tbw #x8 :tw #x9 :th #x9 :tcc #x1)) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (rgbaq (new 'static 'gs-rgbaq :r #x80 :g #x80 :b #x80 :a #x80 :q 1.0)) + (texflush 0) + ) + (let ((v1-3 (the-as object (-> arg0 base)))) + (set! (-> (the-as dma-gif-packet v1-3) dma-vif quad) (-> this sprite-tmpl dma-vif quad)) + (set! (-> (the-as dma-gif-packet v1-3) quad 1) (-> this sprite-tmpl quad 1)) + ) + (&+! (-> arg0 base) 32) + (dotimes (v1-6 16) + (let ((a0-10 (the-as object (-> arg0 base))) + (a2-1 (+ (* v1-6 512) 8)) + (a1-22 (+ (* (+ v1-6 1) 512) 8)) + (a3-3 (* (- 16 v1-6) 512)) + (t0-3 (* (- 16 (+ v1-6 1)) 512)) + ) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 0) a2-1 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 1) a3-3 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 2) a1-22 6664 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-10) 3) t0-3 6656 0 #x10000) + ) + (&+! (-> arg0 base) 64) + ) + (set-display-gs-state arg0 304 512 416 (shl #xff00 16) 48) + (dma-buffer-add-gs-set arg0 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x2600 :tbw #x8 :psm #x30 :tw #x9 :th #x9)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (texflush 0) + ) + (let ((a0-21 (the-as object (-> arg0 base))) + (a1-40 2640) + (v1-13 4560) + ) + (set! (-> (the-as (inline-array vector4w) a0-21) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) a0-21) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) a0-21) 2 quad) (-> this color quad)) + (set-vector! (-> (the-as (inline-array vector4w) a0-21) 3) 8192 a1-40 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-21) 4) 8 a1-40 #xffffff 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-21) 5) 6592 v1-13 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-21) 6) 1608 v1-13 #xffffff 0) + ) + (&+! (-> arg0 base) 112) + 0 + (none) + ) + +;; definition for method 16 of type blit-displays-work +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod draw-zoom-blur ((this blit-displays-work) (arg0 dma-buffer) (arg1 int)) + (let ((s2-0 (the-as object (-> arg0 base))) + (s5-0 (new 'stack-no-clear 'vector)) + ) + 0.0 + (let ((f26-0 512.0)) + 0.0 + (let ((f30-0 416.0) + (f28-0 (the float (-> this zoom-blur-texels))) + ) + (cond + ((-> this zoom-blur-2d) + (set! (-> s5-0 quad) (-> this zoom-blur-pos quad)) + (let* ((f2-0 (* 0.001953125 f28-0 (-> s5-0 x))) + (f0-6 (- f26-0 (- f28-0 f2-0))) + (f3-1 (* 0.0024038462 f28-0 (-> s5-0 y))) + (f1-4 (- f30-0 (- f28-0 f3-1))) + ) + (set! (-> (the-as (inline-array vector4w) s2-0) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) s2-0) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) s2-0) 2 quad) (-> this color quad)) + (set-vector! (-> (the-as (inline-array vector4w) s2-0) 3) (the int (* 16.0 f2-0)) (the int (* 16.0 f3-1)) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) s2-0) 4) 0 0 #xffffff 0) + (set-vector! + (-> (the-as (inline-array vector4w) s2-0) 5) + (the int (* 16.0 (+ -1.0 f0-6))) + (the int (* 16.0 (+ -1.0 f1-4))) + 0 + 0 + ) + ) + (set-vector! (-> (the-as (inline-array vector4w) s2-0) 6) #x2800 (* arg1 16) #xffffff #x10000) + (&+! (-> arg0 base) 112) + ) + (else + (transform-point-vector! s5-0 (-> this zoom-blur-pos)) + (if (< (-> s5-0 z) 0.0) + (vector-negate! s5-0 s5-0) + ) + (+! (-> s5-0 x) -1792.0) + (+! (-> s5-0 y) -1840.0) + (let* ((f1-10 (* 0.001953125 f28-0 (-> s5-0 x))) + (f2-8 (fmax 0.0 (fmin f1-10 f28-0))) + (f0-22 (- f26-0 (- f28-0 f2-8))) + (f3-4 (* 0.0024038462 f28-0 (-> s5-0 y))) + (f3-6 (fmax 0.0 (fmin f3-4 f28-0))) + (f1-16 (- f30-0 (- f28-0 f3-6))) + ) + (set! (-> (the-as (inline-array vector4w) s2-0) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) s2-0) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) s2-0) 2 quad) (-> this color quad)) + (set-vector! (-> (the-as (inline-array vector4w) s2-0) 3) (the int (* 16.0 f2-8)) (the int (* 16.0 f3-6)) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) s2-0) 4) 0 0 #xffffff 0) + (set-vector! + (-> (the-as (inline-array vector4w) s2-0) 5) + (the int (* 16.0 (+ -1.0 f0-22))) + (the int (* 16.0 (+ -1.0 f1-16))) + 0 + 0 + ) + ) + (set-vector! (-> (the-as (inline-array vector4w) s2-0) 6) #x2800 (* arg1 16) #xffffff #x10000) + (&+! (-> arg0 base) 112) + ) + ) + ) + ) + (let ((f0-29 0.0) + (f1-18 0.0) + ) + (if (< (-> s5-0 x) 0.0) + (set! f0-29 (fmin 1.0 (* 0.001953125 (- (-> s5-0 x))))) + ) + (if (< 512.0 (-> s5-0 x)) + (set! f0-29 (fmin 1.0 (* 0.001953125 (+ -512.0 (-> s5-0 x))))) + ) + (if (< (-> s5-0 y) 0.0) + (set! f1-18 (fmin 1.0 (* 0.001953125 (- (-> s5-0 y))))) + ) + (if (< 416.0 (-> s5-0 y)) + (set! f1-18 (fmin 1.0 (* 0.001953125 (+ -416.0 (-> s5-0 y))))) + ) + (let ((f0-32 (fmax f0-29 f1-18))) + (set! (-> this zoom-blur-alpha-current) (lerp (-> this zoom-blur-alpha-target) 1.0 f0-32)) + ) + ) + ) + (set-dirty-mask! (-> *level* level-default) 9 #xd0000 #x4c000) + 0 + (none) + ) + +;; definition for method 17 of type blit-displays-work +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod setup-zoom-blur-2d ((this blit-displays-work) (arg0 vector) (arg1 int) (arg2 float) (arg3 symbol)) + (set! (-> this zoom-blur-2d) arg3) + (set! (-> this zoom-blur-pos quad) (-> arg0 quad)) + (set! (-> this zoom-blur-texels) arg1) + (set! (-> this zoom-blur-alpha-target) arg2) + 0 + (none) + ) + +;; definition for method 18 of type blit-displays-work +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod setup-brightness-and-contrast ((this blit-displays-work) (arg0 dma-buffer) (arg1 float) (arg2 float)) + (set-display-gs-state arg0 408 512 416 0 0) + (let ((s4-1 (fmax 0.0 (fmin 1.0 arg2))) + (s3-1 (fmax 0.0 (fmin 1.0 arg1))) + ) + (let ((v1-2 (the-as object (-> arg0 base)))) + (set! (-> (the-as dma-gif-packet v1-2) dma-vif quad) (-> this adgif-tmpl dma-vif quad)) + (set! (-> (the-as dma-gif-packet v1-2) quad 1) (-> this adgif-tmpl quad 1)) + (adgif-shader<-texture-simple! + (the-as adgif-shader (&+ (the-as dma-gif-packet v1-2) 32)) + (get-texture common-white common) + ) + ) + (&+! (-> arg0 base) 112) + (let ((v1-9 (the int (* 64.2509 (+ (- 0.5 s4-1) (* 2.0 (fmax 0.0 (+ -0.5 s3-1))))))) + (a0-10 (the int (fmin 255.0 (* 256.0 (fmin 1.0 (* 2.0 s3-1)) s4-1)))) + ) + (cond + ((>= v1-9 0) + (dma-buffer-add-gs-set arg0 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha :a #x1 :b #x2 :c #x2 :fix a0-10)) + (rgbaq (new 'static 'gs-rgbaq :a #x80 :q 1.0 :b v1-9 :g v1-9 :r v1-9)) + ) + ) + (else + (let ((v1-15 (- v1-9))) + (dma-buffer-add-gs-set arg0 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha :a #x1 :c #x2 :d #x2 :fix a0-10)) + (rgbaq (new 'static 'gs-rgbaq :a #x80 :q 1.0 :b v1-15 :g v1-15 :r v1-15)) + ) + ) + ) + ) + ) + ) + (let ((v1-21 (the-as object (-> arg0 base)))) + (set! (-> (the-as dma-gif-packet v1-21) dma-vif quad) (-> this contrast-tmpl dma-vif quad)) + (set! (-> (the-as dma-gif-packet v1-21) quad 1) (-> this contrast-tmpl quad 1)) + ) + (&+! (-> arg0 base) 32) + (dotimes (v1-24 16) + (let ((a0-27 (the-as object (-> arg0 base))) + (a2-12 (* v1-24 512)) + (a1-10 (* (+ v1-24 1) 512)) + ) + (set-vector! (-> (the-as (inline-array vector4w) a0-27) 0) 0 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-27) 1) a2-12 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-27) 2) 0 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a0-27) 3) a1-10 6656 0 0) + ) + (&+! (-> arg0 base) 64) + ) + 0 + (none) + ) + +;; definition for method 19 of type blit-displays-work +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod do-blit-displays ((this blit-displays-work)) + (set! (-> this slow-time) (- 1.0 (-> *setting-control* user-current slow-time))) + (let ((v1-3 (-> *setting-control* user-current))) + (when (or (!= (-> v1-3 contrast) 0.5) (!= (-> v1-3 brightness) 0.5)) + (with-dma-buffer-add-bucket ((s4-0 (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id debug-menu) + ) + (setup-brightness-and-contrast this s4-0 (-> v1-3 brightness) (-> v1-3 contrast)) + (reset-display-gs-state *display* s4-0) + ) + ) + ) + (when (zero? (-> this count-down)) + (cond + ((and (-> this menu-mode) (not (-> this screen-copied))) + (with-dma-buffer-add-bucket ((s4-1 (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id bucket3) + ) + (fx-copy-buf s4-1) + ) + (set! (-> this vu1-enable-user-menu) (-> *display* vu1-enable-user-menu)) + (set! (-> *display* vu1-enable-user-menu) (vu1-renderer-mask generic)) + (set! (-> *display* vu1-enable-user) (vu1-renderer-mask generic)) + (set! (-> this texture-enable-user-menu) (the-as uint (-> *texture-pool* texture-enable-user-menu))) + (set! (-> *texture-pool* texture-enable-user-menu) (texture-enable-mask shrub water hud)) + (set! (-> *texture-pool* texture-enable-user) (texture-enable-mask shrub water hud)) + (set! (-> this count-down) (the-as uint 3)) + (set! (-> this screen-copied) #t) + (set! (-> this progress-interp) 0.0) + (set! (-> this progress-interp-dest) 1.0) + (set! (-> this progress-interp-speed) 0.033333335) + ) + ((and (not (get-menu-mode this)) (get-screen-copied this)) + (set! (-> *display* vu1-enable-user-menu) (-> this vu1-enable-user-menu)) + (set! (-> *texture-pool* texture-enable-user-menu) + (the-as texture-enable-mask (-> this texture-enable-user-menu)) + ) + (set! (-> this count-down) (the-as uint 3)) + (set! (-> this screen-copied) #f) + ) + ) + ) + (when (and (-> *setting-control* user-current render) (>= (the-as uint 1) (-> this count-down))) + (when (and (get-horizontal-flip-flag this) (not (get-menu-mode this))) + (with-dma-buffer-add-bucket ((s4-2 (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id debug-no-zbuf1) + ) + (fx-copy-buf s4-2) + (blit-displays-work-method-15 this s4-2) + (reset-display-gs-state *display* s4-2) + ) + ) + (when (logtest? (vu1-renderer-mask rn36) (-> *display* vu1-enable-user)) + (when (not *display-color-bars*) + (with-dma-buffer-add-bucket ((s4-3 (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id bucket567) + ) + (dma-buffer-add-gs-set s4-3 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x3300 :tbw #x8 :tw #x9 :th #x9 :tcc #x1)) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (texflush 0) + ) + (if (or (zero? *screen-shot-work*) (= (-> *screen-shot-work* count) -1)) + (blit-displays-work-method-13 this s4-3 0 6656 8) + ) + (reset-display-gs-state *display* s4-3) + ) + ) + ) + ) + (let ((f0-9 (-> this slow-time)) + (a2-6 (-> *time-of-day-context* filter)) + (s5-4 (new 'stack-no-clear 'vector)) + ) + (set-vector! s5-4 1.0 1.0 1.5 1.0) + (vector4-lerp! s5-4 s5-4 a2-6 f0-9) + (when (and (or (!= (-> s5-4 x) 1.0) (!= (-> s5-4 y) 1.0) (!= (-> s5-4 z) 1.0)) (not (get-menu-mode this))) + (with-dma-buffer-add-bucket ((s3-0 (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id tex-hud-hud-alpha) + ) + (blit-displays-work-method-14 this s3-0 s5-4) + (reset-display-gs-state *display* s3-0) + ) + ) + ) + (cond + ((and (-> *setting-control* user-current render) (zero? (-> this count-down))) + (with-dma-buffer-add-bucket ((s4-5 (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id bucket3) + ) + (dma-buffer-add-gs-set s4-5 + (dthe (new 'static 'gs-dthe)) + (prmodecont (new 'static 'gs-prmode-cont :ac #x1)) + (colclamp (new 'static 'gs-color-clamp :clamp #x1)) + (pabe 0) + (texa (new 'static 'gs-texa :ta1 #x80)) + (texclut (new 'static 'gs-texclut :cbw #x4)) + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (fogcol *fog-color*) + (texflush 0) + ) + (let* ((s0-0 *video-params*) + (s1-0 (-> s0-0 display-fbp)) + (s3-1 (-> s0-0 display-sy)) + ) + (let ((s2-0 (* s3-1 2))) + (dma-buffer-add-gs-set s4-5 + (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x3300 :tbw #x8 :tw #x9 :th #x9)) + ) + (cond + ((or (zero? (-> this zoom-blur-texels)) (or (= (-> this zoom-blur-alpha-target) 1.0) (paused?))) + (let ((f0-14 (-> this slow-time)) + (f30-0 1.0) + ) + (if (!= f0-14 1.0) + (set! f30-0 (lerp 0.05 1.0 f0-14)) + ) + (set-display-gs-state s4-5 (-> s0-0 display-fbp) 640 s2-0 (shl #xff00 16) 0) + (if (= f30-0 1.0) + (blit-displays-work-method-9 this s4-5 416 s2-0 128) + (blit-displays-work-method-10 this s4-5 416 s2-0 (the int (* 128.0 f30-0))) + ) + ) + ) + (else + (set-display-gs-state s4-5 38 512 416 (shl #xff00 16) 0) + (dma-buffer-add-gs-set s4-5 + (tex0-1 (new 'static 'gs-tex0 :tbw #xa :tw #xa :th #x9 :tbp0 (* (-> s0-0 display-fbp) 32))) + ) + (blit-displays-work-method-11 this s4-5 s2-0) + (set-display-gs-state s4-5 s1-0 640 s2-0 (shl #xff00 16) 0) + (dma-buffer-add-gs-set s4-5 (tex0-1 (new 'static 'gs-tex0 :tbp0 #x4c0 :tbw #x8 :tw #x9 :th #x9))) + (draw-zoom-blur this s4-5 s2-0) + (dma-buffer-add-gs-set s4-5 (tex0-1 (new 'static 'gs-tex0 :tbp0 #x3300 :tbw #x8 :tw #x9 :th #x9))) + (blit-displays-work-method-9 this s4-5 416 s2-0 (the int (* 128.0 (-> this zoom-blur-alpha-current)))) + (when (or (!= (-> *setting-control* user-current letterbox) 0.0) + (< (-> *display* base-clock frame-counter) (-> *game-info* letterbox-time)) + ) + (when (and (= (-> *setting-control* user-current aspect-ratio) 'aspect4x3) + (or (zero? *screen-shot-work*) (= (-> *screen-shot-work* count) -1)) + ) + (let ((f0-24 (the-as float (if (< (-> *display* base-clock frame-counter) (-> *game-info* letterbox-time)) + 1.0 + (-> *setting-control* user-current letterbox) + ) + ) + ) + (f1-15 (* 0.0024038462 (the float s2-0))) + ) + (draw-letterbox this s4-5 f0-24 s2-0 f1-15) + ) + ) + ) + ) + ) + ) + (when (!= (-> *setting-control* user-current scanlines) 0.0) + (let ((v1-213 (the int (* 128.0 (-> *setting-control* user-current scanlines))))) + (set! (-> this line-color) + (logior (logand (-> this line-color) (the-as uint #xffffffff00ffffff)) (shr (shl v1-213 56) 32)) + ) + (dotimes (a0-120 15) + (set! (-> this scan-colors a0-120 w) v1-213) + ) + ) + (dma-buffer-add-gs-set s4-5 + (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (rgbaq (-> this line-color)) + ) + (dotimes (v1-219 (/ s3-1 32)) + (let ((a0-127 (the-as object (-> s4-5 base)))) + (set! (-> (the-as dma-gif-packet a0-127) dma-vif quad) (-> this line-tmpl dma-vif quad)) + (set! (-> (the-as dma-gif-packet a0-127) quad 1) (-> this line-tmpl quad 1)) + ) + (&+! (-> s4-5 base) 32) + (dotimes (a0-130 16) + (let ((a1-115 (the-as object (-> s4-5 base))) + (a2-25 (* (+ (* v1-219 64) (* a0-130 4)) 16)) + ) + (set-vector! (-> (the-as (inline-array vector4w) a1-115) 0) 0 a2-25 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a1-115) 1) #x2800 a2-25 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a1-115) 2) 0 (+ a2-25 16) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a1-115) 3) #x2800 (+ a2-25 16) 0 0) + ) + (&+! (-> s4-5 base) 64) + ) + ) + (dma-buffer-add-gs-set s4-5 (alpha-1 (new 'static 'gs-alpha :b #x2 :d #x1))) + (let ((v1-225 (the-as object (-> s4-5 base)))) + (set! (-> (the-as dma-gif-packet v1-225) dma-vif quad) (-> this scan-tmpl dma-vif quad)) + (set! (-> (the-as dma-gif-packet v1-225) quad 1) (-> this scan-tmpl quad 1)) + ) + (&+! (-> s4-5 base) 32) + (let ((a0-142 (* (-> this scanline) 32))) + (dotimes (v1-229 15) + (let ((a1-126 (the-as object (-> s4-5 base)))) + (set! (-> (the-as (inline-array vector4w) a1-126) 0 quad) (-> this scan-colors v1-229 quad)) + (set-vector! (-> (the-as (inline-array vector4w) a1-126) 1) 0 (the-as int a0-142) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a1-126) 2) #x2800 (the-as int a0-142) 0 0) + (let ((a0-143 (+ a0-142 16))) + (set-vector! (-> (the-as (inline-array vector4w) a1-126) 3) 0 (the-as int a0-143) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a1-126) 4) #x2800 (the-as int a0-143) 0 0) + (set! a0-142 (+ a0-143 16)) + ) + ) + (&+! (-> s4-5 base) 80) + ) + ) + (if (not (paused?)) + (set! (-> this scanline) (the-as uint (mod (the-as int (+ (-> this scanline) 4)) s3-1))) + ) + ) + ) + (reset-display-gs-state *display* s4-5) + ) + ) + (else + (with-dma-buffer-add-bucket ((s4-6 (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id bucket3) + ) + (reset-display-gs-state *display* s4-6) + ) + ) + ) + (if (nonzero? (-> this count-down)) + (+! (-> this count-down) -1) + ) + 0 + (none) + ) + +;; definition for method 20 of type blit-displays-work +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod draw-sky ((this blit-displays-work) (arg0 dma-buffer)) + (let ((f0-0 (-> this progress-interp)) + (v1-0 *time-of-day-context*) + ) + (dma-buffer-add-gs-set arg0 + (zbuf-1 (new 'static 'gs-zbuf :zbp #x130 :psm (gs-psm ct24))) + (test-1 (new 'static 'gs-test :ate #x1 :atst (gs-atest always) :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x4c0 :tbw #x8 :tw #x9 :th #x9 :tcc #x1)) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (texflush 0) + ) + (let ((a3-17 (the-as object (-> arg0 base))) + (t0-0 #x7000) + (t1-0 #x7300) + (a0-4 #x7800) + (a2-6 #x7980) + ) + (set! (-> (the-as (inline-array vector4w) a3-17) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) a3-17) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) a3-17) 2) 128 128 128 128) + (set-vector! (-> (the-as (inline-array vector4w) a3-17) 3) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a3-17) 4) t0-0 t1-0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a3-17) 5) 8200 6664 0 0) + (set-vector! (-> (the-as (inline-array vector4w) a3-17) 6) a0-4 a2-6 0 0) + ) + (&+! (-> arg0 base) 112) + (let ((t1-3 (the-as object (-> arg0 base))) + (a3-19 #x8000) + (t0-2 #x8000) + (a0-7 #x9000) + (a2-7 #x8d00) + ) + (set! (-> (the-as (inline-array vector4w) t1-3) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) t1-3) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) t1-3) 2) 128 128 128 128) + (set-vector! (-> (the-as (inline-array vector4w) t1-3) 3) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t1-3) 4) a3-19 t0-2 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t1-3) 5) 8200 6664 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t1-3) 6) a0-7 a2-7 0 0) + (&+! (-> arg0 base) 112) + (dma-buffer-add-gs-set arg0 + (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x3300 :tbw #x8 :tw #x9 :th #x9 :tcc #x1)) + (texflush 0) + ) + (let ((t1-10 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) t1-10) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) t1-10) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) t1-10) 2) 128 128 128 80) + (set-vector! (-> (the-as (inline-array vector4w) t1-10) 3) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t1-10) 4) a3-19 (+ t0-2 -8) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t1-10) 5) 2056 1672 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t1-10) 6) a0-7 (+ a2-7 -8) 0 0) + ) + ) + (&+! (-> arg0 base) 112) + (dma-buffer-add-gs-set arg0 (alpha-1 (new 'static 'gs-alpha))) + (let ((a0-16 (the int (+ 128.0 (* 32.0 f0-0)))) + (a2-16 (the int (- 128.0 (* 16.0 f0-0)))) + (a3-31 (the int (- 128.0 (* 96.0 f0-0)))) + ) + (when (or (!= (-> v1-0 filter x) 1.0) (!= (-> v1-0 filter y) 1.0) (!= (-> v1-0 filter z) 1.0)) + (set! a0-16 128) + (set! a2-16 128) + (set! a3-31 128) + ) + (let ((v1-5 3328) + (t0-9 6656) + ) + (dotimes (t1-11 16) + (let ((t2-22 (the-as object (-> arg0 base))) + (t4-0 (* (+ (* t1-11 32) 1792) 16)) + (t3-35 (* (+ (* (+ t1-11 1) 32) 1792) 16)) + ) + (let ((t6-0 (* (+ (* t1-11 16) 256) 16)) + (t5-5 (* (+ (* (+ t1-11 1) 16) 256) 16)) + ) + (set! (-> (the-as (inline-array vector4w) t2-22) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) t2-22) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! (-> (the-as (inline-array vector4w) t2-22) 2) a0-16 a2-16 a3-31 128) + (set-vector! (-> (the-as (inline-array vector4w) t2-22) 3) t6-0 (+ v1-5 8) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t2-22) 4) t4-0 #x72f8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) t2-22) 5) t5-5 (+ t0-9 8) 0 0) + ) + (set-vector! (-> (the-as (inline-array vector4w) t2-22) 6) t3-35 #x8cf8 0 0) + ) + (&+! (-> arg0 base) 112) + ) + ) + (dma-buffer-add-gs-set arg0 + (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x4c0 :tbw #x8 :tw #x9 :th #x9 :tcc #x1)) + (texflush 0) + ) + (let ((v1-11 (the-as object (-> arg0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-11) 0 quad) (-> this sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-11) 1 quad) (-> this sprite-slow-tmpl quad 1)) + (set-vector! + (-> (the-as (inline-array vector4w) v1-11) 2) + a0-16 + a2-16 + a3-31 + (the int (- 128.0 (* 48.0 f0-0))) + ) + (set-vector! (-> (the-as (inline-array vector4w) v1-11) 3) 8 8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-11) 4) #x7000 #x72f8 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-11) 5) 8200 6664 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-11) 6) #x9000 #x8cf8 0 0) + ) + ) + ) + (&+! (-> arg0 base) 112) + (seek! (-> this progress-interp) (-> this progress-interp-dest) (-> this progress-interp-speed)) + 0 + (none) + ) + +;; definition for function draw-color-bars +;; INFO: Used lq/sq +;; WARN: Return type mismatch pointer vs none. +(defun draw-color-bars ((arg0 blit-displays-work)) + (with-dma-buffer-add-bucket ((s5-0 (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id debug-no-zbuf2) + ) + (let ((v1-5 (the-as object (-> s5-0 base)))) + (set! (-> (the-as dma-gif-packet v1-5) dma-vif quad) (-> arg0 adgif-tmpl dma-vif quad)) + (set! (-> (the-as dma-gif-packet v1-5) quad 1) (-> arg0 adgif-tmpl quad 1)) + (adgif-shader<-texture-simple! + (the-as adgif-shader (&+ (the-as dma-gif-packet v1-5) 32)) + (get-texture colorbars13 programmer) + ) + ) + (&+! (-> s5-0 base) 112) + (let ((v1-8 (the-as object (-> s5-0 base)))) + (set! (-> (the-as (inline-array vector4w) v1-8) 0 quad) (-> arg0 sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-8) 1 quad) (-> arg0 sprite-slow-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) v1-8) 2 quad) (-> arg0 color quad)) + (set-vector! (-> (the-as (inline-array vector4w) v1-8) 3) 32 0 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-8) 4) #x7000 #x7300 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-8) 5) 480 256 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-8) 6) #x9000 #x8d00 0 0) + ) + (&+! (-> s5-0 base) 112) + ) + (none) + ) + +;; definition for function draw-raw-image +;; INFO: Used lq/sq +;; WARN: Return type mismatch pointer vs none. +(defun draw-raw-image ((arg0 blit-displays-work) + (arg1 bucket-id) + (arg2 art-group) + (arg3 vector) + (arg4 vector) + (arg5 level) + (arg6 int) + ) + (local-vars (sv-16 blit-displays-work) (sv-32 int)) + (set! sv-16 *blit-displays-work*) + (with-dma-buffer-add-bucket ((s1-0 (-> *display* frames (-> *display* on-screen) global-buf)) + arg1 + ) + (upload-vram-data s1-0 0 (the-as pointer arg2) (the int (-> arg3 y)) (the int (-> arg3 x))) + (set! sv-32 (+ (log2 (+ (the int (-> arg3 x)) -1)) 1)) + (let ((v1-9 (+ (log2 (+ (the int (-> arg3 y)) -1)) 1))) + (dma-buffer-add-gs-set s1-0 + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha)) + (tex0-1 (new 'static 'gs-tex0 :tcc #x1 :th v1-9 :tw sv-32 :tbw (/ (the int (-> arg3 x)) 64))) + (tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + (texflush 0) + ) + ) + (let ((v1-20 (the-as object (-> s1-0 base))) + (f0-10 (-> *video-params* relative-x-scale)) + ) + (set! (-> (the-as (inline-array vector4w) v1-20) 0 quad) (-> sv-16 sprite-slow-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-20) 1 quad) (-> sv-16 sprite-slow-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) v1-20) 2 quad) (-> sv-16 color quad)) + (set-vector! (-> (the-as (inline-array vector4w) v1-20) 3) 0 0 0 0) + (set-vector! + (-> (the-as (inline-array vector4w) v1-20) 4) + (* (- 2048 (the int (* 256.0 f0-10 (-> arg4 x)))) 16) + (* (- 2048 (the int (* 208.0 (-> arg4 y)))) 16) + 0 + 0 + ) + (set-vector! + (-> (the-as (inline-array vector4w) v1-20) 5) + (* (the int (-> arg3 x)) 16) + (* (the int (-> arg3 y)) 16) + 0 + 0 + ) + (set-vector! + (-> (the-as (inline-array vector4w) v1-20) 6) + (* (+ (the int (* 256.0 f0-10 (-> arg4 x))) 2048) 16) + (* (+ (the int (* 208.0 (-> arg4 y))) 2048) 16) + 0 + 0 + ) + ) + (&+! (-> s1-0 base) 112) + (set-dirty-mask! arg5 arg6 (* (* (the int (-> arg3 y)) (the int (-> arg3 x))) 4) 0) + ) + (none) + ) + + + + diff --git a/test/decompiler/reference/jak3/engine/gfx/font-h_REF.gc b/test/decompiler/reference/jak3/engine/gfx/font-h_REF.gc index 0ca4eecc4f..b6231ed637 100644 --- a/test/decompiler/reference/jak3/engine/gfx/font-h_REF.gc +++ b/test/decompiler/reference/jak3/engine/gfx/font-h_REF.gc @@ -766,13 +766,17 @@ ) ;; definition for function set-font-color -(defun set-font-color ((arg0 font-color) (arg1 int) (arg2 rgba) (arg3 rgba) (arg4 rgba)) - (set! (-> *font-work* color-table arg0 color 0) (the-as rgba arg1)) - (set! (-> *font-work* color-table arg0 color 1) arg2) - (set! (-> *font-work* color-table arg0 color 2) arg3) - (set! (-> *font-work* color-table arg0 color 3) arg4) +(defun set-font-color ((idx font-color) (clr0 rgba) (clr1 rgba) (clr2 rgba) (clr3 rgba)) + (set! (-> *font-work* color-table idx color 0) clr0) + (set! (-> *font-work* color-table idx color 1) clr1) + (set! (-> *font-work* color-table idx color 2) clr2) + (set! (-> *font-work* color-table idx color 3) clr3) 0 ) ;; failed to figure out what this is: 0 + + + + diff --git a/test/decompiler/reference/jak3/engine/gfx/sky/sky-tng_REF.gc b/test/decompiler/reference/jak3/engine/gfx/sky/sky-tng_REF.gc index 4d0a2d75a0..9f790be342 100644 --- a/test/decompiler/reference/jak3/engine/gfx/sky/sky-tng_REF.gc +++ b/test/decompiler/reference/jak3/engine/gfx/sky/sky-tng_REF.gc @@ -802,7 +802,7 @@ (with-dma-buffer-add-bucket ((s5-2 (-> *display* frames (-> *display* on-screen) global-buf)) (bucket-id sky) ) - (blit-displays-work-method-20 *blit-displays-work*) + (draw-sky *blit-displays-work* s5-2) ) ) (else diff --git a/test/decompiler/reference/jak3/engine/level/level-info_REF.gc b/test/decompiler/reference/jak3/engine/level/level-info_REF.gc index e9ba33f7ef..2ca435084f 100644 --- a/test/decompiler/reference/jak3/engine/level/level-info_REF.gc +++ b/test/decompiler/reference/jak3/engine/level/level-info_REF.gc @@ -43,7 +43,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -79,7 +79,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -112,7 +112,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "title-start" :level 'title @@ -315,7 +315,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "vinroom-start" :level 'vinroom @@ -491,7 +491,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((7 . *ljkdxvin-texture-anim-array*)) :borrow #f @@ -525,7 +525,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((7 . *ljkdxvin-texture-anim-array*)) :borrow #f @@ -560,7 +560,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -594,7 +594,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 9.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((34 . ctywide-logout) (36 . ctywide-deactivate) @@ -639,7 +639,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -675,7 +675,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -711,7 +711,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -747,7 +747,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -783,7 +783,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -819,7 +819,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -854,7 +854,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -889,7 +889,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -923,7 +923,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -957,7 +957,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -991,7 +991,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1025,7 +1025,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1059,7 +1059,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1093,7 +1093,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1128,7 +1128,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -1163,7 +1163,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -1197,7 +1197,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1231,7 +1231,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1265,7 +1265,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1299,7 +1299,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1333,7 +1333,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1367,7 +1367,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -1402,7 +1402,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -3395,7 +3395,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -3431,7 +3431,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((34 . lpattack-logout) (36 . rubblea-deactivate) (35 . rubblea-activate) (33 . lpattack-login)) :borrow #f @@ -4190,7 +4190,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4224,7 +4224,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4258,7 +4258,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((34 . lctypatk-logout) (33 . lctypatk-login)) :borrow #f @@ -4292,7 +4292,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lwide-deactivate) (35 . lwide-activate)) :borrow #f @@ -4326,7 +4326,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((34 . lctypalt-logout) (33 . lctypalt-login)) :borrow #f @@ -4360,7 +4360,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4394,7 +4394,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((23 . init-mood-mhcitya)) :borrow #f @@ -4428,7 +4428,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4462,7 +4462,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4496,7 +4496,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4530,7 +4530,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "onintent-start" :level 'onintent @@ -4607,7 +4607,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4642,7 +4642,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "hiphog-start" :level 'hiphog @@ -4738,7 +4738,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4773,7 +4773,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "gungame-start" :level 'gungame @@ -4891,7 +4891,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4926,7 +4926,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4961,7 +4961,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -4996,7 +4996,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "freehq-start" :level 'freehq @@ -5132,7 +5132,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -5167,7 +5167,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -5202,7 +5202,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((3 . *darkjak-highres-texture-anim-array*)) :borrow #f @@ -5786,7 +5786,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "comba-start" :level 'comba @@ -5904,7 +5904,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "combb-start" :level 'combb @@ -5956,7 +5956,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "combc" :level 'combc @@ -6010,7 +6010,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "combd" :level 'combd @@ -6064,7 +6064,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "combe" :level 'combe @@ -6118,7 +6118,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((23 . init-mood-comb)) :borrow #f @@ -6152,7 +6152,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "combn-start" :level 'combn @@ -6226,7 +6226,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((23 . init-mood-combx)) :borrow #f @@ -6260,7 +6260,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . comba-deactivate) (35 . comba-activate) (33 . comba-login) (23 . init-mood-comb)) :borrow #f @@ -6294,7 +6294,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "railb-start" :level 'railb @@ -6348,7 +6348,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "railb2-start" :level 'railb2 @@ -6402,7 +6402,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "railc-start" :level 'railc @@ -6456,7 +6456,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "raild-start" :level 'raild @@ -6510,7 +6510,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "raile-start" :level 'raile @@ -6564,7 +6564,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((23 . init-mood-comb)) :borrow #f @@ -6598,7 +6598,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "railx-start" :level 'railx @@ -6654,7 +6654,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -6689,7 +6689,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -6794,7 +6794,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -7081,7 +7081,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "prebot-intro" :level 'mined @@ -7243,7 +7243,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "sewer-start" :level 'sewa @@ -7358,7 +7358,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer0) + :bigmap-id (bigmap-id sewer-hum-kg) :continues '((new 'static 'continue-point :name "sewb" :level 'sewb @@ -7453,7 +7453,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer0) + :bigmap-id (bigmap-id sewer-hum-kg) :continues '((new 'static 'continue-point :name "sewc-start" :level 'sewc @@ -7528,7 +7528,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer0) + :bigmap-id (bigmap-id sewer-hum-kg) :continues '((new 'static 'continue-point :name "sewd-start" :level 'sewd @@ -7603,7 +7603,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer0) + :bigmap-id (bigmap-id sewer-hum-kg) :continues '((new 'static 'continue-point :name "sewe" :level 'sewe @@ -7716,7 +7716,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer0) + :bigmap-id (bigmap-id sewer-hum-kg) :continues '((new 'static 'continue-point :name "sewf-start" :level 'sewf @@ -7791,7 +7791,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer1) + :bigmap-id (bigmap-id sewer-kg-met) :continues '((new 'static 'continue-point :name "sewg-start" :level 'sewg @@ -7866,7 +7866,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer1) + :bigmap-id (bigmap-id sewer-kg-met) :continues '((new 'static 'continue-point :name "sewh-start" :level 'sewh @@ -7941,7 +7941,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer1) + :bigmap-id (bigmap-id sewer-kg-met) :continues '((new 'static 'continue-point :name "sewi-start" :level 'sewi @@ -7996,7 +7996,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer1) + :bigmap-id (bigmap-id sewer-kg-met) :continues '((new 'static 'continue-point :name "sewj-start" :level 'sewj @@ -8071,7 +8071,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer1) + :bigmap-id (bigmap-id sewer-kg-met) :continues '((new 'static 'continue-point :name "sewk" :level 'sewk @@ -8146,7 +8146,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer2) + :bigmap-id (bigmap-id sewer-met-hum) :continues '((new 'static 'continue-point :name "sewl" :level 'sewl @@ -8219,7 +8219,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer2) + :bigmap-id (bigmap-id sewer-met-hum) :continues '((new 'static 'continue-point :name "sewm" :level 'sewm @@ -8312,7 +8312,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer2) + :bigmap-id (bigmap-id sewer-met-hum) :continues '((new 'static 'continue-point :name "sewn" :level 'sewn @@ -8385,7 +8385,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id sewer2) + :bigmap-id (bigmap-id sewer-met-hum) :continues '((new 'static 'continue-point :name "sewo" :level 'sewo @@ -8736,7 +8736,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((3 . *lforplnt-pris-texture-anim-array*)) :borrow #f @@ -8771,7 +8771,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -8806,7 +8806,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((34 . foresta-logout) (35 . foresta-activate) (33 . foresta-login)) :borrow #f @@ -8893,7 +8893,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "pre-intro-start" :level 'wasintro @@ -9029,7 +9029,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info @@ -9068,7 +9068,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -9103,7 +9103,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -9136,7 +9136,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "wasall-start" :level 'wasall @@ -9214,7 +9214,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . waswide-deactivate) (35 . waswide-activate) (33 . waswide-login)) :borrow (new 'static 'level-borrow-info @@ -9547,7 +9547,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -9976,7 +9976,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10011,7 +10011,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info @@ -10050,7 +10050,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10085,7 +10085,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10120,7 +10120,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10155,7 +10155,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . race-level-deactivate) (35 . race-level-activate)) :borrow #f @@ -10508,7 +10508,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info @@ -10547,7 +10547,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10581,7 +10581,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10615,7 +10615,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -10649,7 +10649,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11092,7 +11092,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11126,7 +11126,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11160,7 +11160,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11194,7 +11194,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11228,7 +11228,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11262,7 +11262,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11296,7 +11296,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11331,7 +11331,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11365,7 +11365,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11399,7 +11399,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11433,7 +11433,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11467,7 +11467,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11501,7 +11501,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11535,7 +11535,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11569,7 +11569,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11603,7 +11603,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11637,7 +11637,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11671,7 +11671,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11705,7 +11705,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11739,7 +11739,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11773,7 +11773,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11807,7 +11807,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11841,7 +11841,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11875,7 +11875,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11909,7 +11909,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11943,7 +11943,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -11977,7 +11977,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12011,7 +12011,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12045,7 +12045,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12079,7 +12079,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12113,7 +12113,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12147,7 +12147,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12181,7 +12181,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12215,7 +12215,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((7 . *ltnfxhip-texture-anim-array*)) :borrow #f @@ -12249,7 +12249,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12283,7 +12283,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12317,7 +12317,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12351,7 +12351,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12385,7 +12385,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12419,7 +12419,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12453,7 +12453,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((6 . *lgunnorm-water-texture-anim-array*)) :borrow #f @@ -12487,7 +12487,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12522,7 +12522,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12713,7 +12713,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -12747,7 +12747,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -14255,7 +14255,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -14344,7 +14344,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -14379,7 +14379,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -15122,7 +15122,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15265,7 +15265,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow (new 'static 'level-borrow-info :alias #f :borrow-info (new 'static 'array object 5 #f #f #f #f #f)) @@ -15300,7 +15300,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15335,7 +15335,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15370,7 +15370,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15405,7 +15405,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15440,7 +15440,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . desert-race-level-deactivate) (35 . desert-race-level-activate)) :borrow #f @@ -15475,7 +15475,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "desrally-race-start" :level 'desrally @@ -15550,7 +15550,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "desert-hover-movie" :level 'deshover @@ -15605,7 +15605,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15640,7 +15640,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15675,7 +15675,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "desert-rescue-movie" :level 'desresc @@ -15773,7 +15773,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -15808,7 +15808,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -15843,7 +15843,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "desert-ashelin-pre-start" :level 'desoasis @@ -15958,7 +15958,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -15993,7 +15993,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -16028,7 +16028,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -16063,7 +16063,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((35 . desert-game-activate)) :borrow #f @@ -16098,7 +16098,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16133,7 +16133,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16168,7 +16168,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16203,7 +16203,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16238,7 +16238,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16273,7 +16273,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16308,7 +16308,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16343,7 +16343,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16378,7 +16378,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16413,7 +16413,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16448,7 +16448,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16483,7 +16483,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16518,7 +16518,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16553,7 +16553,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16588,7 +16588,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16623,7 +16623,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16658,7 +16658,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16693,7 +16693,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16728,7 +16728,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -16763,7 +16763,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -17050,7 +17050,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -17085,7 +17085,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -17120,7 +17120,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -17157,7 +17157,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id temple) + :bigmap-id (bigmap-id temple1) :continues '((new 'static 'continue-point :name "templex-start" :level 'templex @@ -17390,7 +17390,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0 primary0) - :bigmap-id (bigmap-id temple) + :bigmap-id (bigmap-id temple1) :continues '((new 'static 'continue-point :name "templea-start" :level 'templea @@ -17555,7 +17555,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id temple) + :bigmap-id (bigmap-id temple1) :continues '((new 'static 'continue-point :name "templeb-start" :level 'templeb @@ -17963,7 +17963,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id temple) + :bigmap-id (bigmap-id temple1) :continues '((new 'static 'continue-point :name "templec-start" :level 'templec @@ -18058,7 +18058,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id temple) + :bigmap-id (bigmap-id temple1) :continues '((new 'static 'continue-point :name "templed-start" :level 'templed @@ -18233,7 +18233,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id temple) + :bigmap-id (bigmap-id temple1) :continues '() :callback-list '((23 . init-mood-templea)) :borrow #f @@ -18347,7 +18347,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((12 . *hfrag-texture-anim-array*)) :borrow #f @@ -18920,7 +18920,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0 primary0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . factorya-deactivate) (35 . factorya-activate)) :borrow #f @@ -18954,7 +18954,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '((36 . lfaccar-deactivate) (35 . lfaccar-activate)) :borrow #f @@ -18989,7 +18989,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "lfacrm1-start" :level 'lfacrm1 @@ -19043,7 +19043,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "factoryc-start-lfacrm2" :level 'lfacrm2 @@ -19095,7 +19095,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -19129,7 +19129,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -19164,7 +19164,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "factoryb-start" :level 'factoryb @@ -19597,7 +19597,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "factoryd-pre" :level 'factoryd @@ -19686,7 +19686,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -19720,7 +19720,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "warinta" :level 'warinta @@ -19771,7 +19771,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0 primary0) - :bigmap-id (bigmap-id precursor) + :bigmap-id (bigmap-id precursor1) :continues '((new 'static 'continue-point :name "precura-mech" :level 'precura @@ -19886,7 +19886,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id precursor) + :bigmap-id (bigmap-id precursor1) :continues '() :callback-list '((23 . init-mood-precurb)) :borrow #f @@ -19920,7 +19920,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id precursor) + :bigmap-id (bigmap-id precursor1) :continues '((new 'static 'continue-point :name "precurc-end" :level 'precurc @@ -20012,7 +20012,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -20046,7 +20046,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "precurd-start" :level 'precurd @@ -20131,7 +20131,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "bikearena-start" :level 'bikearena @@ -20183,7 +20183,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "halfpipe" :level 'halfpipe @@ -20234,7 +20234,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "sndtest" :level 'sndtest @@ -20285,7 +20285,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -20319,7 +20319,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -20353,7 +20353,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -20387,7 +20387,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -20421,7 +20421,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "chartest-1" :level 'chartest @@ -20472,7 +20472,7 @@ :ocean-alpha 1.0 :priority 100 :draw-priority 10.0 - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '() :callback-list '() :borrow #f @@ -20506,7 +20506,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "testisle-start" :level 'testisle @@ -20558,7 +20558,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "gregtest-start" :level 'gregtest @@ -20625,7 +20625,7 @@ :priority 100 :draw-priority 10.0 :base-task-mask (task-mask task0) - :bigmap-id (bigmap-id no-map) + :bigmap-id (bigmap-id none) :continues '((new 'static 'continue-point :name "jump test" :level '4amy diff --git a/test/decompiler/reference/jak3/engine/physics/ragdoll-h_REF.gc b/test/decompiler/reference/jak3/engine/physics/ragdoll-h_REF.gc index d43a08d9eb..18c9dd5bd2 100644 --- a/test/decompiler/reference/jak3/engine/physics/ragdoll-h_REF.gc +++ b/test/decompiler/reference/jak3/engine/physics/ragdoll-h_REF.gc @@ -294,7 +294,7 @@ (disable-for-duration (_type_ time-frame) none) (ragdoll-proc-method-17 (_type_ ragdoll-edit-info) none) (ragdoll-proc-method-18 (_type_ ragdoll-edit-info) none) - (ragdoll-proc-method-19 (_type_) none) + (ragdoll-proc-method-19 (_type_) symbol) ) ) @@ -334,3 +334,7 @@ ;; failed to figure out what this is: 0 + + + + diff --git a/test/decompiler/reference/jak3/engine/physics/ragdoll_REF.gc b/test/decompiler/reference/jak3/engine/physics/ragdoll_REF.gc index a0edf61634..6291b6a335 100644 --- a/test/decompiler/reference/jak3/engine/physics/ragdoll_REF.gc +++ b/test/decompiler/reference/jak3/engine/physics/ragdoll_REF.gc @@ -1616,13 +1616,11 @@ ) ;; definition for method 19 of type ragdoll-proc -;; WARN: Return type mismatch symbol vs none. (defmethod ragdoll-proc-method-19 ((this ragdoll-proc)) (if (nonzero? (-> this ragdoll)) (logtest? (-> this ragdoll ragdoll-flags) (ragdoll-flag rf2)) #t ) - (none) ) ;; failed to figure out what this is: @@ -1748,3 +1746,7 @@ ) (go-virtual idle) ) + + + + diff --git a/test/decompiler/reference/jak3/engine/physics/rigid-body_REF.gc b/test/decompiler/reference/jak3/engine/physics/rigid-body_REF.gc index e7293aec4a..1bc0d6def0 100644 --- a/test/decompiler/reference/jak3/engine/physics/rigid-body_REF.gc +++ b/test/decompiler/reference/jak3/engine/physics/rigid-body_REF.gc @@ -114,10 +114,10 @@ ;; definition for method 28 of type rigid-body-control ;; WARN: Return type mismatch int vs none. (defmethod rigid-body-control-method-28 ((this rigid-body-control) (arg0 vector) (arg1 quaternion)) - (let ((s3-0 (new 'stack-no-clear 'rigid-body-impact))) - (quaternion->matrix (the-as matrix (-> s3-0 normal)) arg1) - (vector-rotate*! (-> s3-0 point) (-> this info cm-offset-joint) (the-as matrix (-> s3-0 normal))) - (vector+! (-> this position) arg0 (-> s3-0 point)) + (let ((s3-0 (new 'stack-no-clear 'rigid-body-stack))) + (quaternion->matrix (-> s3-0 mat) arg1) + (vector-rotate*! (-> s3-0 vec) (-> this info cm-offset-joint) (-> s3-0 mat)) + (vector+! (-> this position) arg0 (-> s3-0 vec)) ) (quaternion-copy! (the-as quaternion (-> this rot)) arg1) (quaternion-normalize! (the-as quaternion (-> this rot))) diff --git a/test/decompiler/reference/jak3/engine/process-drawable/process-taskable_REF.gc b/test/decompiler/reference/jak3/engine/process-drawable/process-taskable_REF.gc index 7e6f694f8c..440d4493a9 100644 --- a/test/decompiler/reference/jak3/engine/process-drawable/process-taskable_REF.gc +++ b/test/decompiler/reference/jak3/engine/process-drawable/process-taskable_REF.gc @@ -383,10 +383,7 @@ (if (-> self skel effect) (do-effect (-> self skel effect) "death-default" 0.0 -1) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (if (logtest? (-> self flags) (process-taskable-flags ptf5)) (restart-mission) @@ -402,10 +399,7 @@ :enter (-> (method-of-type process-taskable active) enter) :exit (-> (method-of-type process-taskable active) exit) :code (behavior ((arg0 game-task-event)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (go-virtual hide) ) diff --git a/test/decompiler/reference/jak3/engine/scene/scene_REF.gc b/test/decompiler/reference/jak3/engine/scene/scene_REF.gc index b11968a00d..0e0980d899 100644 --- a/test/decompiler/reference/jak3/engine/scene/scene_REF.gc +++ b/test/decompiler/reference/jak3/engine/scene/scene_REF.gc @@ -1370,10 +1370,7 @@ #x33001 #t ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.05)) - (suspend) - ) + (suspend-for (seconds 0.05) ) (set! (-> *setting-control* user-current bg-a) 0.0) (remove-setting! 'movie) diff --git a/test/decompiler/reference/jak3/engine/sound/gsound_REF.gc b/test/decompiler/reference/jak3/engine/sound/gsound_REF.gc index 6e37a7ad34..10bea89a44 100644 --- a/test/decompiler/reference/jak3/engine/sound/gsound_REF.gc +++ b/test/decompiler/reference/jak3/engine/sound/gsound_REF.gc @@ -1461,10 +1461,7 @@ (set! (-> a1-3 0) 'empty0) (want-sound-banks *load-state* a1-3) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((a1-4 (new 'stack-no-clear 'array 'symbol 4))) (set! (-> a1-4 2) (-> gp-0 4)) diff --git a/test/decompiler/reference/jak3/engine/target/board/board-states_REF.gc b/test/decompiler/reference/jak3/engine/target/board/board-states_REF.gc index 7648b2bcaf..0878f5d2e9 100644 --- a/test/decompiler/reference/jak3/engine/target/board/board-states_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/board/board-states_REF.gc @@ -3432,10 +3432,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s3-2 (current-time))) - (until (time-elapsed? s3-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (move-to-point! (-> self control) s4-1) ) diff --git a/test/decompiler/reference/jak3/engine/target/flut/flut_REF.gc b/test/decompiler/reference/jak3/engine/target/flut/flut_REF.gc index 95d4e32942..b2b3665f87 100644 --- a/test/decompiler/reference/jak3/engine/target/flut/flut_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/flut/flut_REF.gc @@ -359,11 +359,8 @@ (ja-channel-set! 0) (ja-post) (when (not (and (-> self entity) (= (-> self entity extra process) self))) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.1)) - (spawn-part-and-sound! self) - (suspend) - ) + (suspend-for (seconds 0.1) + (spawn-part-and-sound! self) ) (deactivate self) ) @@ -381,11 +378,8 @@ (spawn-part-and-sound! self) (suspend) ) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 1)) - (spawn-part-and-sound! self) - (suspend) - ) + (suspend-for (seconds 1) + (spawn-part-and-sound! self) ) (go arg0) ) diff --git a/test/decompiler/reference/jak3/engine/target/flut/target-flut_REF.gc b/test/decompiler/reference/jak3/engine/target/flut/target-flut_REF.gc index 64e6b3cbaa..775de20fc4 100644 --- a/test/decompiler/reference/jak3/engine/target/flut/target-flut_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/flut/target-flut_REF.gc @@ -2827,10 +2827,7 @@ (let ((s3-2 (new-stack-vector0))) (set! (-> s3-2 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s2-0 (current-time))) - (until (time-elapsed? s2-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (move-to-point! (-> self control) s3-2) ) @@ -3015,33 +3012,30 @@ ) ) ) - (let ((s5-3 (current-time))) - (until (time-elapsed? s5-3 (seconds 1)) - (target-flut-falling-anim-trans) - (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) - (let ((v1-39 (new-stack-vector0)) - (f0-6 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) - ) - 0.0 - (vector-! - v1-39 - (-> self control transv) - (vector-float*! v1-39 (-> self control dynam gravity-normal) (the-as float f0-6)) + (suspend-for (seconds 1) + (target-flut-falling-anim-trans) + (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) + (let ((v1-39 (new-stack-vector0)) + (f0-6 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) ) - (let* ((f1-7 (vector-length v1-39)) - (f2-2 f1-7) - ) - (if (< (the-as float (-> self control unknown-word04)) (the-as float f0-6)) - (set! f0-6 (-> self control unknown-word04)) - ) - (vector+! - (-> self control transv) - (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f0-6)) - (vector-float*! v1-39 v1-39 (/ f1-7 f2-2)) + 0.0 + (vector-! + v1-39 + (-> self control transv) + (vector-float*! v1-39 (-> self control dynam gravity-normal) (the-as float f0-6)) + ) + (let* ((f1-7 (vector-length v1-39)) + (f2-2 f1-7) + ) + (if (< (the-as float (-> self control unknown-word04)) (the-as float f0-6)) + (set! f0-6 (-> self control unknown-word04)) ) + (vector+! + (-> self control transv) + (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f0-6)) + (vector-float*! v1-39 v1-39 (/ f1-7 f2-2)) ) ) - (suspend) ) ) (remove-setting! 'mode-name) @@ -3077,10 +3071,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-8 (current-time))) - (until (time-elapsed? s5-8 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) (('lava 'melt 'fry 'slime) @@ -3103,10 +3094,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-12 (current-time))) - (until (time-elapsed? s5-12 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) ) diff --git a/test/decompiler/reference/jak3/engine/target/gun/gun-blue-shot_REF.gc b/test/decompiler/reference/jak3/engine/target/gun/gun-blue-shot_REF.gc index 640356954b..f2887318d7 100644 --- a/test/decompiler/reference/jak3/engine/target/gun/gun-blue-shot_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/gun/gun-blue-shot_REF.gc @@ -3152,10 +3152,7 @@ (defstate dissipate (gun-blue-shot-3) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (go-virtual die) ) @@ -3165,10 +3162,7 @@ (defstate impact (gun-blue-shot-3) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (go-virtual die) ) diff --git a/test/decompiler/reference/jak3/engine/target/gun/gun-dark-shot_REF.gc b/test/decompiler/reference/jak3/engine/target/gun/gun-dark-shot_REF.gc index 3cc1d66c93..c6f863f995 100644 --- a/test/decompiler/reference/jak3/engine/target/gun/gun-dark-shot_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/gun/gun-dark-shot_REF.gc @@ -996,7 +996,7 @@ (f0-4 (evaluate (-> this blur-curve) f0-3 (loop-behavior use-default))) (f0-5 (- 1.0 f0-4)) ) - (blit-displays-work-method-17 + (setup-zoom-blur-2d *blit-displays-work* (-> this root trans) (the-as int (-> this num-blur-segments)) @@ -1205,7 +1205,7 @@ :exit (behavior () (when (= (process->handle self) (-> *last-active-nuke* last-active-nuke)) (disable *screen-filter*) - (blit-displays-work-method-17 *blit-displays-work* (-> self root trans) 0 1.0 #f) + (setup-zoom-blur-2d *blit-displays-work* (-> self root trans) 0 1.0 #f) ) ) :trans (behavior () @@ -1384,7 +1384,7 @@ :exit (behavior () (when (= (process->handle self) (-> *last-active-nuke* last-active-nuke)) (disable *screen-filter*) - (blit-displays-work-method-17 *blit-displays-work* (-> self root trans) 0 1.0 #f) + (setup-zoom-blur-2d *blit-displays-work* (-> self root trans) 0 1.0 #f) ) ) :trans (behavior () @@ -3150,64 +3150,61 @@ ;; INFO: Used lq/sq ;; WARN: Return type mismatch int vs object. (defbehavior zero-g-wait-for-land gravity-spinner () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.5)) - (let* ((s4-0 (handle->process (-> self parent-hand))) - (s5-0 (if (type? s4-0 process-focusable) - s4-0 + (suspend-for (seconds 1.5) + (let* ((s4-0 (handle->process (-> self parent-hand))) + (s5-0 (if (type? s4-0 process-focusable) + s4-0 + ) + ) + ) + (cond + ((and s5-0 + (not (logtest? (-> (the-as process-focusable s5-0) focus-status) (focus-status disable dead inactive))) + ) + (if (or (< (- (-> (get-trans (the-as process-focusable s5-0) 3) y) + (-> (the-as process-focusable s5-0) root root-prim local-sphere w) ) + (-> self ground-height) + ) + (let ((s4-1 (-> (the-as process-focusable s5-0) root))) + (and (if (type? s4-1 collide-shape-moving) + s4-1 + ) + (logtest? (-> (the-as collide-shape-moving (-> (the-as process-focusable s5-0) root)) status) + (collide-status on-surface touch-surface) + ) + ) ) + ) + (return (the-as object 0)) ) - (cond - ((and s5-0 - (not (logtest? (-> (the-as process-focusable s5-0) focus-status) (focus-status disable dead inactive))) - ) - (if (or (< (- (-> (get-trans (the-as process-focusable s5-0) 3) y) - (-> (the-as process-focusable s5-0) root root-prim local-sphere w) - ) - (-> self ground-height) - ) - (let ((s4-1 (-> (the-as process-focusable s5-0) root))) - (and (if (type? s4-1 collide-shape-moving) - s4-1 - ) - (logtest? (-> (the-as collide-shape-moving (-> (the-as process-focusable s5-0) root)) status) - (collide-status on-surface touch-surface) - ) - ) - ) - ) - (return (the-as object 0)) + (when (not (logtest? (process-mask vehicle) (-> (the-as process-focusable s5-0) mask))) + (let ((s4-2 (new 'stack 'sphere))) + (vector-lerp! + s4-2 + (-> (the-as process-focusable s5-0) root root-prim local-sphere) + (-> self original-sphere-offset) + (* 3.0 (seconds-per-frame)) ) - (when (not (logtest? (process-mask vehicle) (-> (the-as process-focusable s5-0) mask))) - (let ((s4-2 (new 'stack 'sphere))) - (vector-lerp! - s4-2 - (-> (the-as process-focusable s5-0) root root-prim local-sphere) - (-> self original-sphere-offset) - (* 3.0 (seconds-per-frame)) - ) - (set! (-> s4-2 r) (lerp - (-> (the-as process-focusable s5-0) root root-prim local-sphere w) - (-> self original-sphere-offset r) - (* 3.0 (seconds-per-frame)) - ) + (set! (-> s4-2 r) (lerp + (-> (the-as process-focusable s5-0) root root-prim local-sphere w) + (-> self original-sphere-offset r) + (* 3.0 (seconds-per-frame)) + ) + ) + (set! (-> (the-as process-focusable s5-0) root root-prim local-sphere quad) (-> s4-2 quad)) + ) + (if (>= (+ (current-time) (seconds -1)) time) + (set! (-> (the-as process-focusable s5-0) root root-prim local-sphere quad) + (-> self original-sphere-offset quad) ) - (set! (-> (the-as process-focusable s5-0) root root-prim local-sphere quad) (-> s4-2 quad)) ) - (if (>= (+ (current-time) (seconds -1)) gp-0) - (set! (-> (the-as process-focusable s5-0) root root-prim local-sphere quad) - (-> self original-sphere-offset quad) - ) - ) - ) ) - (else - (return (the-as object 0)) - ) + ) + (else + (return (the-as object 0)) ) ) - (suspend) ) ) (the-as int #f) @@ -3906,16 +3903,10 @@ ) ) (set! f30-0 (+ -0.6 f30-0)) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.15)) - (suspend) - ) + (suspend-for (seconds 0.15) ) ) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 13.5)) - (suspend) - ) + (suspend-for (seconds 13.5) ) (go empty-state) (set! f30-0 4.0) diff --git a/test/decompiler/reference/jak3/engine/target/gun/gun-red-shot_REF.gc b/test/decompiler/reference/jak3/engine/target/gun/gun-red-shot_REF.gc index 3106ae0591..7056c5fc74 100644 --- a/test/decompiler/reference/jak3/engine/target/gun/gun-red-shot_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/gun/gun-red-shot_REF.gc @@ -1700,7 +1700,7 @@ ;; definition for method 10 of type gun-red-2-shockwave (defmethod deactivate ((this gun-red-2-shockwave)) "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." - (blit-displays-work-method-17 *blit-displays-work* (-> this origin) 0 1.0 #f) + (setup-zoom-blur-2d *blit-displays-work* (-> this origin) 0 1.0 #f) (call-parent-method this) (none) ) @@ -1740,7 +1740,7 @@ (set! (-> self current-warp-alpha) 1.0) ) :exit (behavior () - (blit-displays-work-method-17 *blit-displays-work* (-> self origin) 0 1.0 #f) + (setup-zoom-blur-2d *blit-displays-work* (-> self origin) 0 1.0 #f) ) :trans (behavior () (let ((f0-1 @@ -1776,7 +1776,7 @@ (let* ((f0-16 (- 1.0 (evaluate *impact-blur* f0-14 (loop-behavior use-default)))) (f0-19 (lerp f0-16 1.0 (fmax 0.0 (- 0.5 (-> self strength))))) ) - (blit-displays-work-method-17 *blit-displays-work* (-> self origin) 2 (fmin 1.0 f0-19) #f) + (setup-zoom-blur-2d *blit-displays-work* (-> self origin) 2 (fmin 1.0 f0-19) #f) ) ) (if (< (-> self current-stage-t) 1.0) @@ -2192,11 +2192,7 @@ :virtual #t :trans (behavior () (go-impact self) - (let ((t9-2 (-> (find-parent-state) trans))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler trans) ) ) @@ -2205,11 +2201,7 @@ :virtual #t :trans (behavior () (go-impact self) - (let ((t9-2 (-> (find-parent-state) trans))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler trans) ) ) @@ -2246,7 +2238,7 @@ ;; definition for method 10 of type gun-red-3-grenade (defmethod deactivate ((this gun-red-3-grenade)) "Make a process dead, clean it up, remove it from the active pool, and return to dead pool." - (blit-displays-work-method-17 *blit-displays-work* *zero-vector* 0 1.0 #f) + (setup-zoom-blur-2d *blit-displays-work* *zero-vector* 0 1.0 #f) (call-parent-method this) (none) ) @@ -2326,7 +2318,7 @@ (f0-14 (lerp f0-13 1.0 f30-1)) ) (set! (-> *display* force-sync) (the-as uint 2)) - (blit-displays-work-method-17 *blit-displays-work* (-> self root trans) 2 (fmin 1.0 f0-14) #f) + (setup-zoom-blur-2d *blit-displays-work* (-> self root trans) 2 (fmin 1.0 f0-14) #f) ) ) (let ((gp-8 (-> self child))) @@ -2340,7 +2332,7 @@ ) ) ) - (blit-displays-work-method-17 *blit-displays-work* (-> self root trans) 15 1.0 #f) + (setup-zoom-blur-2d *blit-displays-work* (-> self root trans) 15 1.0 #f) (deactivate self) ) ) diff --git a/test/decompiler/reference/jak3/engine/target/gun/gun-yellow-shot_REF.gc b/test/decompiler/reference/jak3/engine/target/gun/gun-yellow-shot_REF.gc index 13e4a0c579..9d7bcf465e 100644 --- a/test/decompiler/reference/jak3/engine/target/gun/gun-yellow-shot_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/gun/gun-yellow-shot_REF.gc @@ -757,10 +757,7 @@ process (lambda :behavior process ((arg0 handle)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (send-event (handle->process arg0) 'die) ) @@ -791,10 +788,7 @@ ) (logior! (-> self draw status) (draw-control-status no-draw)) (transform-post) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (deactivate self) ) @@ -938,11 +932,7 @@ ) ) ) - (let ((t9-5 (-> (find-parent-state) trans))) - (if t9-5 - (t9-5) - ) - ) + (call-parent-state-handler trans) (ja-post) ) ) @@ -2117,11 +2107,7 @@ :virtual #t :enter (behavior () (sound-stop (-> self snd-trail)) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) ) diff --git a/test/decompiler/reference/jak3/engine/target/indax/target-indax_REF.gc b/test/decompiler/reference/jak3/engine/target/indax/target-indax_REF.gc index f844958bbd..ec102a3ee7 100644 --- a/test/decompiler/reference/jak3/engine/target/indax/target-indax_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/indax/target-indax_REF.gc @@ -1594,10 +1594,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (move-to-point! (-> self control) s4-1) ) @@ -1828,10 +1825,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) ((= arg0 'bot) diff --git a/test/decompiler/reference/jak3/engine/target/mech/mech-states_REF.gc b/test/decompiler/reference/jak3/engine/target/mech/mech-states_REF.gc index 28f05368d1..3a8dc2171a 100644 --- a/test/decompiler/reference/jak3/engine/target/mech/mech-states_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/mech/mech-states_REF.gc @@ -1039,10 +1039,7 @@ (let ((s4-1 (new-stack-vector0))) (set! (-> s4-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (move-to-point! (-> self control) s4-1) ) @@ -1184,11 +1181,8 @@ ) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! jakb-mech-jump-loop-ja :num! (loop! 0.5) :frame-num 0.0) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.8)) - (ja :group! jakb-mech-jump-loop-ja :num! (loop! 0.5)) - (suspend) - ) + (suspend-for (seconds 0.8) + (ja :group! jakb-mech-jump-loop-ja :num! (loop! 0.5)) ) (remove-setting! 'mode-name) ) @@ -1291,10 +1285,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-10 (current-time))) - (until (time-elapsed? gp-10 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) ) diff --git a/test/decompiler/reference/jak3/engine/target/mech/mech_REF.gc b/test/decompiler/reference/jak3/engine/target/mech/mech_REF.gc index 805915a479..4129d885da 100644 --- a/test/decompiler/reference/jak3/engine/target/mech/mech_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/mech/mech_REF.gc @@ -270,11 +270,8 @@ (mech-method-24 self) (suspend) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (mech-method-24 self) - (suspend) - ) + (suspend-for (seconds 1) + (mech-method-24 self) ) (go arg0) ) diff --git a/test/decompiler/reference/jak3/engine/target/pilot-states_REF.gc b/test/decompiler/reference/jak3/engine/target/pilot-states_REF.gc index 5bd9ae8b42..a158a32d0f 100644 --- a/test/decompiler/reference/jak3/engine/target/pilot-states_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/pilot-states_REF.gc @@ -1034,10 +1034,7 @@ (logior! (-> self focus-status) (focus-status dead)) (case arg0 (('melt 'grenade 'explode) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (case arg0 (('dark-eco-pool) @@ -1086,10 +1083,7 @@ ) 0 (ja-channel-set! 0) - (let ((s5-11 (current-time))) - (until (time-elapsed? s5-11 (seconds 1.8)) - (suspend) - ) + (suspend-for (seconds 1.8) ) ) (('endlessfall) @@ -1119,10 +1113,7 @@ ) ) ) - (let ((s5-13 (current-time))) - (until (time-elapsed? s5-13 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) ) (('drown-death) @@ -1145,10 +1136,7 @@ ) ) ) - (let ((s5-14 (current-time))) - (until (time-elapsed? s5-14 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) (('bot) @@ -1159,10 +1147,7 @@ ) ) (('big-explosion) - (let ((s5-15 (current-time))) - (until (time-elapsed? s5-15 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) (else diff --git a/test/decompiler/reference/jak3/engine/target/target-darkjak_REF.gc b/test/decompiler/reference/jak3/engine/target/target-darkjak_REF.gc index e4706a25b2..fd7e1da9b9 100644 --- a/test/decompiler/reference/jak3/engine/target/target-darkjak_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/target-darkjak_REF.gc @@ -319,11 +319,7 @@ (set! (-> self part) (the-as sparticle-launch-control 0)) 0 ) - (let ((t9-5 (-> (find-parent-state) enter))) - (if t9-5 - (t9-5) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () (dotimes (gp-0 (-> self bolts length)) diff --git a/test/decompiler/reference/jak3/engine/target/target-death_REF.gc b/test/decompiler/reference/jak3/engine/target/target-death_REF.gc index fddb65f23a..acf55b0038 100644 --- a/test/decompiler/reference/jak3/engine/target/target-death_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/target-death_REF.gc @@ -56,10 +56,7 @@ (intro-play) ) ((logtest? (-> arg0 flags) (continue-flags warp-gate)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.05)) - (suspend) - ) + (suspend-for (seconds 0.05) ) (let ((s5-1 (new 'static 'vector)) (a2-0 (find-nearest-entity (-> arg0 trans) warp-gate)) @@ -219,10 +216,7 @@ (go target-grab 'stance) ) (else - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.05)) - (suspend) - ) + (suspend-for (seconds 0.05) ) ) ) @@ -1476,10 +1470,7 @@ (let ((gp-1 (new-stack-vector0))) (set! (-> gp-1 quad) (-> self control last-trans-on-ground quad)) (ja-channel-set! 0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (move-to-point! (-> self control) gp-1) ) @@ -2337,10 +2328,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-5 (current-time))) - (until (time-elapsed? s5-5 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) (('grenade 'big-explosion 'explode) @@ -2420,10 +2408,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((s5-10 (current-time))) - (until (time-elapsed? s5-10 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) ) @@ -2440,10 +2425,7 @@ (set! (-> self post-hook) target-no-ja-move-post) (ja-channel-set! 0) (ja-post) - (let ((s5-11 (current-time))) - (until (time-elapsed? s5-11 (seconds 1.2)) - (suspend) - ) + (suspend-for (seconds 1.2) ) ) ((= v1-61 'endlessfall) @@ -2482,38 +2464,35 @@ (target-falling-anim 30 (seconds 0.33)) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! jakb-launch-jump-loop-ja :num! (loop! 0.5) :frame-num 0.0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.8)) - (when (and (logtest? (-> self control status) (collide-status on-surface)) (!= (-> self control cur-pat event) 2)) - (set! v1-24 'target-hit-ground-hard) - (goto cfg-17) + (suspend-for (seconds 0.8) + (when (and (logtest? (-> self control status) (collide-status on-surface)) (!= (-> self control cur-pat event) 2)) + (set! v1-24 'target-hit-ground-hard) + (goto cfg-17) + ) + (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) + (let ((v1-49 (new-stack-vector0)) + (f0-7 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) + ) + 0.0 + (vector-! + v1-49 + (-> self control transv) + (vector-float*! v1-49 (-> self control dynam gravity-normal) (the-as float f0-7)) ) - (vector-seek! (-> self draw color-mult) *zero-vector* (seconds-per-frame)) - (let ((v1-49 (new-stack-vector0)) - (f0-7 (the-as number (vector-dot (-> self control dynam gravity-normal) (-> self control transv)))) + (let* ((f1-7 (vector-length v1-49)) + (f2-2 f1-7) + ) + (if (< (the-as float (-> self control unknown-word04)) (the-as float f0-7)) + (set! f0-7 (-> self control unknown-word04)) ) - 0.0 - (vector-! - v1-49 + (vector+! (-> self control transv) - (vector-float*! v1-49 (-> self control dynam gravity-normal) (the-as float f0-7)) - ) - (let* ((f1-7 (vector-length v1-49)) - (f2-2 f1-7) - ) - (if (< (the-as float (-> self control unknown-word04)) (the-as float f0-7)) - (set! f0-7 (-> self control unknown-word04)) - ) - (vector+! - (-> self control transv) - (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f0-7)) - (vector-float*! v1-49 v1-49 (/ f1-7 f2-2)) - ) + (vector-float*! (-> self control transv) (-> self control dynam gravity-normal) (the-as float f0-7)) + (vector-float*! v1-49 v1-49 (/ f1-7 f2-2)) ) ) - (ja :group! jakb-launch-jump-loop-ja :num! (loop! 0.5)) - (suspend) ) + (ja :group! jakb-launch-jump-loop-ja :num! (loop! 0.5)) ) (set! v1-24 #f) (label cfg-17) @@ -2538,10 +2517,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) (remove-setting! 'mode-name) @@ -2707,10 +2683,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((s5-14 (current-time))) - (until (time-elapsed? s5-14 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) ((= v1-61 'centipede) diff --git a/test/decompiler/reference/jak3/engine/target/target-handler_REF.gc b/test/decompiler/reference/jak3/engine/target/target-handler_REF.gc index e501d549c1..036e5c2827 100644 --- a/test/decompiler/reference/jak3/engine/target/target-handler_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/target-handler_REF.gc @@ -202,10 +202,8 @@ process (lambda :behavior target () - (let ((gp-0 (current-time)) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 (seconds 1)) + (let ((gp-0 (current-time))) + (suspend-for (seconds 1) (when (time-elapsed? gp-0 (seconds 0.03)) (set! gp-0 (current-time)) (process-drawable-shock-effect @@ -218,7 +216,6 @@ 40960.0 ) ) - (suspend) ) ) (none) diff --git a/test/decompiler/reference/jak3/engine/target/target-invisible_REF.gc b/test/decompiler/reference/jak3/engine/target/target-invisible_REF.gc index 5209f515c3..ce2e91ba8d 100644 --- a/test/decompiler/reference/jak3/engine/target/target-invisible_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/target-invisible_REF.gc @@ -484,10 +484,7 @@ (set-time! (-> self state-time)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.66)) - (suspend) - ) + (suspend-for (seconds 0.66) ) (cond ((logtest? (-> *part-group-id-table* 182 flags) (sp-group-flag sp13)) @@ -515,10 +512,7 @@ ) ) (sound-play "dark-maker") - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (go-virtual idle) ) diff --git a/test/decompiler/reference/jak3/engine/target/target-lightjak_REF.gc b/test/decompiler/reference/jak3/engine/target/target-lightjak_REF.gc index 94543b7082..2af58bda19 100644 --- a/test/decompiler/reference/jak3/engine/target/target-lightjak_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/target-lightjak_REF.gc @@ -2348,11 +2348,8 @@ (defstate die (freeze-screen) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (seek! (-> self transition) 0.0 (seconds-per-frame)) - (suspend) - ) + (suspend-for (seconds 1) + (seek! (-> self transition) 0.0 (seconds-per-frame)) ) ) ) diff --git a/test/decompiler/reference/jak3/engine/target/target-turret_REF.gc b/test/decompiler/reference/jak3/engine/target/target-turret_REF.gc index 91b7992224..691eec6b85 100644 --- a/test/decompiler/reference/jak3/engine/target/target-turret_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/target-turret_REF.gc @@ -1169,10 +1169,7 @@ (sound-stop (-> self sound-id 1)) (sound-stop (-> self sound-id 2)) (logior! (-> self focus-status) (focus-status disable ignore inactive)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.8)) - (suspend) - ) + (suspend-for (seconds 0.8) ) (send-event (handle->process (-> self rider)) diff --git a/test/decompiler/reference/jak3/engine/target/target2_REF.gc b/test/decompiler/reference/jak3/engine/target/target2_REF.gc index dcbc86a151..9ec48cc728 100644 --- a/test/decompiler/reference/jak3/engine/target/target2_REF.gc +++ b/test/decompiler/reference/jak3/engine/target/target2_REF.gc @@ -43,12 +43,9 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.3)) - (suspend) - (ja :num! (seek! (ja-aframe 19.0 0) 0.05)) - (suspend) - ) + (suspend-for (seconds 0.3) + (suspend) + (ja :num! (seek! (ja-aframe 19.0 0) 0.05)) ) (ja-channel-push! 1 (seconds 0.3)) (ja-no-eval :group! jakb-painful-land-ja :num! (seek!) :frame-num (ja-aframe 40.0 0)) @@ -1595,11 +1592,8 @@ (until #f (let ((s5-0 (rand-vu-int-range 30 600))) (ja :group! jakb-wall-hide-head-ja) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 s5-0) - (gp-0) - (suspend) - ) + (suspend-for s5-0 + (gp-0) ) ) (let ((f30-0 (rand-vu-float-range 0.5 1.5))) @@ -1637,12 +1631,9 @@ (suspend) (ja :num! (seek! max f30-0)) ) - (let ((s5-2 (rand-vu-int-range 60 300)) - (s4-2 (current-time)) - ) - (until (time-elapsed? s4-2 s5-2) + (let ((s5-2 (rand-vu-int-range 60 300))) + (suspend-for s5-2 (gp-0) - (suspend) ) ) (ja-no-eval :group! jakb-wall-hide-head-left-ja :num! (seek! 0.0 f30-0) :frame-num max) @@ -1659,12 +1650,9 @@ (suspend) (ja :num! (seek! 0.0 f30-0)) ) - (let ((s5-3 (rand-vu-int-range 60 300)) - (s4-3 (current-time)) - ) - (until (time-elapsed? s4-3 s5-3) + (let ((s5-3 (rand-vu-int-range 60 300))) + (suspend-for s5-3 (gp-0) - (suspend) ) ) (ja-no-eval :group! jakb-wall-hide-head-right-ja :num! (seek! max f30-0) :frame-num 0.0) @@ -2019,14 +2007,13 @@ (suspend) (ja :num! (seek!)) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (the-as time-frame arg0)) - (ja-no-eval :group! jakb-blast-recover-loop-ja :num! (seek!) :frame-num 0.0) - (until (ja-done? 0) - (suspend) - (ja :num! (seek!)) - ) + (suspend-for (the-as time-frame arg0) + (ja-no-eval :group! jakb-blast-recover-loop-ja :num! (seek!) :frame-num 0.0) + (until (ja-done? 0) + (suspend) + (ja :num! (seek!)) ) + (empty-form) ) (ja-no-eval :group! jakb-blast-recover-end-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) diff --git a/test/decompiler/reference/jak3/engine/ui/bigmap-h_REF.gc b/test/decompiler/reference/jak3/engine/ui/bigmap-h_REF.gc index c4982b019e..b41540271c 100644 --- a/test/decompiler/reference/jak3/engine/ui/bigmap-h_REF.gc +++ b/test/decompiler/reference/jak3/engine/ui/bigmap-h_REF.gc @@ -76,13 +76,13 @@ (deftype bigmap (basic) ((drawing-flag symbol) (loading-flag symbol) - (bigmap-index uint32) + (bigmap-index bigmap-id) (bigmap-image external-art-buffer) (tpage external-art-buffer) - (tpage2 basic) + (tpage2 external-art-buffer) (progress-minimap texture-page) (progress-minimap2 texture-page) - (load-index uint32) + (load-index bigmap-id) (x0 int32) (y0 int32) (x1 int32) @@ -99,24 +99,24 @@ (color vector4w :inline) (corner vector 4 :inline) (auto-save-icon-flag symbol) - (global-flags uint32) + (global-flags bigmap-flag) ) (:methods (new (symbol type) _type_) - (bigmap-method-9 () none) + (initialize (_type_) none) (update (_type_) none) - (bigmap-method-11 (_type_) symbol) - (bigmap-method-12 () none) - (bigmap-method-13 () none) + (loaded? (_type_) symbol) + (draw! (_type_ int int int int) none) + (handle-cpad-input (_type_) none) (enable-drawing (_type_) none) (disable-drawing (_type_) int) - (bigmap-method-16 (_type_) none) - (bigmap-method-17 () none) - (bigmap-method-18 () none) - (bigmap-method-19 () none) - (bigmap-method-20 () none) - (bigmap-method-21 () none) - (bigmap-method-22 () none) + (set-map-indices! (_type_) none) + (set-pos! (_type_ vector) none) + (bigmap-method-18 (_type_ (pointer int32)) none) + (texture-upload-dma (_type_ dma-buffer (pointer uint32) int int int gs-psm) none) + (bigmap-method-20 (_type_ dma-buffer) symbol) + (sprite-dma (_type_ dma-buffer int int int int int int) object) + (draw-from-minimap (_type_ dma-buffer connection-minimap) none) ) ) @@ -159,3 +159,7 @@ ;; failed to figure out what this is: 0 + + + + diff --git a/test/decompiler/reference/jak3/engine/ui/bigmap_REF.gc b/test/decompiler/reference/jak3/engine/ui/bigmap_REF.gc new file mode 100644 index 0000000000..79221ad45a --- /dev/null +++ b/test/decompiler/reference/jak3/engine/ui/bigmap_REF.gc @@ -0,0 +1,963 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition for method 0 of type bigmap +(defmethod new bigmap ((allocation symbol) (type-to-make type)) + (let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size))))) + (set! (-> gp-0 bigmap-image) + ((method-of-type external-art-buffer new) + allocation + external-art-buffer + 0 + (lambda ((arg0 external-art-buffer)) + (let ((a1-3 (logand -64 (+ -591936 (-> *display* frames 0 global-buf real-buffer-end) 63))) + (v1-1 (-> arg0 heap)) + ) + (set! (-> v1-1 base) (the-as pointer a1-3)) + (set! (-> v1-1 current) (-> v1-1 base)) + (set! (-> v1-1 top-base) (&+ (-> v1-1 base) #x90800)) + (set! (-> v1-1 top) (-> v1-1 top-base)) + ) + 0 + ) + #f + ) + ) + (set! (-> gp-0 tpage) + ((method-of-type external-art-buffer new) + allocation + external-art-buffer + 0 + (lambda ((arg0 external-art-buffer)) + (let ((a1-3 (logand -64 (+ -597056 (-> *display* frames 1 global-buf real-buffer-end) 63))) + (v1-1 (-> arg0 heap)) + ) + (set! (-> v1-1 base) (the-as pointer a1-3)) + (set! (-> v1-1 current) (-> v1-1 base)) + (set! (-> v1-1 top-base) (&+ (-> v1-1 base) #x54000)) + (set! (-> v1-1 top) (-> v1-1 top-base)) + ) + 0 + ) + #f + ) + ) + (set! (-> gp-0 tpage2) + ((method-of-type external-art-buffer new) + allocation + external-art-buffer + 0 + (lambda ((arg0 external-art-buffer)) + (let ((a1-3 (logand -64 (+ -941120 (-> *display* frames 1 global-buf real-buffer-end) 63))) + (v1-1 (-> arg0 heap)) + ) + (set! (-> v1-1 base) (the-as pointer a1-3)) + (set! (-> v1-1 current) (-> v1-1 base)) + (set! (-> v1-1 top-base) (&+ (-> v1-1 base) #x54000)) + (set! (-> v1-1 top) (-> v1-1 top-base)) + ) + 0 + ) + #f + ) + ) + (set! (-> gp-0 sprite-tmpl dma-vif dma) (new 'static 'dma-tag :qwc #x6 :id (dma-tag-id cnt))) + (set! (-> gp-0 sprite-tmpl dma-vif vif0) (new 'static 'vif-tag)) + (set! (-> gp-0 sprite-tmpl dma-vif vif1) (new 'static 'vif-tag :imm #x6 :cmd (vif-cmd direct) :msk #x1)) + (set! (-> gp-0 sprite-tmpl gif0) (the-as uint #x50ab400000008001)) + (set! (-> gp-0 sprite-tmpl gif1) (the-as uint #x53531)) + (set! (-> gp-0 draw-tmpl dma-vif dma) (new 'static 'dma-tag :qwc #xa :id (dma-tag-id cnt))) + (set! (-> gp-0 draw-tmpl dma-vif vif0) (new 'static 'vif-tag)) + (set! (-> gp-0 draw-tmpl dma-vif vif1) (new 'static 'vif-tag :imm #xa :cmd (vif-cmd direct) :msk #x1)) + (set! (-> gp-0 draw-tmpl gif0) (the-as uint #x90aa400000008001)) + (set! (-> gp-0 draw-tmpl gif1) (the-as uint #x535353531)) + (set! (-> gp-0 adgif-tmpl dma-vif dma) (new 'static 'dma-tag :qwc #x6 :id (dma-tag-id cnt))) + (set! (-> gp-0 adgif-tmpl dma-vif vif0) (new 'static 'vif-tag)) + (set! (-> gp-0 adgif-tmpl dma-vif vif1) (new 'static 'vif-tag :imm #x6 :cmd (vif-cmd direct) :msk #x1)) + (set! (-> gp-0 adgif-tmpl gif0) (the-as uint #x1000000000008005)) + (set! (-> gp-0 adgif-tmpl gif1) (the-as uint 14)) + (set-vector! (-> gp-0 offset) 0.0 0.0 0.0 0.0) + (set-vector! (-> gp-0 scroll) 0.0 0.0 0.0 0.0) + (set-vector! (-> gp-0 pos) 0 0 0 0) + (set-vector! (-> gp-0 color) 128 128 128 128) + (set! (-> gp-0 drawing-flag) #f) + (set! (-> gp-0 loading-flag) #f) + (set! (-> gp-0 progress-minimap) #f) + (set! (-> gp-0 progress-minimap2) #f) + (set! (-> gp-0 auto-save-icon-flag) #f) + (initialize gp-0) + gp-0 + ) + ) + +;; definition for symbol *bigmap-info-array*, type bigmap-info-array +(define *bigmap-info-array* + (new 'static 'bigmap-info-array + :data (new 'static 'inline-array bigmap-info 24 + (new 'static 'bigmap-info :x -2621440.0 :y -4456448.0 :z 16384.0 :w 0.000061035156) + (new 'static 'bigmap-info :x -2621440.0 :y -4456448.0 :z 16384.0 :w 0.000061035156) + (new 'static 'bigmap-info :x -2038169.6 :y -2301542.5 :z 27443.2 :w 0.0000364389) + (new 'static 'bigmap-info :x -354713.6 :y -1128448.0 :z 4505.6 :w 0.00022194601) + (new 'static 'bigmap-info :x -4205363.0 :y 3437363.2 :z 4628.48 :w 0.00021605365) + (new 'static 'bigmap-info :x -3381657.5 :y 2019737.6 :z 7618.56 :w 0.0001312584) + (new 'static 'bigmap-info :x -1399193.6 :y -1023590.4 :z 5406.72 :w 0.00018495502) + (new 'static 'bigmap-info :x 2215526.5 :y 615055.4 :z 10444.8 :w 0.00009574142) + (new 'static 'bigmap-info :x 2215526.5 :y 615055.4 :z 10444.8 :w 0.00009574142) + (new 'static 'bigmap-info :z 16384.0 :w 0.000061035156) + (new 'static 'bigmap-info :x -1481932.8 :y -918323.2 :z 5857.28 :w 0.00017072771) + (new 'static 'bigmap-info :x -1481932.8 :y -918323.2 :z 5857.28 :w 0.00017072771) + (new 'static 'bigmap-info :x -2614886.5 :y -1766195.2 :z 9052.16 :w 0.00011047087) + (new 'static 'bigmap-info :x -2530508.8 :y -1041203.2 :z 5591.04 :w 0.0001788576) + (new 'static 'bigmap-info :x -2374451.2 :y -4505.6 :z 4628.48 :w 0.00021605365) + (new 'static 'bigmap-info :x -2712780.8 :y -2477260.8 :z 6471.68 :w 0.00015451938) + (new 'static 'bigmap-info :x -1218560.0 :y -3392307.2 :z 5857.28 :w 0.00017072771) + (new 'static 'bigmap-info :x 16039117.0 :y 16509747.0 :z 3317.76 :w 0.00030140817) + (new 'static 'bigmap-info :x 15403827.0 :y 16360653.0 :z 5283.84 :w 0.0001892563) + (new 'static 'bigmap-info :x 15403827.0 :y 16360653.0 :z 5283.84 :w 0.0001892563) + (new 'static 'bigmap-info :x 15403827.0 :y 16360653.0 :z 5283.84 :w 0.0001892563) + (new 'static 'bigmap-info :x -1716224.0 :y 1286144.0 :z 3604.48 :w 0.00027743253) + (new 'static 'bigmap-info :x -1316864.0 :y -2084126.8 :z 4014.08 :w 0.00024912308) + (new 'static 'bigmap-info :x 5619712.0 :y -2914304.0 :z 9830.4 :w 0.00010172526) + ) + ) + ) + +;; definition for method 17 of type bigmap +;; WARN: Return type mismatch int vs none. +(defmethod set-pos! ((this bigmap) (arg0 vector)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (init-vf0-vector) + (.lvf vf1 (&-> arg0 quad)) + (.lvf vf2 (&-> this offset quad)) + (.add.z.vf vf1 vf0 vf1 :mask #b10) + (.sub.vf vf1 vf1 vf2) + (.mul.w.vf vf1 vf1 vf2) + (.ftoi.vf vf1 vf1) + (.svf (&-> this pos quad) vf1) + 0 + (none) + ) + ) + +;; definition for method 18 of type bigmap +;; WARN: Return type mismatch int vs none. +(defmethod bigmap-method-18 ((this bigmap) (arg0 (pointer int32))) + (when (or (= (-> this load-index) (bigmap-id sewer-met-hum)) (= (-> this load-index) (bigmap-id sewer-hum-kg))) + (let ((v1-4 (-> arg0 0))) + (set! (-> arg0 0) (-> arg0 1)) + (set! (-> arg0 1) (- 832 v1-4)) + ) + ) + (none) + ) + +;; definition for method 19 of type bigmap +;; WARN: Return type mismatch int vs none. +(defmethod texture-upload-dma ((this bigmap) (arg0 dma-buffer) (arg1 (pointer uint32)) (arg2 int) (arg3 int) (arg4 int) (arg5 gs-psm)) + (local-vars (sv-16 int)) + (set! sv-16 arg2) + (dma-buffer-add-gs-set arg0 + (bitbltbuf (new 'static 'gs-bitbltbuf :dpsm (the-as int arg5) :dbp sv-16 :dbw (/ arg3 64))) + (trxpos (new 'static 'gs-trxpos)) + (trxreg (new 'static 'gs-trxreg :rrw arg3 :rrh arg4)) + (trxdir (new 'static 'gs-trxdir)) + ) + (dma-buffer-add-ref-texture arg0 arg1 arg3 arg4 arg5) + 0 + (none) + ) + +;; definition for method 21 of type bigmap +;; INFO: Used lq/sq +;; WARN: Return type mismatch pointer vs object. +(defmethod sprite-dma ((this bigmap) (arg0 dma-buffer) (arg1 int) (arg2 int) (arg3 int) (arg4 int) (arg5 int) (arg6 int)) + (let ((v1-0 (the-as object (-> arg0 base)))) + (let ((t5-0 0) + (t4-2 (the int (* 416.0 (-> *video-params* relative-x-scale)))) + ) + (set! (-> (the-as (inline-array vector4w) v1-0) 0 quad) (-> this sprite-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) v1-0) 1 quad) (-> this sprite-tmpl quad 1)) + (set! (-> (the-as (inline-array vector4w) v1-0) 2 quad) (-> this color quad)) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 3) (* arg5 16) (* t5-0 16) 0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 4) (* arg1 16) (* arg3 16) #xfffff0 0) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 5) (* arg6 16) (* t4-2 16) 0 0) + ) + (set-vector! (-> (the-as (inline-array vector4w) v1-0) 6) (* arg2 16) (* arg4 16) #xfffff0 0) + ) + (let ((v0-0 (&+ (-> arg0 base) 112))) + (set! (-> arg0 base) v0-0) + v0-0 + ) + ) + +;; definition for method 20 of type bigmap +;; INFO: Used lq/sq +(defmethod bigmap-method-20 ((this bigmap) (arg0 dma-buffer)) + (local-vars (sv-16 uint)) + (let* ((s4-0 (the-as (pointer uint32) (-> this bigmap-image art-group))) + (f0-1 (* 0.001953125 (the float (- (-> this x1) (-> this x0))))) + (s3-0 (the int (* 256.0 f0-1))) + (v1-5 (the int (-> this scroll x))) + (a0-2 (-> this x0)) + (f1-7 (-> this scroll x)) + (s2-0 (- a0-2 (the int (* (- f1-7 (* (the float (the int (/ f1-7 256.0))) 256.0)) f0-1)))) + (s1-0 (/ v1-5 256)) + (s0-0 (/ (+ v1-5 511) 256)) + ) + (-> s4-0 2) + (set! sv-16 (* (-> s4-0 3) 256)) + (while (>= s0-0 s1-0) + (texture-upload-dma + this + arg0 + (the-as (pointer uint32) (+ (+ (-> s4-0 0) 16) (the-as uint s4-0))) + 0 + 16 + 16 + (gs-psm ct32) + ) + (dma-buffer-add-gs-set arg0 (texflush 0)) + (let ((v1-18 (+ (-> s4-0 1) (* (the-as uint s1-0) sv-16) (* (the int (-> this scroll y)) 256)))) + (texture-upload-dma + this + arg0 + (the-as (pointer uint32) (+ (+ v1-18 16) (the-as uint s4-0))) + 8 + 256 + 416 + (gs-psm mt8) + ) + ) + (dma-buffer-add-gs-set arg0 + (tex0-1 (new 'static 'gs-tex0 :tbp0 #x8 :tbw #x4 :psm #x13 :tw #x8 :th #x9 :cld #x1)) + (tex1-1 (new 'static 'gs-tex1)) + (texflush 0) + ) + (sprite-dma this arg0 (+ s2-0 1792) (+ s3-0 1792 s2-0) (-> this y0) (-> this y1) 0 256) + (+! s2-0 s3-0) + (+! s1-0 1) + ) + ) + #f + ) + +;; definition for method 22 of type bigmap +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod draw-from-minimap ((this bigmap) (arg0 dma-buffer) (arg1 connection-minimap)) + (local-vars (sv-80 vector4w)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (init-vf0-vector) + (cond + ((= (-> arg1 position) #t) + (let* ((s3-0 (handle->process (-> arg1 handle))) + (v1-4 (if (type? s3-0 process-drawable) + (the-as process-drawable s3-0) + ) + ) + ) + (if (and v1-4 (nonzero? (-> v1-4 root))) + (set! (-> arg1 last-world-pos quad) (-> v1-4 root trans quad)) + ) + ) + ) + ((and (= (logand (the-as int (-> arg1 position)) 7) 4) + (= (-> (the-as entity-actor (-> arg1 position)) type) entity-actor) + ) + (let* ((v1-14 (the-as entity-actor (-> arg1 position))) + (s3-1 (if v1-14 + (-> v1-14 extra process) + ) + ) + (a0-13 (if (type? s3-1 process-drawable) + (the-as process-drawable s3-1) + ) + ) + ) + (if a0-13 + (set! (-> arg1 last-world-pos quad) (-> a0-13 root trans quad)) + (set! (-> arg1 last-world-pos quad) (-> (the-as entity-actor (-> arg1 position)) extra trans quad)) + ) + ) + ) + (else + (set! (-> arg1 last-world-pos quad) (-> arg1 position quad)) + ) + ) + (let ((f30-0 (-> arg1 class scale)) + (s1-0 (-> arg1 class color)) + ) + (set! sv-80 (new 'stack-no-clear 'vector4w)) + (let ((s0-0 (new-stack-vector0)) + (s2-0 (new-stack-vector0)) + (s3-2 (new-stack-vector0)) + ) + (let ((f26-0 (-> *video-params* relative-x-scale)) + (f28-0 (-> *video-params* relative-x-scale-reciprical)) + ) + (-> arg1 class) + (.lvf vf1 (&-> arg1 last-world-pos quad)) + (.lvf vf2 (&-> this offset quad)) + (.add.z.vf vf1 vf0 vf1 :mask #b10) + (.sub.vf vf1 vf1 vf2) + (.mul.w.vf vf1 vf1 vf2) + (.ftoi.vf vf1 vf1) + (.svf (&-> sv-80 quad) vf1) + (if (logtest? (-> arg1 class flags) (minimap-flag goal)) + (set! (-> arg1 class icon-xy x) (the-as uint (mod (the int (-> this goal-time)) 6))) + ) + (bigmap-method-18 this (the-as (pointer int32) sv-80)) + (cond + ((get-horizontal-flip-flag *blit-displays-work*) + (set! f26-0 (- f26-0)) + (set! (-> s0-0 x) (+ (the float (+ (- 2304 (-> sv-80 x)) (-> this x1))) (-> this scroll x))) + ) + (else + (set! (-> s0-0 x) (- (the float (+ (-> sv-80 x) 1792 (-> this x0))) (-> this scroll x))) + ) + ) + (set! (-> s0-0 y) (+ 1840.0 (* (- (the float (-> sv-80 y)) (-> this scroll y)) f28-0))) + (let ((f0-12 (* 20.0 f26-0 f30-0)) + (f1-8 (* 20.0 f28-0 f30-0)) + ) + (set! (-> s2-0 x) (the float (the int (- (-> s0-0 x) (* 0.5 f0-12))))) + (set! (-> s2-0 y) (the float (the int (- (-> s0-0 y) (* 0.5 f1-8))))) + (set! (-> s3-2 x) (+ (-> s2-0 x) f0-12)) + (set! (-> s3-2 y) (+ (-> s2-0 y) f1-8)) + ) + ) + (let* ((a2-1 (the-as uint (+ (* (the-as uint 320) (-> arg1 class icon-xy x)) 8))) + (a3-0 (the-as uint (+ (* (the-as uint 320) (-> arg1 class icon-xy y)) 8))) + (v1-55 (+ (the-as int a2-1) 312)) + (a0-35 (+ (the-as int a3-0) 312)) + (a1-6 (the-as object (-> arg0 base))) + ) + (set! (-> (the-as (inline-array vector4w) a1-6) 0 quad) (-> this sprite-tmpl dma-vif quad)) + (set! (-> (the-as (inline-array vector4w) a1-6) 1 quad) (-> this sprite-tmpl quad 1)) + (set-vector! + (-> (the-as (inline-array vector4w) a1-6) 2) + (the-as int (-> s1-0 r)) + (the-as int (-> s1-0 g)) + (the-as int (-> s1-0 b)) + 128 + ) + (set-vector! (-> (the-as (inline-array vector4w) a1-6) 3) (the-as int a2-1) (the-as int a3-0) 0 0) + (set-vector! + (-> (the-as (inline-array vector4w) a1-6) 4) + (the int (* 16.0 (-> s2-0 x))) + (the int (* 16.0 (-> s2-0 y))) + #xffffff + 0 + ) + (set-vector! (-> (the-as (inline-array vector4w) a1-6) 5) v1-55 a0-35 0 0) + (set-vector! + (-> (the-as (inline-array vector4w) a1-6) 6) + (the int (* 16.0 (-> s3-2 x))) + (the int (* 16.0 (-> s3-2 y))) + #xffffff + 0 + ) + ) + ) + ) + (&+! (-> arg0 base) 112) + 0 + (none) + ) + ) + +;; definition for method 9 of type bigmap +;; WARN: Return type mismatch int vs none. +(defmethod initialize ((this bigmap)) + (set! (-> this bigmap-index) (bigmap-id city)) + (set-pending-file (-> this bigmap-image) (the-as string #f) 0 (process->handle *dproc*) 0.0) + 0 + (none) + ) + +;; definition for method 10 of type bigmap +;; WARN: Return type mismatch int vs none. +(defmethod update ((this bigmap)) + (when (-> this drawing-flag) + (update! *minimap*) + (cond + ((= (-> *blit-displays-work* count-down) 1) + (set-pending-file + (-> this bigmap-image) + "world-map" + (the-as int (-> this load-index)) + (process->handle *dproc*) + 0.0 + ) + (set-pending-file (-> this tpage) "progress-minimap" 0 (process->handle *dproc*) 0.0) + (set-pending-file (-> this tpage2) "progress-minimap" 1 (process->handle *dproc*) 0.0) + (set! (-> this loading-flag) #t) + ) + (else + (update (-> this bigmap-image)) + (update (-> this tpage)) + (update (-> this tpage2)) + (when (and (-> this loading-flag) + (= (file-status (-> this bigmap-image) "world-map" (the-as int (-> this load-index))) 'active) + (= (file-status (-> this tpage) "progress-minimap" 0) 'active) + (= (file-status (-> this tpage2) "progress-minimap" 1) 'active) + (not (load-in-progress? *level*)) + ) + (let ((s5-0 (-> *level* loading-level)) + (s4-0 (-> *texture-pool* allocate-func)) + (s3-0 (-> *texture-relocate-later* memcpy)) + (s2-0 loading-level) + ) + (set! (-> *texture-pool* allocate-func) texture-page-common-boot-allocate) + (set! (-> *level* loading-level) #f) + (set! (-> *texture-relocate-later* memcpy) #f) + (set! loading-level (-> this tpage heap)) + (set! (-> this progress-minimap) + (the-as + texture-page + (link (-> this tpage buf) (-> this tpage load-file data) (-> this tpage len) (-> this tpage heap) 4) + ) + ) + (set! (-> this progress-minimap2) + (the-as + texture-page + (link (-> this tpage2 buf) (-> this tpage2 load-file data) (-> this tpage2 len) (-> this tpage2 heap) 4) + ) + ) + (set! (-> *level* loading-level) s5-0) + (set! (-> *texture-pool* allocate-func) s4-0) + (set! (-> *texture-relocate-later* memcpy) s3-0) + (set! loading-level s2-0) + ) + (set! (-> this loading-flag) #f) + ) + ) + ) + ) + 0 + (none) + ) + +;; definition for method 11 of type bigmap +;; WARN: Return type mismatch texture-page vs symbol. +(defmethod loaded? ((this bigmap)) + (the-as symbol (and (-> *bigmap* progress-minimap) (-> *bigmap* progress-minimap2))) + ) + +;; definition for method 12 of type bigmap +;; INFO: Used lq/sq +;; WARN: Return type mismatch int vs none. +(defmethod draw! ((this bigmap) (arg0 int) (arg1 int) (arg2 int) (arg3 int)) + (local-vars + (sv-96 (inline-array vector4w)) + (sv-100 texture) + (sv-104 matrix) + (sv-112 int) + (sv-120 float) + (sv-240 (function bigmap vector none)) + ) + (when (and (= (file-status (-> this bigmap-image) "world-map" (the-as int (-> this load-index))) 'active) + (not (-> this loading-flag)) + ) + (with-dma-buffer-add-bucket ((s2-0 (-> *display* frames (-> *display* on-screen) global-buf)) + (bucket-id hud-draw-hud-alpha) + ) + (dma-buffer-add-gs-set s2-0 + (scissor-1 (new 'static 'gs-scissor + :scax0 (+ arg0 -1792) + :scay0 (+ arg1 -1840) + :scax1 (+ arg2 -1792) + :scay1 (+ arg3 -1840) + ) + ) + (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))) + (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1)) + (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp))) + ) + (let ((v1-14 (the-as object (-> this bigmap-image art-group))) + (f0-0 (-> *video-params* relative-x-scale)) + ) + (set! (-> this scroll x) + (fmax 0.0 (fmin (-> this scroll x) (the float (+ (-> (the-as (pointer uint32) v1-14) 2) -513)))) + ) + (set! (-> this scroll y) + (fmax + 0.0 + (fmin (-> this scroll y) (+ (- -1.0 (* 416.0 f0-0)) (the float (-> (the-as (pointer uint32) v1-14) 3)))) + ) + ) + ) + (cond + ((get-horizontal-flip-flag *blit-displays-work*) + (set! (-> this x0) (+ arg2 -1792)) + (set! (-> this x1) (+ arg0 -1792)) + ) + (else + (set! (-> this x0) (+ arg0 -1792)) + (set! (-> this x1) (+ arg2 -1792)) + ) + ) + (set! (-> this y0) arg1) + (set! (-> this y1) arg3) + (bigmap-method-20 this s2-0) + (when (!= (-> this load-index) (bigmap-id none)) + (when (= (-> this y0) 1840) + (let ((s0-1 (-> s2-0 base)) + (s1-1 (lookup-texture-by-id-fast (new 'static 'texture-id :index #x4 :page #x11))) + ) + (when s1-1 + (set! (-> (the-as (pointer uint128) s0-1) 0) (-> this adgif-tmpl dma-vif quad)) + (set! (-> (the-as (pointer uint128) s0-1) 1) (-> this adgif-tmpl quad 1)) + (adgif-shader<-texture-simple! (the-as adgif-shader (&+ s0-1 32)) s1-1) + (&+! (-> s2-0 base) 112) + ) + (if (not s1-1) + (format 0 "ERROR: bigmap: mini-map-icons texture is #f~%") + ) + ) + (let ((s1-2 (-> *minimap* engine alive-list))) + (while s1-2 + (let ((a2-11 s1-2)) + (when (logtest? (-> a2-11 class flags) (minimap-flag bigmap bigmap-only)) + (if (not (and (logtest? (minimap-flag local-only) (-> a2-11 class flags)) + (not (logtest? (the-as minimap-flag (logand (bigmap-flag ctywide waswide wasall desert) (-> this global-flags))) + (-> a2-11 class flags) + ) + ) + ) + ) + (draw-from-minimap this s2-0 a2-11) + ) + ) + ) + (set! s1-2 (-> s1-2 next)) + ) + ) + (let ((s1-3 (new 'stack-no-clear 'vector)) + (f30-0 (-> *video-params* relative-x-scale)) + ) + (vector-z-quaternion! s1-3 (-> *target* control quat)) + (vector-xz-normalize! s1-3 -1.0) + (set! (-> s1-3 y) 0.0) + (set! (-> s1-3 w) 0.0) + (set! sv-96 (the-as (inline-array vector4w) (-> s2-0 base))) + (set! sv-100 (lookup-texture-by-id-fast (new 'static 'texture-id :index #x1 :page #x11))) + (set! sv-104 (new 'stack-no-clear 'matrix)) + (set! sv-112 (the int (* 56.0 f30-0))) + (set! sv-120 (-> *video-params* relative-x-scale-reciprical)) + (when sv-100 + (let ((s0-2 this)) + (set! sv-240 (method-of-object s0-2 set-pos!)) + (let ((a1-29 (target-pos 0))) + (sv-240 s0-2 a1-29) + ) + ) + (let ((s0-3 (new 'stack 'vector4w))) + 0.0 + (set! (-> s0-3 quad) (-> this pos quad)) + (bigmap-method-18 this (the-as (pointer int32) s0-3)) + (let ((f0-15 (cond + ((get-horizontal-flip-flag *blit-displays-work*) + (set! f30-0 (- f30-0)) + (+ (the float (+ (- 2304 (-> s0-3 x)) (-> this x1))) (-> this scroll x)) + ) + (else + (- (the float (+ (-> s0-3 x) 1792 (-> this x0))) (-> this scroll x)) + ) + ) + ) + ) + (set-vector! (-> sv-104 rvec) (* (-> s1-3 z) f30-0) 0.0 (- (-> s1-3 x)) 0.0) + (set-vector! (-> sv-104 uvec) 0.0 1.0 0.0 0.0) + (set-vector! (-> sv-104 fvec) (* (-> s1-3 x) f30-0) 0.0 (-> s1-3 z) 1.0) + (set-vector! + (-> sv-104 trans) + f0-15 + 0.0 + (+ 1840.0 (* (- (the float (-> s0-3 y)) (-> this scroll y)) sv-120)) + 1.0 + ) + ) + ) + (let* ((v1-83 (mod (-> *display* real-clock frame-counter) 360)) + (f0-26 (+ 1.5 (* 0.25 (cos (* 182.04445 (the float v1-83)))))) + (f0-27 (* 7.0 f0-26)) + ) + (cond + ((or (= (-> this load-index) (bigmap-id sewer-met-hum)) (= (-> this load-index) (bigmap-id sewer-hum-kg))) + (set-vector! (-> this corner 0) (- f0-27) 0.0 0.0 1.0) + (set-vector! (-> this corner 1) 0.0 0.0 f0-27 1.0) + (set-vector! (-> this corner 2) 0.0 0.0 (- f0-27) 1.0) + (set-vector! (-> this corner 3) f0-27 0.0 0.0 1.0) + ) + (else + (set-vector! (-> this corner 0) 0.0 0.0 (- f0-27) 1.0) + (set-vector! (-> this corner 1) f0-27 0.0 0.0 1.0) + (set-vector! (-> this corner 2) (- f0-27) 0.0 0.0 1.0) + (set-vector! (-> this corner 3) 0.0 0.0 f0-27 1.0) + ) + ) + ) + (vector-matrix*! (the-as vector (-> this corner)) (the-as vector (-> this corner)) sv-104) + (vector-matrix*! (-> this corner 1) (-> this corner 1) sv-104) + (vector-matrix*! (-> this corner 2) (-> this corner 2) sv-104) + (vector-matrix*! (-> this corner 3) (-> this corner 3) sv-104) + (let ((v1-97 (-> this adgif-tmpl dma-vif quad))) + (set! (-> sv-96 0 quad) v1-97) + ) + (let ((v1-98 (-> this adgif-tmpl quad 1))) + (set! (-> sv-96 1 quad) v1-98) + ) + (adgif-shader<-texture-simple! (the-as adgif-shader (-> sv-96 2)) sv-100) + (let ((v1-100 (-> this draw-tmpl dma-vif quad))) + (set! (-> sv-96 7 quad) v1-100) + ) + (let ((v1-101 (-> this draw-tmpl quad 1))) + (set! (-> sv-96 8 quad) v1-101) + ) + (set-vector! (-> sv-96 9) 0 255 255 128) + (set-vector! (-> sv-96 10) 0 0 0 0) + (set-vector! + (-> sv-96 11) + (the int (* 16.0 (-> this corner 0 x))) + (the int (* 16.0 (-> this corner 0 z))) + #xffffff + 0 + ) + (set-vector! (-> sv-96 12) 256 0 0 0) + (set-vector! + (-> sv-96 13) + (the int (* 16.0 (-> this corner 1 x))) + (the int (* 16.0 (-> this corner 1 z))) + #xffffff + 0 + ) + (set-vector! (-> sv-96 14) 0 256 0 0) + (set-vector! + (-> sv-96 15) + (the int (* 16.0 (-> this corner 2 x))) + (the int (* 16.0 (-> this corner 2 z))) + #xffffff + 0 + ) + (set-vector! (-> sv-96 16) 256 256 0 0) + (set-vector! + (-> sv-96 17) + (the int (* 16.0 (-> this corner 3 x))) + (the int (* 16.0 (-> this corner 3 z))) + #xffffff + 0 + ) + (&+! (-> s2-0 base) 288) + ) + ) + ) + ) + (dma-buffer-add-gs-set s2-0 (scissor-1 (new 'static 'gs-scissor :scax1 #x1ff :scay1 #x19f))) + ) + (when (= (-> this load-index) (bigmap-id none)) + (let ((s3-1 + (new 'stack 'font-context *font-default-matrix* 0 0 0.0 (font-color default) (font-flags shadow kerning)) + ) + ) + (let ((f30-2 (* 0.0024038462 (the float (- arg3 arg1))))) + (let ((v1-138 s3-1)) + (set! (-> v1-138 scale) f30-2) + ) + (let ((v1-139 s3-1)) + (set! (-> v1-139 width) (the float (the int (* 400.0 f30-2)))) + ) + (let ((a0-100 s3-1)) + (set! (-> a0-100 flags) (font-flags kerning middle large)) + ) + (let ((s5-1 print-game-text)) + (format (clear *temp-string*) "~S" (lookup-text! *common-text* (text-id map-data-unavailable) #f)) + (let* ((f0-63 (s5-1 *temp-string* s3-1 #t 44 (bucket-id hud-draw-hud-alpha))) + (v1-142 s3-1) + (a0-106 (- 256 (the int (* 200.0 f30-2)))) + (a1-52 (- 208 (the int (* 0.5 f0-63)))) + ) + (set! (-> v1-142 origin x) (the float a0-106)) + (set! (-> v1-142 origin y) (the float a1-52)) + ) + ) + ) + (let ((s5-2 print-game-text)) + (format (clear *temp-string*) "~S" (lookup-text! *common-text* (text-id map-data-unavailable) #f)) + (s5-2 *temp-string* s3-1 #f 44 (bucket-id hud-draw-hud-alpha)) + ) + ) + ) + (+! (-> this goal-time) (* 16.0 (seconds-per-frame))) + (set-dirty-mask! (-> *level* level-default) 4 #x1a400 0) + ) + 0 + (none) + ) + +;; definition for method 13 of type bigmap +;; WARN: Return type mismatch int vs none. +(defmethod handle-cpad-input ((this bigmap)) + (let ((v1-1 (-> this bigmap-image art-group)) + (s5-0 (-> *cpad-list* cpads 0)) + ) + (when v1-1 + (let ((f30-0 (analog-input (the-as int (-> s5-0 leftx)) 128.0 32.0 110.0 4.0)) + (f0-0 (analog-input (the-as int (-> s5-0 lefty)) 128.0 32.0 110.0 4.0)) + ) + (+! (-> this scroll x) f30-0) + (+! (-> this scroll y) f0-0) + ) + ) + ) + 0 + (none) + ) + +;; definition for method 16 of type bigmap +;; WARN: Return type mismatch int vs none. +(defmethod set-map-indices! ((this bigmap)) + (let ((s5-0 (level-get-target-inside *level*))) + (let ((v1-2 (-> *setting-control* user-current bigmap-level))) + (cond + (v1-2 + (cond + ((= v1-2 'city) + (set! (-> this bigmap-index) (bigmap-id city)) + 0 + ) + ((= v1-2 'comb) + (set! (-> this bigmap-index) (bigmap-id comb)) + ) + ((= v1-2 'desert) + (set! (-> this bigmap-index) (bigmap-id desert)) + ) + ((= v1-2 'factory) + (set! (-> this bigmap-index) (bigmap-id factory)) + ) + ((= v1-2 'forest) + (set! (-> this bigmap-index) (bigmap-id forest)) + ) + ((= v1-2 'metalhead-city) + (set! (-> this bigmap-index) (bigmap-id mhcity)) + ) + ((= v1-2 'mine) + (set! (-> this bigmap-index) (bigmap-id mine)) + ) + ((= v1-2 'nest) + (set! (-> this bigmap-index) (bigmap-id nest)) + ) + ((= v1-2 'nest2) + (set! (-> this bigmap-index) (bigmap-id nest2)) + ) + ((= v1-2 'none) + (set! (-> this bigmap-index) (bigmap-id none)) + ) + ((= v1-2 'precursor1) + (set! (-> this bigmap-index) (bigmap-id precursor1)) + ) + ((= v1-2 'precursor2) + (set! (-> this bigmap-index) (bigmap-id precursor2)) + ) + ((= v1-2 'rubble) + (set! (-> this bigmap-index) (bigmap-id rubble)) + ) + ((= v1-2 'sewer-hum-kg) + (set! (-> this bigmap-index) (bigmap-id sewer-hum-kg)) + ) + ((= v1-2 'sewer-kg-met) + (set! (-> this bigmap-index) (bigmap-id sewer-kg-met)) + ) + ((= v1-2 'sewer-met-hum) + (set! (-> this bigmap-index) (bigmap-id sewer-met-hum)) + ) + ((= v1-2 'stadium) + (set! (-> this bigmap-index) (bigmap-id stadium)) + ) + ((= v1-2 'temple1) + (set! (-> this bigmap-index) (bigmap-id temple1)) + ) + ((= v1-2 'temple2) + (set! (-> this bigmap-index) (bigmap-id temple2)) + ) + ((= v1-2 'temple3) + (set! (-> this bigmap-index) (bigmap-id temple3)) + ) + ((= v1-2 'temple4) + (set! (-> this bigmap-index) (bigmap-id temple4)) + ) + ((= v1-2 'tower) + (set! (-> this bigmap-index) (bigmap-id tower)) + ) + ((= v1-2 'volcano) + (set! (-> this bigmap-index) (bigmap-id volcano)) + ) + ((= v1-2 'wascity) + (set! (-> this bigmap-index) (bigmap-id wascity)) + ) + ) + ) + (s5-0 + (set! (-> this bigmap-index) (-> s5-0 info bigmap-id)) + ) + ) + ) + (if (and (= (status-of-level-and-borrows *level* 'ctywide #f) 'active) + (not (or (= (-> s5-0 name) 'mhcitya) (= (-> s5-0 name) 'mhcityb))) + ) + (set! (-> this bigmap-index) (-> ctyport bigmap-id)) + ) + ) + (cond + ((= (-> this bigmap-index) (bigmap-id temple1)) + (cond + ((task-node-closed? (game-task-node factory-boss-resolution)) + (set! (-> this load-index) (bigmap-id temple4)) + ) + ((task-node-closed? (game-task-node desert-oasis-defense-resolution)) + (set! (-> this load-index) (bigmap-id temple3)) + ) + ((task-node-closed? (game-task-node volcano-darkeco-resolution)) + (set! (-> this load-index) (bigmap-id temple2)) + ) + (else + (set! (-> this load-index) (bigmap-id temple1)) + ) + ) + ) + ((= (-> this bigmap-index) (bigmap-id precursor1)) + (if (task-node-closed? (game-task-node comb-wild-ride-resolution)) + (set! (-> this load-index) (bigmap-id precursor2)) + (set! (-> this load-index) (bigmap-id precursor1)) + ) + ) + ((= (-> this bigmap-index) (bigmap-id nest)) + (if (task-node-closed? (game-task-node nest-eggs-gas)) + (set! (-> this load-index) (bigmap-id nest2)) + (set! (-> this load-index) (bigmap-id nest)) + ) + ) + (else + (set! (-> this load-index) (-> this bigmap-index)) + ) + ) + (none) + ) + +;; definition for method 14 of type bigmap +;; INFO: Used lq/sq +;; WARN: Return type mismatch bigmap-flag vs none. +(defmethod enable-drawing ((this bigmap)) + (set-map-indices! this) + (set! (-> this offset quad) (-> *bigmap-info-array* data (-> this load-index) quad)) + (let ((s4-0 (target-pos 0)) + (s5-0 (-> this offset)) + ) + (cond + ((= (-> this load-index) (bigmap-id sewer-hum-kg)) + (let ((a0-10 (level-get *level* 'sewa))) + (if a0-10 + (set! (-> a0-10 info bigmap-id) (bigmap-id sewer-hum-kg)) + ) + ) + (set! (-> this scroll x) (+ -256.0 (* (- (-> s4-0 y) (-> s5-0 y)) (-> s5-0 w)))) + (set! (-> this scroll y) (- 624.0 (* (- (-> s4-0 x) (-> s5-0 x)) (-> s5-0 w)))) + ) + ((= (-> this load-index) (bigmap-id sewer-kg-met)) + (let ((a0-14 (level-get *level* 'sewa))) + (if a0-14 + (set! (-> a0-14 info bigmap-id) (bigmap-id sewer-kg-met)) + ) + ) + (set! (-> this scroll x) (+ -256.0 (* (- (-> s4-0 x) (-> s5-0 x)) (-> s5-0 w)))) + (set! (-> this scroll y) (+ -208.0 (* (- (-> s4-0 z) (-> s5-0 y)) (-> s5-0 w)))) + ) + ((= (-> this load-index) (bigmap-id sewer-met-hum)) + (let ((a0-18 (level-get *level* 'sewa))) + (if a0-18 + (set! (-> a0-18 info bigmap-id) (bigmap-id sewer-met-hum)) + ) + ) + (set! (-> this scroll x) (+ -256.0 (* (- (-> s4-0 y) (-> s5-0 y)) (-> s5-0 w)))) + (set! (-> this scroll y) (- 624.0 (* (- (-> s4-0 x) (-> s5-0 x)) (-> s5-0 w)))) + ) + (else + (set! (-> this scroll x) (+ -256.0 (* (- (-> s4-0 x) (-> s5-0 x)) (-> s5-0 w)))) + (set! (-> this scroll y) (+ -208.0 (* (- (-> s4-0 z) (-> s5-0 y)) (-> s5-0 w)))) + ) + ) + ) + (set! (-> this drawing-flag) #t) + (set! (-> this loading-flag) #f) + (set! (-> this global-flags) (bigmap-flag)) + (if (= (status-of-level-and-borrows *level* 'ctywide #f) 'active) + (logior! (-> this global-flags) (bigmap-flag ctywide)) + ) + (if (= (status-of-level-and-borrows *level* 'waswide #f) 'active) + (logior! (-> this global-flags) (bigmap-flag wasall)) + ) + (if (= (status-of-level-and-borrows *level* 'wasall #f) 'active) + (logior! (-> this global-flags) (bigmap-flag waswide)) + ) + (if (= (status-of-level-and-borrows *level* 'desert #f) 'active) + (logior! (-> this global-flags) (bigmap-flag desert)) + ) + (none) + ) + +;; definition for method 15 of type bigmap +(defmethod disable-drawing ((this bigmap)) + (set-pending-file + (-> this bigmap-image) + (the-as string #f) + (the-as int (-> this bigmap-index)) + (process->handle *dproc*) + 0.0 + ) + (set-pending-file (-> this tpage) (the-as string #f) 0 (process->handle *dproc*) 0.0) + (set-pending-file (-> this tpage2) (the-as string #f) 0 (process->handle *dproc*) 0.0) + (let ((v1-12 #f)) + (while (not v1-12) + (update (-> this bigmap-image)) + (update (-> this tpage)) + (update (-> this tpage2)) + (set! v1-12 (and (= (-> this bigmap-image status) 'inactive) + (= (-> this tpage status) 'inactive) + (= (-> this tpage2 status) 'inactive) + ) + ) + ) + ) + (when (-> this progress-minimap) + (unload-page *texture-pool* (-> this progress-minimap)) + (set! (-> (&-> *level* level-default texture-page 6) 0) (the-as texture-page 0)) + (set! (-> this progress-minimap) #f) + ) + (when (-> this progress-minimap2) + (unload-page *texture-pool* (-> this progress-minimap2)) + (set! (-> (&-> *level* level-default texture-page 3) 0) (the-as texture-page 0)) + (set! (-> this progress-minimap2) #f) + ) + (set! (-> this drawing-flag) #f) + (set! (-> this loading-flag) #f) + 0 + ) + +;; failed to figure out what this is: +(kmemopen global "bigmap-struct") + +;; definition for symbol *bigmap*, type bigmap +(define *bigmap* (new 'global 'bigmap)) + +;; failed to figure out what this is: +(kmemclose) + + + + diff --git a/test/decompiler/reference/jak3/engine/ui/minimap_REF.gc b/test/decompiler/reference/jak3/engine/ui/minimap_REF.gc index 6f6b3dc530..355b034ce0 100644 --- a/test/decompiler/reference/jak3/engine/ui/minimap_REF.gc +++ b/test/decompiler/reference/jak3/engine/ui/minimap_REF.gc @@ -1937,7 +1937,7 @@ ) (while s3-0 (let ((s4-0 (-> s3-0 next))) - (when (or (bigmap-method-11 *bigmap*) (not (paused?))) + (when (or (loaded? *bigmap*) (not (paused?))) (cond ((logtest? (-> s3-0 flags) (minimap-flag fade-out)) (logclear! (-> s3-0 flags) (minimap-flag fade-in)) diff --git a/test/decompiler/reference/jak3/engine/ui/progress/progress-draw_REF.gc b/test/decompiler/reference/jak3/engine/ui/progress/progress-draw_REF.gc index f54f7f7382..50f0179c58 100644 --- a/test/decompiler/reference/jak3/engine/ui/progress/progress-draw_REF.gc +++ b/test/decompiler/reference/jak3/engine/ui/progress/progress-draw_REF.gc @@ -158,14 +158,14 @@ (if (< (seconds 0.027) (logand (-> pp clock integral-frame-counter) 15)) (set-font-color (the-as font-color gp-0) - (the-as int (the-as uint #x80ffffff)) + (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) ) (set-font-color (the-as font-color gp-0) - (the-as int (the-as uint #x80606060)) + (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80) @@ -2549,7 +2549,7 @@ (let ((f30-0 (fmax 0.0 (* 2.0 (- 0.5 (-> arg0 menu-transition)))))) (set! (-> arg1 alpha) f30-0) (cond - ((not (bigmap-method-11 *bigmap*)) + ((not (loaded? *bigmap*)) (progress-method-51 arg0 arg1) ) (else @@ -2588,7 +2588,7 @@ (set! (-> a0-2 flags) (font-flags kerning middle large)) ) (cond - ((not (bigmap-method-11 *bigmap*)) + ((not (loaded? *bigmap*)) (progress-method-51 arg0 arg1) ) ((begin @@ -2685,7 +2685,7 @@ (set! (-> arg1 alpha) f30-0) (progress-method-33 arg0 (-> *progress-work* body)) (cond - ((not (bigmap-method-11 *bigmap*)) + ((not (loaded? *bigmap*)) (progress-method-51 arg0 arg1) ) (else @@ -2880,7 +2880,7 @@ (f24-0 (-> *video-params* relative-x-scale)) ) (cond - ((not (bigmap-method-11 *bigmap*)) + ((not (loaded? *bigmap*)) (progress-method-51 arg0 arg1) ) (else @@ -4803,7 +4803,7 @@ (set! sv-24 (the int (-> *game-info* skill))) (set! (-> arg1 alpha) sv-16) (cond - ((not (bigmap-method-11 *bigmap*)) + ((not (loaded? *bigmap*)) (progress-method-51 arg0 arg1) ) (else @@ -5245,3 +5245,7 @@ 0 (none) ) + + + + diff --git a/test/decompiler/reference/jak3/engine/ui/progress/progress_REF.gc b/test/decompiler/reference/jak3/engine/ui/progress/progress_REF.gc index 0ce1b2cf60..c66b1d12bb 100644 --- a/test/decompiler/reference/jak3/engine/ui/progress/progress_REF.gc +++ b/test/decompiler/reference/jak3/engine/ui/progress/progress_REF.gc @@ -1566,13 +1566,7 @@ (progress-method-33 self (-> *progress-work* full-screen)) (cond ((>= (-> self pos-transition) 0.38) - (let ((t9-15 (method-of-object *bigmap* bigmap-method-12))) - 1792 - 1840 - 2304 - 2256 - (t9-15) - ) + (draw! *bigmap* 1792 1840 2304 2256) ) (else (let ((s4-1 (vector<-cspace! (new 'stack-no-clear 'vector) (-> self node-list data 21))) @@ -1582,15 +1576,9 @@ (set! (-> gp-1 quad) (the-as uint128 0)) (let ((s5-2 (new 'stack-no-clear 'vector4w))) (set! (-> s5-2 quad) (the-as uint128 0)) - (when (and (transform-point-qword! gp-1 s4-1) (transform-point-qword! s5-2 s3-1)) - (let ((t9-20 (method-of-object *bigmap* bigmap-method-12))) - (/ (-> s5-2 x) 16) - (/ (-> s5-2 y) 16) - (/ (-> gp-1 x) 16) - (/ (-> gp-1 y) 16) - (t9-20) + (if (and (transform-point-qword! gp-1 s4-1) (transform-point-qword! s5-2 s3-1)) + (draw! *bigmap* (/ (-> s5-2 x) 16) (/ (-> s5-2 y) 16) (/ (-> gp-1 x) 16) (/ (-> gp-1 y) 16)) ) - ) ) ) ) @@ -1661,64 +1649,64 @@ (let ((t9-0 format) (a0-3 #t) (a1-1 "DONE NOTIFY: ~S ~S~%") - (v1-3 (-> block param 1)) + (v1-3 (the-as mc-status-code (-> block param 1))) ) (t9-0 a0-3 a1-1 (cond - ((= v1-3 15) + ((= v1-3 (mc-status-code bad-version)) "bad-version" ) - ((= v1-3 13) + ((= v1-3 (mc-status-code no-save)) "no-save" ) - ((= v1-3 10) + ((= v1-3 (mc-status-code no-last)) "no-last" ) - ((= v1-3 14) + ((= v1-3 (mc-status-code no-space)) "no-space" ) - ((= v1-3 4) + ((= v1-3 (mc-status-code internal-error)) "internal-error" ) - ((= v1-3 8) + ((= v1-3 (mc-status-code no-memory)) "no-memory" ) - ((= v1-3 2) + ((= v1-3 (mc-status-code bad-handle)) "bad-handle" ) - ((zero? v1-3) + ((= v1-3 (mc-status-code busy)) "busy" ) - ((= v1-3 5) + ((= v1-3 (mc-status-code write-error)) "write-error" ) - ((= v1-3 6) + ((= v1-3 (mc-status-code read-error)) "read-error" ) - ((= v1-3 9) + ((= v1-3 (mc-status-code no-card)) "no-card" ) - ((= v1-3 11) + ((= v1-3 (mc-status-code no-format)) "no-format" ) - ((= v1-3 1) + ((= v1-3 (mc-status-code ok)) "ok" ) - ((= v1-3 16) + ((= v1-3 (mc-status-code no-process)) "no-process" ) - ((= v1-3 17) + ((= v1-3 (mc-status-code no-auto-save)) "no-auto-save" ) - ((= v1-3 12) + ((= v1-3 (mc-status-code no-file)) "no-file" ) - ((= v1-3 3) + ((= v1-3 (mc-status-code format-failed)) "format-failed" ) - ((= v1-3 7) + ((= v1-3 (mc-status-code new-game)) "new-game" ) (else @@ -1944,7 +1932,7 @@ ;; definition for method 9 of type menu-slider-option (defmethod respond-progress ((this menu-slider-option) (arg0 progress) (arg1 symbol)) (with-pp - (when (bigmap-method-11 *bigmap*) + (when (loaded? *bigmap*) (let ((s5-0 (&+ (the-as (pointer float) *setting-control*) (-> this setting-offset))) (s3-0 #f) ) @@ -2001,7 +1989,7 @@ ;; definition for method 9 of type menu-stereo-mode-sound-option (defmethod respond-progress ((this menu-stereo-mode-sound-option) (arg0 progress) (arg1 symbol)) - (when (bigmap-method-11 *bigmap*) + (when (loaded? *bigmap*) (let ((a0-2 (-> *setting-control* user-default stereo-mode)) (v1-4 #f) ) @@ -2282,7 +2270,7 @@ (set-next-state arg0 a1-3 0) ) (set! (-> arg0 selected-option) #f) - (when (bigmap-method-11 *bigmap*) + (when (loaded? *bigmap*) (cond ((cpad-pressed? 0 triangle) ) @@ -3096,7 +3084,7 @@ ;; definition for method 9 of type menu-bigmap-option (defmethod respond-progress ((this menu-bigmap-option) (arg0 progress) (arg1 symbol)) - ((method-of-object *bigmap* bigmap-method-13)) + (handle-cpad-input *bigmap*) (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons confirm)) (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons confirm)) 0 @@ -4155,10 +4143,7 @@ process (lambda :behavior process ((arg0 int)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 2.5)) - (suspend) - ) + (suspend-for (seconds 2.5) ) (while (or (not (handle-command-list *gui-control* (gui-channel alert) (the-as gui-connection #f))) (= (status-of-level-and-borrows *level* 'title #f) 'active) @@ -4254,3 +4239,7 @@ ) 0 ) + + + + diff --git a/test/decompiler/reference/jak3/levels/city/blow-tower/blow-tower-obs2_REF.gc b/test/decompiler/reference/jak3/levels/city/blow-tower/blow-tower-obs2_REF.gc index 4747b34745..892403beb0 100644 --- a/test/decompiler/reference/jak3/levels/city/blow-tower/blow-tower-obs2_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/blow-tower/blow-tower-obs2_REF.gc @@ -402,10 +402,7 @@ (defbehavior bt-roboguard-turret-code bt-roboguard () (ja-channel-push! 1 (seconds 0.2)) (ja-no-eval :group! bt-roboguard-idle-shoot0-loop-ja :num! zero) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (let ((gp-1 (lambda ((arg0 bt-roboguard) (arg1 symbol)) @@ -421,10 +418,7 @@ ) (until #f (when (< (fabs (-> self me-to-focus-angle)) f30-0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (while (< (fabs (-> self me-to-focus-angle)) f30-0) (suspend) @@ -446,10 +440,7 @@ ) ) (when (< (fabs (-> self me-to-focus-angle)) f30-0) - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (while (< (fabs (-> self me-to-focus-angle)) f30-0) (suspend) @@ -885,11 +876,7 @@ (defstate hovering (bt-mh-flyer) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (bt-mh-flyer-method-51 self) ) :code (behavior () @@ -920,11 +907,7 @@ (bt-mh-flyer-flight-code) ) :post (behavior () - (let ((t9-1 (-> (find-parent-state) post))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler post) (bt-mh-flyer-method-52 self) ) ) @@ -934,11 +917,7 @@ :virtual #t :trans (behavior () (sound-play "charge-loop" :id (-> self charge-sound) :position (-> self root trans)) - (let ((t9-2 (-> (find-parent-state) trans))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler trans) ) ) @@ -947,20 +926,12 @@ :virtual #t :trans (behavior () (sound-play "charge-loop" :id (-> self charge-sound) :position (-> self root trans)) - (let ((t9-2 (-> (find-parent-state) trans))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler trans) (bt-mh-flyer-method-51 self) ) :code bt-mh-flyer-flight-code :post (behavior () - (let ((t9-1 (-> (find-parent-state) post))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler post) (bt-mh-flyer-method-52 self) ) ) @@ -969,20 +940,12 @@ (defstate fleeing (bt-mh-flyer) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (bt-mh-flyer-method-51 self) ) :code bt-mh-flyer-flight-code :post (behavior () - (let ((t9-1 (-> (find-parent-state) post))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler post) (bt-mh-flyer-method-52 self) ) ) @@ -991,11 +954,7 @@ (defstate firing (bt-mh-flyer) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (bt-mh-flyer-method-51 self) ) :code (behavior () @@ -1009,11 +968,7 @@ (bt-mh-flyer-flight-code) ) :post (behavior () - (let ((t9-1 (-> (find-parent-state) post))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler post) (bt-mh-flyer-method-52 self) ) ) @@ -1023,11 +978,7 @@ :virtual #t :enter (behavior () (sound-play "charge-fire") - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) ) @@ -2327,11 +2278,7 @@ (defstate dormant (bt-grunt) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self root trans quad) (-> self start-pos quad)) (set! (-> self entity extra vis-dist) 819200.0) ) @@ -2369,10 +2316,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.3)) - (suspend) - ) + (suspend-for (seconds 0.3) ) (until #f (suspend) @@ -2381,16 +2325,10 @@ (logior! (-> self skel effect flags) (effect-control-flag ecf1)) ) (do-effect (-> self skel effect) "death-default" 0.0 -1) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.3)) - (suspend) - ) + (suspend-for (seconds 0.3) ) (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.8)) - (suspend) - ) + (suspend-for (seconds 0.8) ) (go-virtual dormant) ) @@ -3260,11 +3198,7 @@ :virtual #t :enter (behavior () (set! (-> self hit-points) 10.0) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) ) diff --git a/test/decompiler/reference/jak3/levels/city/blow-tower/blow-tower-obs_REF.gc b/test/decompiler/reference/jak3/levels/city/blow-tower/blow-tower-obs_REF.gc index 24a180069d..c918a8560b 100644 --- a/test/decompiler/reference/jak3/levels/city/blow-tower/blow-tower-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/blow-tower/blow-tower-obs_REF.gc @@ -1733,10 +1733,7 @@ (part-tracker-spawn part-tracker :to *entity-pool* :group (-> *part-group-id-table* 1460)) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (let ((v1-46 (-> self root root-prim))) (set! (-> v1-46 prim-core collide-as) (collide-spec)) @@ -2126,10 +2123,7 @@ :code (behavior () (until #f (attempt-barrel-spawn) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.3)) - (suspend) - ) + (suspend-for (seconds 0.3) ) ) #f diff --git a/test/decompiler/reference/jak3/levels/city/blow-tower/cty-blow-tower_REF.gc b/test/decompiler/reference/jak3/levels/city/blow-tower/cty-blow-tower_REF.gc index 83b68e8a07..2a9fb21eed 100644 --- a/test/decompiler/reference/jak3/levels/city/blow-tower/cty-blow-tower_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/blow-tower/cty-blow-tower_REF.gc @@ -5070,11 +5070,7 @@ (defstate die (bt-pickup) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (dotimes (gp-0 2) (send-event (handle->process (-> self pickup-barrels gp-0)) 'die) ) diff --git a/test/decompiler/reference/jak3/levels/city/common/mh-squad-member_REF.gc b/test/decompiler/reference/jak3/levels/city/common/mh-squad-member_REF.gc index bf8e13d215..1643ce380a 100644 --- a/test/decompiler/reference/jak3/levels/city/common/mh-squad-member_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/common/mh-squad-member_REF.gc @@ -287,10 +287,6 @@ ) ) ) - (let ((t9-3 (-> (find-parent-state) trans))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler trans) ) ) diff --git a/test/decompiler/reference/jak3/levels/city/ctywide-obs_REF.gc b/test/decompiler/reference/jak3/levels/city/ctywide-obs_REF.gc index 9a2beee39b..35c0fa4466 100644 --- a/test/decompiler/reference/jak3/levels/city/ctywide-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/ctywide-obs_REF.gc @@ -2642,11 +2642,8 @@ ) (send-event *camera* 'teleport-to-transformq s4-0) ) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 3)) - (set! (-> *camera* slave 0 fov) (-> *city-burning-bush-get-on-info* (-> self info index) fov)) - (suspend) - ) + (suspend-for (seconds 3) + (set! (-> *camera* slave 0 fov) (-> *city-burning-bush-get-on-info* (-> self info index) fov)) ) (set! (-> *camera-combiner* trans quad) (-> s5-0 quad)) (let ((a2-15 (-> *camera-combiner* inv-camera-rot)) diff --git a/test/decompiler/reference/jak3/levels/city/ctywide-tasks_REF.gc b/test/decompiler/reference/jak3/levels/city/ctywide-tasks_REF.gc index 1a8823580d..96bcb8690a 100644 --- a/test/decompiler/reference/jak3/levels/city/ctywide-tasks_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/ctywide-tasks_REF.gc @@ -61,10 +61,7 @@ (talker-spawn-func (-> *talker-speech* 26) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self speech-id)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (or (not *target*) (focus-test? *target* dead teleporting)) (suspend) @@ -73,10 +70,7 @@ (talker-spawn-func (-> *talker-speech* 27) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self speech-id)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (or (not *target*) (focus-test? *target* dead teleporting)) (suspend) @@ -98,17 +92,10 @@ ) (wait-for-speech-end (-> self speech-id)) (set! (-> self player-vehicle) (the-as handle #f)) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'complete) - (let ((t9-14 (-> (find-parent-state) code))) - (if t9-14 - ((the-as (function none) t9-14)) - ) - ) + (call-parent-state-handler code) ) ) @@ -118,11 +105,7 @@ :code (behavior ((arg0 resetter-params)) (task-node-close! (game-task-node city-vehicle-training-hover-zone-1) 'event) (sleep-code) - (let ((t9-3 (-> (find-parent-state) code))) - (if t9-3 - ((the-as (function none) t9-3)) - ) - ) + (call-parent-state-handler code) ) ) @@ -131,11 +114,7 @@ :virtual #t :code (behavior () (task-node-close! (game-task-node city-vehicle-training-hover-zone-2) 'event) - (let ((t9-2 (-> (find-parent-state) code))) - (if t9-2 - ((the-as (function none) t9-2)) - ) - ) + (call-parent-state-handler code) ) ) @@ -197,10 +176,7 @@ (talker-spawn-func (-> *talker-speech* 27) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self speech-id)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (set! (-> self speech-id) (talker-spawn-func (-> *talker-speech* 28) *entity-pool* (target-pos 0) (the-as region #f)) @@ -220,10 +196,7 @@ (talker-spawn-func (-> *talker-speech* 29) *entity-pool* (target-pos 0) (the-as region #f)) ) (wait-for-speech-end (-> self speech-id)) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (go-virtual complete) ) @@ -254,10 +227,7 @@ ((-> (method-of-object self wait) trans)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) (until (< 327680.0 (vector-vector-xz-distance (target-pos 0) (new 'static 'vector :x -285696.0 :y 36044.8 :z 5443625.0 :w 1.0)) @@ -266,10 +236,7 @@ ) (set-setting! 'airlock-command '(("hip-door-a-6" close)) 0.0 0) (talker-spawn-func (-> *talker-speech* 162) *entity-pool* (target-pos 0) (the-as region #f)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) (until (handle-command-list *gui-control* (gui-channel voicebox) (the-as gui-connection #f)) (suspend) @@ -370,7 +337,3 @@ (send-event self 'complete) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/city/destroy-grid/cty-destroy-grid_REF.gc b/test/decompiler/reference/jak3/levels/city/destroy-grid/cty-destroy-grid_REF.gc index f33d504cb7..26f857d02d 100644 --- a/test/decompiler/reference/jak3/levels/city/destroy-grid/cty-destroy-grid_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/destroy-grid/cty-destroy-grid_REF.gc @@ -436,11 +436,7 @@ ) ) ) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) :exit #f :trans (behavior () @@ -510,11 +506,7 @@ (put-rider-in-seat gp-0 (-> self seat) self) ) ) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () (let ((gp-0 (new 'stack-no-clear 'vector))) @@ -1735,11 +1727,7 @@ :virtual #t :enter (behavior () (logior! (-> self jinx-flags) (jinx-flag j0)) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) :code (behavior () (until (process-grab? *target* #f) @@ -1774,11 +1762,7 @@ ) :post (behavior () (move-cam-to-jinx self) - (let ((t9-2 (-> (find-parent-state) post))) - (if t9-2 - ((the-as (function none) t9-2)) - ) - ) + (call-parent-state-handler post) ) ) @@ -2035,11 +2019,7 @@ ) (suspend) ) - (let ((t9-4 (-> (find-parent-state) code))) - (if t9-4 - ((the-as (function none) t9-4)) - ) - ) + (call-parent-state-handler code) ) ) @@ -2290,10 +2270,7 @@ (process-entity-status! self (entity-perm-status dead) #t) (sound-play "bomb-set") (set! (-> self sound-id) (sound-play "time-tick-loop")) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) (sound-stop (-> self sound-id)) (sound-play "bomb-explode") @@ -2454,7 +2431,3 @@ (go (method-of-object this idle)) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/city/hijack/cty-hijack_REF.gc b/test/decompiler/reference/jak3/levels/city/hijack/cty-hijack_REF.gc index ce5cf09837..020b6ffc8d 100644 --- a/test/decompiler/reference/jak3/levels/city/hijack/cty-hijack_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/hijack/cty-hijack_REF.gc @@ -1477,11 +1477,7 @@ :virtual #t :enter (behavior () (set! (-> self vehicle-is-visible?) #f) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (task-node-close! (game-task-node city-vehicle-training-hover-zone-1) 'event) (set-setting! 'kg-difficulty #f 1.5 0) (set-setting! 'exclusive-load '((ignore lctyhijk)) 0.0 0) @@ -1602,11 +1598,7 @@ (task-node-close! (game-task-node city-hijack-vehicle-infiltrate) 'event) (go-virtual show-missile-launch) ) - (let ((t9-18 (-> (find-parent-state) trans))) - (if t9-18 - (t9-18) - ) - ) + (call-parent-state-handler trans) ) ) @@ -1811,10 +1803,7 @@ (until (process-grab? *target* #f) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.5)) - (suspend) - ) + (suspend-for (seconds 1.5) ) (send-event (handle->process (-> self hpickup)) 'flight-up) (let ((gp-1 (-> self missiles allocated-length)) @@ -1863,10 +1852,7 @@ ) ) (sound-play "hj-missile" :id (-> self missile-sound)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (dotimes (gp-3 (-> self missiles length)) (send-event (handle->process (-> self missiles gp-3)) 'begin-moving) @@ -1876,16 +1862,10 @@ (send-event (handle->process (-> self missiles gp-4)) 'begin-moving) ) (cty-hijack-manager-method-39 self 1) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (remove-setting! 'entity-name) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (until (process-release? *target*) (suspend) diff --git a/test/decompiler/reference/jak3/levels/city/port/attack/ctyport-attack-bbush_REF.gc b/test/decompiler/reference/jak3/levels/city/port/attack/ctyport-attack-bbush_REF.gc index 61a6508fc2..139a2d0cc0 100644 --- a/test/decompiler/reference/jak3/levels/city/port/attack/ctyport-attack-bbush_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/port/attack/ctyport-attack-bbush_REF.gc @@ -522,19 +522,11 @@ (defstate pickup-nukes (ctyport-attack-manager-bbush) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self countdown-timer) (the-as handle (current-time))) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (if (< (vector-vector-xz-distance (target-pos 0) *port-attack-bbush-fail-sphere*) *port-attack-bbush-fail-radius*) (send-event self 'fail) ) @@ -634,7 +626,3 @@ (sleep-code) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/city/port/attack/ctyport-attack_REF.gc b/test/decompiler/reference/jak3/levels/city/port/attack/ctyport-attack_REF.gc index d50e5f74e8..9e1e28445b 100644 --- a/test/decompiler/reference/jak3/levels/city/port/attack/ctyport-attack_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/port/attack/ctyport-attack_REF.gc @@ -1977,10 +1977,7 @@ process (lambda :behavior process () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.75)) - (suspend) - ) + (suspend-for (seconds 0.75) ) (let ((a0-0 (ppointer->process (-> self parent)))) (if a0-0 @@ -2149,10 +2146,7 @@ :virtual #t :code (behavior () (sound-stop (-> self hum-sound)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (disable *screen-filter*) (deactivate self) @@ -2348,10 +2342,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((gp-1 (new 'stack-no-clear 'event-message-block))) (set! (-> gp-1 from) (process->ppointer self)) diff --git a/test/decompiler/reference/jak3/levels/city/port/attack/h-torpedo_REF.gc b/test/decompiler/reference/jak3/levels/city/port/attack/h-torpedo_REF.gc index 2014b4977b..40c60bd857 100644 --- a/test/decompiler/reference/jak3/levels/city/port/attack/h-torpedo_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/port/attack/h-torpedo_REF.gc @@ -1188,22 +1188,14 @@ ) ) :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self speed) 0.0) (set! (-> self jump-state) (the-as uint 2)) (set! (-> self jump-time) 0.0) (set! (-> *target* pilot jumping?) #f) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) ) :post (behavior () (control-hook-player self) diff --git a/test/decompiler/reference/jak3/levels/city/protect/assault-enemies_REF.gc b/test/decompiler/reference/jak3/levels/city/protect/assault-enemies_REF.gc index 6716b38faa..13ab93db06 100644 --- a/test/decompiler/reference/jak3/levels/city/protect/assault-enemies_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/protect/assault-enemies_REF.gc @@ -309,11 +309,7 @@ (defstate knocked-recover (assault-citizen-norm) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (logclear! (-> self enemy-flags) (enemy-flag vulnerable)) (if (< (vector-vector-xz-distance (-> self root trans) (-> self center-pos)) 16384.0) (go-virtual cower-ground) @@ -484,11 +480,7 @@ (defstate cower-ground (assault-citizen-norm) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (if (enemy-method-109 self) (go-virtual die) ) @@ -917,10 +909,7 @@ (defstate tracking (assault-cleanup) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) (set-time! (-> self offscreen-time)) (until #f @@ -1572,11 +1561,7 @@ ) ) ) - (let ((t9-11 (-> (find-parent-state) enter))) - (if t9-11 - (t9-11) - ) - ) + (call-parent-state-handler enter) ) ) @@ -2176,11 +2161,7 @@ (defstate drop-bombs (assault-bombbot) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self drop-num) (the-as uint 3)) ) ) @@ -2212,11 +2193,7 @@ (set! (-> self next-node) (the-as int (-> self current-node))) (set-time! (-> self state-time)) (set-time! (-> self stop-shoot)) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (remove-attacker *cty-attack-controller* (-> self attacker-info)) diff --git a/test/decompiler/reference/jak3/levels/city/protect/assault-task_REF.gc b/test/decompiler/reference/jak3/levels/city/protect/assault-task_REF.gc index da907c0458..f239a2289f 100644 --- a/test/decompiler/reference/jak3/levels/city/protect/assault-task_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/protect/assault-task_REF.gc @@ -362,10 +362,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (send-event self 'ammo-special 15 29) (sleep-code) @@ -511,10 +508,7 @@ (set! (-> v1-4 notify-proc) (process->handle self)) (send-event (handle->process (-> self h-player-controller)) 'set-params v1-4) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (if *target* (logclear! (-> *target* focus-status) (focus-status teleporting)) @@ -814,11 +808,7 @@ ) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (spawn-enemies *assault-squad* self) ) :code (behavior () @@ -1484,10 +1474,7 @@ process (lambda :behavior process () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (dotimes (gp-1 (-> *assault-squad* spawn-records 1 records length)) (send-event (handle->process (-> *assault-squad* spawn-records 1 records data gp-1 proc)) 'traffic-off-force) @@ -1594,11 +1581,7 @@ (defstate clip-to-nav-mesh (assault-player-controller) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (assault-player-controller-method-36 self) ) ) diff --git a/test/decompiler/reference/jak3/levels/city/protect/cty-protect_REF.gc b/test/decompiler/reference/jak3/levels/city/protect/cty-protect_REF.gc index bf9422c47d..4b870eaa8a 100644 --- a/test/decompiler/reference/jak3/levels/city/protect/cty-protect_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/protect/cty-protect_REF.gc @@ -163,11 +163,7 @@ :virtual #t :enter (behavior () (set-blackout-frames (seconds 10)) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) ) @@ -344,16 +340,10 @@ ((-> (method-of-type task-manager active) trans)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (talker-spawn-func (-> *talker-speech* 337) *entity-pool* (target-pos 0) (the-as region #f)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2.5)) - (suspend) - ) + (suspend-for (seconds 2.5) ) (talker-spawn-func (-> *talker-speech* 336) *entity-pool* (target-pos 0) (the-as region #f)) (send-event self 'complete) @@ -397,10 +387,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (talker-spawn-func (-> *talker-speech* 334) *entity-pool* (target-pos 0) (the-as region #f)) (sleep-code) diff --git a/test/decompiler/reference/jak3/levels/city/protect/flying-turret_REF.gc b/test/decompiler/reference/jak3/levels/city/protect/flying-turret_REF.gc index 720cc55607..addd88e082 100644 --- a/test/decompiler/reference/jak3/levels/city/protect/flying-turret_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/protect/flying-turret_REF.gc @@ -721,11 +721,7 @@ :enter (behavior () (set! (-> self chase-mode) (the-as uint 3)) (flying-turret-method-230 self (the-as uint 0)) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () (when (handle->process (-> self current-enemy)) @@ -1542,7 +1538,3 @@ ) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/city/protect/protect-gunship_REF.gc b/test/decompiler/reference/jak3/levels/city/protect/protect-gunship_REF.gc index 0a40e486f4..060ccd5ac8 100644 --- a/test/decompiler/reference/jak3/levels/city/protect/protect-gunship_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/protect/protect-gunship_REF.gc @@ -1923,10 +1923,7 @@ (set! (-> gp-1 pickup-amount) 2.0) (drop-pickup gp-1 #t *entity-pool* gp-1 0 #t) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) ) ) @@ -4188,7 +4185,3 @@ (call-parent-method this) (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/city/protect/roboguard-city_REF.gc b/test/decompiler/reference/jak3/levels/city/protect/roboguard-city_REF.gc index f6fc601f5e..889f2f2332 100644 --- a/test/decompiler/reference/jak3/levels/city/protect/roboguard-city_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/protect/roboguard-city_REF.gc @@ -461,10 +461,7 @@ (defbehavior roboguard-city-turret-code roboguard-city () (ja-channel-push! 1 (seconds 0.2)) (ja-no-eval :group! roboguard-city-idle-shoot0-loop-ja :num! zero) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (let ((gp-1 (lambda :behavior process @@ -481,10 +478,7 @@ ) (until #f (when (< (fabs (-> self me-to-focus-angle)) f30-0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (while (< (fabs (-> self me-to-focus-angle)) f30-0) (suspend) @@ -506,10 +500,7 @@ ) ) (when (< (fabs (-> self me-to-focus-angle)) f30-0) - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (while (< (fabs (-> self me-to-focus-angle)) f30-0) (suspend) @@ -603,11 +594,7 @@ :virtual #t :trans (behavior () (nav-enemy-method-181 self) - (let ((t9-2 (-> (find-parent-state) trans))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler trans) (let ((gp-0 (get-current-enemy self))) (when gp-0 (let* ((s5-0 self) @@ -1688,11 +1675,7 @@ (defstate knocked-recover (roboguard-city) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () (let ((t9-0 (-> (method-of-type kg-squad-member knocked-recover) trans))) @@ -2502,7 +2485,3 @@ (enemy-falling-post) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/city/sniper/cty-sniper-battery_REF.gc b/test/decompiler/reference/jak3/levels/city/sniper/cty-sniper-battery_REF.gc index f615a608ef..64562584d9 100644 --- a/test/decompiler/reference/jak3/levels/city/sniper/cty-sniper-battery_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/sniper/cty-sniper-battery_REF.gc @@ -345,10 +345,7 @@ (ja-channel-set! 1) (ja :group! cty-sniper-button-pushdown-ja :num! (identity (the float (ja-num-frames 0)))) (ja-post) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (-> self stay-down-time)) - (suspend) - ) + (suspend-for (-> self stay-down-time) ) (send-event (handle->process (-> self lid)) 'up #x3e800000) (ja-no-eval :group! cty-sniper-button-popup-ja :num! (seek! max 0.25) :frame-num 0.0) @@ -1051,7 +1048,3 @@ (set! (-> self during-movement-sound) (new-sound-id)) (go-virtual idle) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/city/sniper/cty-sniper-turret_REF.gc b/test/decompiler/reference/jak3/levels/city/sniper/cty-sniper-turret_REF.gc index e1d5641d2f..9efc4dffa2 100644 --- a/test/decompiler/reference/jak3/levels/city/sniper/cty-sniper-turret_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/sniper/cty-sniper-turret_REF.gc @@ -3049,10 +3049,7 @@ ) :code (behavior () (logior! (-> self flags) (cty-sniper-turret-flag cst3)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.49)) - (suspend) - ) + (suspend-for (seconds 0.49) ) (let ((gp-1 (rand-vu-int-range 3 6))) (dotimes (s5-0 gp-1) @@ -3187,29 +3184,26 @@ (when (and (< f30-0 0.0) (not (-> *setting-control* user-current freeze-screen))) (set-setting! 'mode-name 'cam-no-trans 0.0 0) (suspend) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.5)) - (let ((s3-0 (new 'stack-no-clear 'vector))) - (set! (-> s3-0 quad) (the-as uint128 0)) - (cond - ((< (* (-> s5-2 x) (-> gp-1 z)) (* (-> s5-2 z) (-> gp-1 x))) - (set! (-> s3-0 z) (- (-> s5-2 x))) - (set! (-> s3-0 x) (-> s5-2 z)) - ) - (else - (set! (-> s3-0 z) (-> s5-2 x)) - (set! (-> s3-0 x) (- (-> s5-2 z))) - ) + (suspend-for (seconds 0.5) + (let ((s3-0 (new 'stack-no-clear 'vector))) + (set! (-> s3-0 quad) (the-as uint128 0)) + (cond + ((< (* (-> s5-2 x) (-> gp-1 z)) (* (-> s5-2 z) (-> gp-1 x))) + (set! (-> s3-0 z) (- (-> s5-2 x))) + (set! (-> s3-0 x) (-> s5-2 z)) + ) + (else + (set! (-> s3-0 z) (-> s5-2 x)) + (set! (-> s3-0 x) (- (-> s5-2 z))) ) - (vector+! s3-0 s3-0 (target-pos 0)) - (+! (-> s3-0 y) 20480.0) - (set! (-> *camera* slave 0 trans quad) (-> s3-0 quad)) ) - (vector-! gp-1 (-> self root trans) (target-pos 0)) - (vector-! s5-2 (camera-pos) (target-pos 0)) - (set-setting! 'interp-time 'abs 300.0 0) - (suspend) + (vector+! s3-0 s3-0 (target-pos 0)) + (+! (-> s3-0 y) 20480.0) + (set! (-> *camera* slave 0 trans quad) (-> s3-0 quad)) ) + (vector-! gp-1 (-> self root trans) (target-pos 0)) + (vector-! s5-2 (camera-pos) (target-pos 0)) + (set-setting! 'interp-time 'abs 300.0 0) ) ) (set-setting! 'mode-name 'cam-pov-track 0.0 0) @@ -3247,10 +3241,7 @@ #t ) (logior! (-> *target* focus-status) (focus-status ignore)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.08)) - (suspend) - ) + (suspend-for (seconds 0.08) ) (send-event self 'pov-cam-on) (send-event (handle->process (-> self reticle)) 'on) @@ -3264,10 +3255,7 @@ #x33001 #t ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.08)) - (suspend) - ) + (suspend-for (seconds 0.08) ) (disable *screen-filter*) ) @@ -3309,14 +3297,11 @@ ) ) ) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 1.5)) - (when (focus-test? *target* grabbed) - (logclear! (-> self flags) (cty-sniper-turret-flag cst11)) - (send-event (handle->process (-> self reticle)) 'unlock) - (goto cfg-44) - ) - (suspend) + (suspend-for (seconds 1.5) + (when (focus-test? *target* grabbed) + (logclear! (-> self flags) (cty-sniper-turret-flag cst11)) + (send-event (handle->process (-> self reticle)) 'unlock) + (goto cfg-44) ) ) (if (and (logtest? (-> self flags) (cty-sniper-turret-flag cst7)) (not (cty-sniper-turret-method-39 self))) @@ -3372,10 +3357,7 @@ (suspend) (set-setting! 'interp-time 'abs 600.0 0) (remove-setting! 'mode-name) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (send-event (handle->process (-> self reticle)) 'die) (let ((v1-71 (-> self root root-prim))) @@ -3651,7 +3633,3 @@ (t9-1 this a1-6 a2-1 a3-1 0.0) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/city/traffic/citizen/civilian_REF.gc b/test/decompiler/reference/jak3/levels/city/traffic/citizen/civilian_REF.gc index 0ce09f0db9..1476b5c5ed 100644 --- a/test/decompiler/reference/jak3/levels/city/traffic/citizen/civilian_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/traffic/citizen/civilian_REF.gc @@ -1291,11 +1291,7 @@ (defstate knocked-recover (civilian) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (let ((v1-2 self)) (set! (-> v1-2 enemy-flags) (the-as enemy-flag (logclear (-> v1-2 enemy-flags) (enemy-flag ef38)))) ) @@ -2240,7 +2236,3 @@ ) (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/city/traffic/citizen/metalhead-flitter_REF.gc b/test/decompiler/reference/jak3/levels/city/traffic/citizen/metalhead-flitter_REF.gc index c29147034d..353c86be74 100644 --- a/test/decompiler/reference/jak3/levels/city/traffic/citizen/metalhead-flitter_REF.gc +++ b/test/decompiler/reference/jak3/levels/city/traffic/citizen/metalhead-flitter_REF.gc @@ -363,17 +363,11 @@ ) ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.6)) - (suspend) - ) + (suspend-for (seconds 0.6) ) (+! (-> self root trans y) -8192.0) (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6))) ) (logclear! (-> self draw status) (draw-control-status no-draw)) (go-virtual ambush-jumping) @@ -1105,7 +1099,3 @@ (go-inactive self) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/comb/comb-obs_REF.gc b/test/decompiler/reference/jak3/levels/comb/comb-obs_REF.gc index 2e0b5313e5..70cc503643 100644 --- a/test/decompiler/reference/jak3/levels/comb/comb-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/comb/comb-obs_REF.gc @@ -403,10 +403,7 @@ :unk 0 ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (cleanup-for-death self) ) @@ -764,10 +761,7 @@ :unk 0 ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (cleanup-for-death self) ) @@ -1330,11 +1324,8 @@ (print-text self (text-id text-05f8)) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 6)) - (print-text self (text-id light-jak-shield-how-to)) - (suspend) - ) + (suspend-for (seconds 6) + (print-text self (text-id light-jak-shield-how-to)) ) (send-event *target* 'end-mode 'lightjak) (go-virtual complete) diff --git a/test/decompiler/reference/jak3/levels/comb/comb-sentry_REF.gc b/test/decompiler/reference/jak3/levels/comb/comb-sentry_REF.gc index ed45f69165..31bd020abf 100644 --- a/test/decompiler/reference/jak3/levels/comb/comb-sentry_REF.gc +++ b/test/decompiler/reference/jak3/levels/comb/comb-sentry_REF.gc @@ -792,10 +792,7 @@ :unk 0 ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (cleanup-for-death self) ) @@ -840,7 +837,3 @@ ;; failed to figure out what this is: 0 - - - - diff --git a/test/decompiler/reference/jak3/levels/comb/comb-travel_REF.gc b/test/decompiler/reference/jak3/levels/comb/comb-travel_REF.gc index ae4bca8ff3..2fe002f305 100644 --- a/test/decompiler/reference/jak3/levels/comb/comb-travel_REF.gc +++ b/test/decompiler/reference/jak3/levels/comb/comb-travel_REF.gc @@ -259,11 +259,7 @@ (suspend) ) #f - (let ((t9-29 (-> (find-parent-state) code))) - (if t9-29 - ((the-as (function none) t9-29)) - ) - ) + (call-parent-state-handler code) ) ) @@ -273,11 +269,7 @@ :code (behavior () (remove-setting! 'pilot-exit) (set-setting! 'pilot #f 0.0 0) - (let ((t9-3 (-> (find-parent-state) code))) - (if t9-3 - ((the-as (function none) t9-3)) - ) - ) + (call-parent-state-handler code) ) ) @@ -336,16 +328,9 @@ :code (behavior () (send-event *target* 'end-mode 'pilot) (send-event (handle->process (-> self player-vehicle)) 'sled-disable) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) - ) - (let ((t9-3 (-> (find-parent-state) code))) - (if t9-3 - ((the-as (function none) t9-3)) - ) + (suspend-for (seconds 2) ) + (call-parent-state-handler code) ) ) @@ -382,7 +367,3 @@ 0 (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/comb/h-sled_REF.gc b/test/decompiler/reference/jak3/levels/comb/h-sled_REF.gc index 18d7a3044d..8332b584c8 100644 --- a/test/decompiler/reference/jak3/levels/comb/h-sled_REF.gc +++ b/test/decompiler/reference/jak3/levels/comb/h-sled_REF.gc @@ -2040,11 +2040,7 @@ :virtual #t :enter (behavior () (set! (-> self health-hud) (process->handle (hud-sled-health-spawn self))) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (let ((t9-1 (-> (find-parent-state) exit))) diff --git a/test/decompiler/reference/jak3/levels/common/elec-gate_REF.gc b/test/decompiler/reference/jak3/levels/common/elec-gate_REF.gc index 878d8d6a5d..b8c2d2816e 100644 --- a/test/decompiler/reference/jak3/levels/common/elec-gate_REF.gc +++ b/test/decompiler/reference/jak3/levels/common/elec-gate_REF.gc @@ -720,10 +720,7 @@ (defstate shutdown-camera (elec-gate) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (format 0 "~s~%" (-> self name)) (if (res-lump-struct (-> self entity) 'camera-name structure) @@ -736,10 +733,7 @@ :to *entity-pool* ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (go-virtual shutdown) ) diff --git a/test/decompiler/reference/jak3/levels/common/enemy/darkprec/dp-bipedal_REF.gc b/test/decompiler/reference/jak3/levels/common/enemy/darkprec/dp-bipedal_REF.gc index fe433bc3af..39f91f3ba6 100644 --- a/test/decompiler/reference/jak3/levels/common/enemy/darkprec/dp-bipedal_REF.gc +++ b/test/decompiler/reference/jak3/levels/common/enemy/darkprec/dp-bipedal_REF.gc @@ -2164,7 +2164,7 @@ ) ) :code (behavior () - (local-vars (v1-31 object) (v1-72 symbol)) + (local-vars (v1-31 symbol) (v1-72 symbol)) (cond ((handle->process (-> self ragdoll-proc)) (ja-channel-push! 1 0) diff --git a/test/decompiler/reference/jak3/levels/common/enemy/darkprec/neo-wasp_REF.gc b/test/decompiler/reference/jak3/levels/common/enemy/darkprec/neo-wasp_REF.gc index 0ad27a0cb7..ce67a63ddf 100644 --- a/test/decompiler/reference/jak3/levels/common/enemy/darkprec/neo-wasp_REF.gc +++ b/test/decompiler/reference/jak3/levels/common/enemy/darkprec/neo-wasp_REF.gc @@ -730,10 +730,7 @@ 0 (set! (-> self hit-points) 0.0) (do-effect (-> self skel effect) "death-default" 0.0 -1) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (cleanup-for-death self) @@ -1404,7 +1401,3 @@ ) (go (method-of-object this idle)) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/common/enemy/flitter_REF.gc b/test/decompiler/reference/jak3/levels/common/enemy/flitter_REF.gc index e18aa4ea40..58544338fb 100644 --- a/test/decompiler/reference/jak3/levels/common/enemy/flitter_REF.gc +++ b/test/decompiler/reference/jak3/levels/common/enemy/flitter_REF.gc @@ -739,10 +739,7 @@ (part-tracker-spawn part-tracker :to *entity-pool* :group (-> *part-group-id-table* 1412)) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.6)) - (suspend) - ) + (suspend-for (seconds 0.6) ) (+! (-> self root trans y) -8192.0) (update-focus self) @@ -761,10 +758,7 @@ ) ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6))) ) (logclear! (-> self draw status) (draw-control-status no-draw)) (go-virtual ambush-jumping) @@ -1415,7 +1409,3 @@ (set! (-> this minimap) (add-icon! *minimap* this (the-as uint 108) (the-as int #f) (the-as vector #t) 0)) (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/common/enemy/grunt_REF.gc b/test/decompiler/reference/jak3/levels/common/enemy/grunt_REF.gc index 180b8cd0f4..cb1ec7e359 100644 --- a/test/decompiler/reference/jak3/levels/common/enemy/grunt_REF.gc +++ b/test/decompiler/reference/jak3/levels/common/enemy/grunt_REF.gc @@ -1028,10 +1028,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (let ((v1-6 (-> self root root-prim))) (set! (-> v1-6 prim-core collide-as) (-> self root backup-collide-as)) @@ -1793,7 +1790,7 @@ (defstate knocked-recover (grunt) :virtual #t :code (behavior () - (local-vars (v1-49 object)) + (local-vars (v1-49 symbol)) (ja-channel-push! 1 0) (let ((gp-0 (-> (the-as ragdoll-proc (handle->process (-> self ragdoll-proc))) ragdoll))) (when gp-0 diff --git a/test/decompiler/reference/jak3/levels/common/enemy/hover/robo-hover_REF.gc b/test/decompiler/reference/jak3/levels/common/enemy/hover/robo-hover_REF.gc index c20571ae32..023336b663 100644 --- a/test/decompiler/reference/jak3/levels/common/enemy/hover/robo-hover_REF.gc +++ b/test/decompiler/reference/jak3/levels/common/enemy/hover/robo-hover_REF.gc @@ -1067,11 +1067,7 @@ ) ) :post (behavior () - (let ((t9-1 (-> (find-parent-state) post))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler post) (seek! (-> self gun-blend) 0.0 (* 5.0 (seconds-per-frame))) ) ) @@ -1875,7 +1871,3 @@ 0 (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/common/enemy/kg-grunt_REF.gc b/test/decompiler/reference/jak3/levels/common/enemy/kg-grunt_REF.gc index a691f467df..d4d66db38b 100644 --- a/test/decompiler/reference/jak3/levels/common/enemy/kg-grunt_REF.gc +++ b/test/decompiler/reference/jak3/levels/common/enemy/kg-grunt_REF.gc @@ -908,10 +908,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (let ((v1-6 (-> self root root-prim))) (set! (-> v1-6 prim-core collide-as) (-> self root backup-collide-as)) @@ -2028,7 +2025,3 @@ ) 0 ) - - - - diff --git a/test/decompiler/reference/jak3/levels/common/enemy/mantis_REF.gc b/test/decompiler/reference/jak3/levels/common/enemy/mantis_REF.gc index 18685e4fab..bebca2d00d 100644 --- a/test/decompiler/reference/jak3/levels/common/enemy/mantis_REF.gc +++ b/test/decompiler/reference/jak3/levels/common/enemy/mantis_REF.gc @@ -713,11 +713,7 @@ (defstate active (mantis) :virtual #t :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (if (logtest? (-> self flags) (mantis-flag tracked)) (mantis-method-199 self) ) @@ -807,16 +803,10 @@ ) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.3)) - (suspend) - ) + (suspend-for (seconds 0.3) ) (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6))) ) (logclear! (-> self draw status) (draw-control-status no-draw)) (let* ((v1-45 (-> self nav)) @@ -948,13 +938,10 @@ (suspend) (ja :num! (seek! max 1.2)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (if (logtest? (-> self root status) (collide-status on-ground)) - (goto cfg-35) - ) - (suspend) - ) + (suspend-for (seconds 1) + (if (logtest? (-> self root status) (collide-status on-ground)) + (goto cfg-35) + ) ) (label cfg-35) (go-virtual hostile) @@ -2192,7 +2179,3 @@ (set! (-> this draw light-index) (the-as uint 30)) (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/common/enemy/roboguard_REF.gc b/test/decompiler/reference/jak3/levels/common/enemy/roboguard_REF.gc index 08ba1bfe15..58bb68928c 100644 --- a/test/decompiler/reference/jak3/levels/common/enemy/roboguard_REF.gc +++ b/test/decompiler/reference/jak3/levels/common/enemy/roboguard_REF.gc @@ -560,10 +560,7 @@ (defbehavior roboguard-turret-code roboguard () (ja-channel-push! 1 (seconds 0.2)) (ja-no-eval :group! roboguard-idle-shoot0-loop-ja :num! zero) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (let ((gp-1 (lambda ((arg0 roboguard) (arg1 symbol)) @@ -579,10 +576,7 @@ ) (until #f (when (< (fabs (-> self me-to-focus-angle)) f30-0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (while (< (fabs (-> self me-to-focus-angle)) f30-0) (suspend) @@ -604,10 +598,7 @@ ) ) (when (< (fabs (-> self me-to-focus-angle)) f30-0) - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (while (< (fabs (-> self me-to-focus-angle)) f30-0) (suspend) diff --git a/test/decompiler/reference/jak3/levels/common/enemy/spyder_REF.gc b/test/decompiler/reference/jak3/levels/common/enemy/spyder_REF.gc index 08957b0a4d..84da69deaa 100644 --- a/test/decompiler/reference/jak3/levels/common/enemy/spyder_REF.gc +++ b/test/decompiler/reference/jak3/levels/common/enemy/spyder_REF.gc @@ -1126,13 +1126,10 @@ (set! (-> self fire-info 0 quad) (-> s3-0 quad)) (set! (-> self fire-info 1 quad) (-> s2-1 quad)) ) - (let ((s3-1 (current-time))) - (until (time-elapsed? s3-1 (seconds 0.2)) - (set! f30-0 (seek f30-0 (lerp-scale 0.0 1.0 (the float s4-0) 0.0 8.0) (seconds-per-frame))) - (ja :num! (loop!)) - (ja :chan 1 :num! (chan 0) :frame-interp0 f30-0 :frame-interp1 f30-0) - (suspend) - ) + (suspend-for (seconds 0.2) + (set! f30-0 (seek f30-0 (lerp-scale 0.0 1.0 (the float s4-0) 0.0 8.0) (seconds-per-frame))) + (ja :num! (loop!)) + (ja :chan 1 :num! (chan 0) :frame-interp0 f30-0 :frame-interp1 f30-0) ) (let ((f28-1 (+ 12288.0 f28-0))) (set! (-> gp-0 quad) (-> s5-0 quad)) @@ -1446,7 +1443,3 @@ 0 (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/common/enemy/spydroid-orig_REF.gc b/test/decompiler/reference/jak3/levels/common/enemy/spydroid-orig_REF.gc index e7d37a742d..4259908006 100644 --- a/test/decompiler/reference/jak3/levels/common/enemy/spydroid-orig_REF.gc +++ b/test/decompiler/reference/jak3/levels/common/enemy/spydroid-orig_REF.gc @@ -1165,10 +1165,7 @@ ) (suspend) (ja-channel-set! 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (let ((gp-1 (-> self child))) @@ -1766,7 +1763,3 @@ 0 (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/common/enemy/spydroid_REF.gc b/test/decompiler/reference/jak3/levels/common/enemy/spydroid_REF.gc index 4bde6a4db9..fb3fbd6f91 100644 --- a/test/decompiler/reference/jak3/levels/common/enemy/spydroid_REF.gc +++ b/test/decompiler/reference/jak3/levels/common/enemy/spydroid_REF.gc @@ -1475,21 +1475,13 @@ ) ) :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (spydroid-method-231 self (the-as uint 0)) (set-time! (-> self state-time)) (logior! (-> self flags) (citizen-flag neck-no-auto-look-at)) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (when (or (!= (-> self faction-mode) 0) (logtest? (-> self flags) (citizen-flag in-mission))) (spydroid-method-236 self) (go-virtual hostile) diff --git a/test/decompiler/reference/jak3/levels/desert/artifact-race/artifact-race_REF.gc b/test/decompiler/reference/jak3/levels/desert/artifact-race/artifact-race_REF.gc index c5b8c283e7..4bd4315a27 100644 --- a/test/decompiler/reference/jak3/levels/desert/artifact-race/artifact-race_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/artifact-race/artifact-race_REF.gc @@ -422,7 +422,7 @@ ) ;; definition for symbol *artifact-race-speech-list*, type (inline-array talker-speech-class) -(define *artifact-race-speech-list* (new 'static 'inline-array talker-speech-class 16 +(define *artifact-race-speech-list* (new 'static 'inline-array talker-speech-class 32 (new 'static 'talker-speech-class :name "none") (new 'static 'talker-speech-class :name "dax128" @@ -573,6 +573,166 @@ :on-close #f :camera #f ) + (new 'static 'talker-speech-class + :name "dax177" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x10 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax178" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x11 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax179" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x12 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax180" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x13 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax181" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x14 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax182" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x15 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax183" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x16 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax184" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x17 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax185" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x18 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax186" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x19 + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax187" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x1a + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax188" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x1b + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax189" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x1c + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax190" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x1d + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax191" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x1e + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) + (new 'static 'talker-speech-class + :name "dax192" + :channel (gui-channel daxter) + :flags (talker-flags tf0) + :speech #x1f + :text-duration (seconds 1) + :neg #x1 + :on-close #f + :camera #f + ) ) ) @@ -982,22 +1142,12 @@ 0 (when (= (-> self node-info task) (game-task desert-artifact-race-1)) (send-event *target* 'end-mode 'pilot) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) - ) - (let ((t9-3 (-> (find-parent-state) code))) - (if t9-3 - ((the-as (function none) t9-3)) - ) + (suspend-for (seconds 0.5) ) + (call-parent-state-handler code) ) ) diff --git a/test/decompiler/reference/jak3/levels/desert/chase/desert-chase_REF.gc b/test/decompiler/reference/jak3/levels/desert/chase/desert-chase_REF.gc index dfb06392e7..900bd4ff6b 100644 --- a/test/decompiler/reference/jak3/levels/desert/chase/desert-chase_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/chase/desert-chase_REF.gc @@ -152,15 +152,12 @@ ) :code (behavior () (suspend) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (let ((a1-0 (new 'stack-no-clear 'overlaps-others-params))) - (set! (-> a1-0 options) (overlaps-others-options)) - (set! (-> a1-0 collide-with-filter) (the-as collide-spec -1)) - (set! (-> a1-0 tlist) *touching-list*) - (find-overlapping-shapes (-> self root) a1-0) - ) - (suspend) + (suspend-for (seconds 3) + (let ((a1-0 (new 'stack-no-clear 'overlaps-others-params))) + (set! (-> a1-0 options) (overlaps-others-options)) + (set! (-> a1-0 collide-with-filter) (the-as collide-spec -1)) + (set! (-> a1-0 tlist) *touching-list*) + (find-overlapping-shapes (-> self root) a1-0) ) ) (let ((v1-10 (-> self root root-prim))) @@ -615,16 +612,10 @@ (let ((v1-137 (-> self vehicle 3 handle process))) (set-setting! 'sound-ear v1-137 0.0 (-> v1-137 0 pid)) ) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 1.5)) - (suspend) - ) + (suspend-for (seconds 1.5) ) (desert-chase-ambush-manager-method-35 self 3) - (let ((gp-10 (current-time))) - (until (time-elapsed? gp-10 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (persist-with-delay *setting-control* 'blur-a (seconds 1.5) 'blur-a 'abs 0.5 0) (set! (-> *display* force-sync) (the-as uint 240)) @@ -633,16 +624,10 @@ (set-setting! 'sound-ear v1-157 0.0 (-> v1-157 0 pid)) ) (set-setting! 'entity-name "camera-400" 0.0 0) - (let ((gp-12 (current-time))) - (until (time-elapsed? gp-12 (seconds 1.5)) - (suspend) - ) + (suspend-for (seconds 1.5) ) (desert-chase-ambush-manager-method-35 self 2) - (let ((gp-13 (current-time))) - (until (time-elapsed? gp-13 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (desert-chase-ambush-manager-method-35 self 1) (persist-with-delay *setting-control* 'blur-a (seconds 1.5) 'blur-a 'abs 0.5 0) @@ -652,16 +637,10 @@ (set-setting! 'sound-ear v1-181 0.0 (-> v1-181 0 pid)) ) (set-setting! 'entity-name "camera-402" 0.0 0) - (let ((gp-15 (current-time))) - (until (time-elapsed? gp-15 (seconds 1.5)) - (suspend) - ) + (suspend-for (seconds 1.5) ) (desert-chase-ambush-manager-method-35 self 0) - (let ((gp-16 (current-time))) - (until (time-elapsed? gp-16 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (remove-setting! 'sound-ear) (persist-with-delay *setting-control* 'blur-a (seconds 1.5) 'blur-a 'abs 0.5 0) @@ -701,10 +680,7 @@ (if *target* (logclear! (-> *target* focus-status) (focus-status teleporting)) ) - (let ((gp-19 (current-time))) - (until (time-elapsed? gp-19 (seconds 2.5)) - (suspend) - ) + (suspend-for (seconds 2.5) ) (remove-setting! 'entity-name) (dotimes (gp-20 4) @@ -1742,10 +1718,7 @@ 0 ) ) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((gp-7 (new 'stack-no-clear 'event-message-block))) (set! (-> gp-7 from) (process->ppointer self)) @@ -1769,10 +1742,7 @@ (set! (-> gp-8 i-node) 48) ) ) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((gp-10 (-> self control-array 2))) (when (not (handle->process (-> gp-10 vehicle))) @@ -1782,10 +1752,7 @@ 0 ) ) - (let ((gp-11 (current-time))) - (until (time-elapsed? gp-11 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((gp-12 (new 'stack-no-clear 'event-message-block))) (set! (-> gp-12 from) (process->ppointer self)) @@ -1809,10 +1776,7 @@ (set! (-> gp-13 i-node) 48) ) ) - (let ((gp-14 (current-time))) - (until (time-elapsed? gp-14 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((gp-15 (new 'stack-no-clear 'event-message-block))) (set! (-> gp-15 from) (process->ppointer self)) @@ -1829,15 +1793,9 @@ ) ) ) - (let ((gp-16 (current-time))) - (until (time-elapsed? gp-16 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) - (let ((gp-17 (current-time))) - (until (time-elapsed? gp-17 (seconds 4)) - (suspend) - ) + (suspend-for (seconds 4) ) (send-event (handle->process (-> self h-player-controller)) 'change-mode 'idle) (dotimes (gp-18 4) @@ -1932,10 +1890,7 @@ ) ) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (was-squad-manager-start self) (let ((v1-66 *was-squad-control*)) @@ -2075,10 +2030,7 @@ (if (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) ) - (let ((s5-5 (current-time))) - (until (time-elapsed? s5-5 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (+! gp-6 -1) (if (= gp-6 -1) @@ -2123,15 +2075,8 @@ (defstate complete (desert-chase-chase-manager) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 4)) - (suspend) - ) - ) - (let ((t9-1 (-> (find-parent-state) code))) - (if t9-1 - ((the-as (function none) t9-1)) - ) + (suspend-for (seconds 4) ) + (call-parent-state-handler code) ) ) diff --git a/test/decompiler/reference/jak3/levels/desert/chase/desert-jump_REF.gc b/test/decompiler/reference/jak3/levels/desert/chase/desert-jump_REF.gc index 86862e3ec7..1640d40142 100644 --- a/test/decompiler/reference/jak3/levels/desert/chase/desert-jump_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/chase/desert-jump_REF.gc @@ -1020,10 +1020,7 @@ ) ) ) - (let ((gp-7 (current-time))) - (until (time-elapsed? gp-7 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (send-event self 'complete) ) diff --git a/test/decompiler/reference/jak3/levels/desert/chase/wcar-marauder-b_REF.gc b/test/decompiler/reference/jak3/levels/desert/chase/wcar-marauder-b_REF.gc index 176291683e..4cb9857bae 100644 --- a/test/decompiler/reference/jak3/levels/desert/chase/wcar-marauder-b_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/chase/wcar-marauder-b_REF.gc @@ -381,10 +381,6 @@ (if (and *target* (focus-test? *target* pilot-riding) (not (logtest? (vehicle-flag vf55) (-> self v-flags)))) (turbo-pickup-spawn (-> self root trans)) ) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) ) diff --git a/test/decompiler/reference/jak3/levels/desert/des-bbush-tasks_REF.gc b/test/decompiler/reference/jak3/levels/desert/des-bbush-tasks_REF.gc index 889ceaa2ab..61906b80ad 100644 --- a/test/decompiler/reference/jak3/levels/desert/des-bbush-tasks_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/des-bbush-tasks_REF.gc @@ -653,10 +653,7 @@ (script-eval gp-0) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (while (not (-> *setting-control* user-current speech-control)) (suspend) diff --git a/test/decompiler/reference/jak3/levels/desert/des-burning-bush_REF.gc b/test/decompiler/reference/jak3/levels/desert/des-burning-bush_REF.gc index 2873b6f0fa..d40693c562 100644 --- a/test/decompiler/reference/jak3/levels/desert/des-burning-bush_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/des-burning-bush_REF.gc @@ -972,10 +972,7 @@ ) ) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (set-time! (-> self state-time)) (while (and (nonzero? (get-status *gui-control* (the-as sound-id (-> self message-id)))) @@ -1582,11 +1579,8 @@ (send-event *camera* 'teleport-to-transformq s4-0) ) (set! (-> self update-fov?) #t) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 3)) - (set! (-> *camera* slave 0 fov) (-> *burning-bush-get-on-info* (-> self info index) fov)) - (suspend) - ) + (suspend-for (seconds 3) + (set! (-> *camera* slave 0 fov) (-> *burning-bush-get-on-info* (-> self info index) fov)) ) (set! (-> self update-fov?) #f) (set! (-> *camera-combiner* trans quad) (-> s5-0 quad)) diff --git a/test/decompiler/reference/jak3/levels/desert/des-bush_REF.gc b/test/decompiler/reference/jak3/levels/desert/des-bush_REF.gc index e5b4822ae3..8d990e515c 100644 --- a/test/decompiler/reference/jak3/levels/desert/des-bush_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/des-bush_REF.gc @@ -816,11 +816,7 @@ 0 ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (hud-timer-handler self) ) :code (behavior () @@ -3213,7 +3209,3 @@ #f ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/desert/des-cactus_REF.gc b/test/decompiler/reference/jak3/levels/desert/des-cactus_REF.gc index c5258801d7..f68134502d 100644 --- a/test/decompiler/reference/jak3/levels/desert/des-cactus_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/des-cactus_REF.gc @@ -392,10 +392,7 @@ ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (cleanup-for-death self) ) @@ -707,7 +704,3 @@ (:rotate-y (degrees 0) (degrees 3600)) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/desert/hover/des-beast-2_REF.gc b/test/decompiler/reference/jak3/levels/desert/hover/des-beast-2_REF.gc index 60134e87d2..231241b26a 100644 --- a/test/decompiler/reference/jak3/levels/desert/hover/des-beast-2_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/hover/des-beast-2_REF.gc @@ -305,11 +305,7 @@ (defstate impact (beast-grenade-2) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) @@ -375,11 +371,7 @@ (defstate dissipate (beast-grenade-2) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) @@ -893,20 +885,14 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (until (ja-done? 0) (suspend) ) (logior! (-> self skel effect flags) (effect-control-flag ecf1)) (do-effect (-> self skel effect) "death-default" 0.0 -1) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (go-virtual die) ) diff --git a/test/decompiler/reference/jak3/levels/desert/hover/mh-flyer_REF.gc b/test/decompiler/reference/jak3/levels/desert/hover/mh-flyer_REF.gc index f4d9be8ab0..51e7ba4171 100644 --- a/test/decompiler/reference/jak3/levels/desert/hover/mh-flyer_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/hover/mh-flyer_REF.gc @@ -211,11 +211,7 @@ ) ) :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) @@ -259,11 +255,7 @@ (defstate dissipate (mh-flyer-shot) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) @@ -1334,10 +1326,7 @@ (if (-> self skel effect) (do-effect (-> self skel effect) "death-default" 0.0 -1) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (cleanup-for-death self) ) diff --git a/test/decompiler/reference/jak3/levels/desert/hover/scorpion-gun_REF.gc b/test/decompiler/reference/jak3/levels/desert/hover/scorpion-gun_REF.gc index 10ddf8473c..ee3424e611 100644 --- a/test/decompiler/reference/jak3/levels/desert/hover/scorpion-gun_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/hover/scorpion-gun_REF.gc @@ -2135,16 +2135,10 @@ (send-event self 'use-camera #f) (send-event (handle->process (-> self gun)) 'shutdown) (send-event *camera* 'change-target (handle->process (-> self last-beast))) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (send-event (handle->process (-> self scorp)) 'set-control-hook-player) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 4)) - (suspend) - ) + (suspend-for (seconds 4) ) (until (process-release? *target*) (suspend) @@ -2185,10 +2179,7 @@ (send-event *camera* 'change-target (handle->process (-> self scorp))) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (let* ((v1-7 (-> *game-info* sub-task-list (game-task-node desert-beast-battle-kill-last-beast))) (v1-9 (if (-> v1-7 manager) diff --git a/test/decompiler/reference/jak3/levels/desert/lizard/desert-lizard-task_REF.gc b/test/decompiler/reference/jak3/levels/desert/lizard/desert-lizard-task_REF.gc index 899b613b3d..bc1561a529 100644 --- a/test/decompiler/reference/jak3/levels/desert/lizard/desert-lizard-task_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/lizard/desert-lizard-task_REF.gc @@ -294,13 +294,10 @@ ) ) (when (time-elapsed? (-> self state-time) (seconds 5)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (set! (-> self sound-id) - (add-process *gui-control* self (gui-channel background) (gui-action queue) "hudchime" -99.0 0) - ) - (suspend) - ) + (suspend-for (seconds 1) + (set! (-> self sound-id) + (add-process *gui-control* self (gui-channel background) (gui-action queue) "hudchime" -99.0 0) + ) ) (sound-params-set! *gui-control* (-> self sound-id) #f -1 -1 -1 1.0) (set-action! @@ -634,11 +631,7 @@ :virtual #t :code (behavior () (send-event (handle->process (-> self vehicle-handle)) 'go-die) - (let ((t9-2 (-> (find-parent-state) code))) - (if t9-2 - ((the-as (function none) t9-2)) - ) - ) + (call-parent-state-handler code) ) ) diff --git a/test/decompiler/reference/jak3/levels/desert/race/course-race_REF.gc b/test/decompiler/reference/jak3/levels/desert/race/course-race_REF.gc index 01c0022f35..291ce54bf7 100644 --- a/test/decompiler/reference/jak3/levels/desert/race/course-race_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/race/course-race_REF.gc @@ -284,11 +284,7 @@ :virtual #t :code (behavior () (task-manager-race-method-36 self) - (let ((t9-2 (-> (find-parent-state) code))) - (if t9-2 - ((the-as (function none) t9-2)) - ) - ) + (call-parent-state-handler code) ) ) @@ -604,10 +600,7 @@ ) #f (label cfg-123) - (let ((gp-7 (current-time))) - (until (time-elapsed? gp-7 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event (handle->process (-> self player-vehicle)) 'go-die) (remove-setting! 'entity-name) @@ -676,11 +669,7 @@ (set-setting! 'vehicles 'set (shr t1-0 32) t1-0) ) (set! (-> self start-continue) (the-as continue-point "desertb-race-start")) - (let ((t9-2 (-> (find-parent-state) code))) - (if t9-2 - ((the-as (function none) t9-2)) - ) - ) + (call-parent-state-handler code) ) ) @@ -696,20 +685,13 @@ ) (task-node-close! (game-task-node desert-course-race-win) 'event) (send-event (ppointer->process *race-manager*) 'kill-npc-racers) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (handle->process (-> self scene-player)) (suspend) ) ) - (let ((t9-6 (-> (find-parent-state) code))) - (if t9-6 - ((the-as (function none) t9-6)) - ) - ) + (call-parent-state-handler code) ) ) @@ -887,11 +869,7 @@ (process-spawn hud-wasbbv-goal-time :init hud-init-by-other :name "hud-wasbbv-goal-time" :to self) ) ) - (let ((t9-7 (-> (find-parent-state) code))) - (if t9-7 - ((the-as (function none) t9-7)) - ) - ) + (call-parent-state-handler code) ) ) @@ -1073,10 +1051,6 @@ (process-spawn hud-wasbbv-goal-time :init hud-init-by-other :name "hud-wasbbv-goal-time" :to self) ) ) - (let ((t9-6 (-> (find-parent-state) code))) - (if t9-6 - ((the-as (function none) t9-6)) - ) - ) + (call-parent-state-handler code) ) ) diff --git a/test/decompiler/reference/jak3/levels/desert/race/turtle-training_REF.gc b/test/decompiler/reference/jak3/levels/desert/race/turtle-training_REF.gc index d319ee1ebd..918c05d479 100644 --- a/test/decompiler/reference/jak3/levels/desert/race/turtle-training_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/race/turtle-training_REF.gc @@ -374,16 +374,10 @@ (set! (-> gp-0 map-icon) (the-as uint 12)) (set! (-> self arrow) (process->handle (task-arrow-spawn gp-0 self))) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 4)) - (print-training-text self (text-id text-05e6)) - (suspend) - ) + (suspend-for (seconds 4) + (print-training-text self (text-id text-05e6)) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (set! (-> self time-limit) (seconds 30)) (set-time! (-> self start-time)) @@ -409,10 +403,7 @@ (set! (-> self arrow) (the-as handle #f)) (send-event (handle->process (-> self hud-timer)) 'hide-and-die) (set! (-> self start-time) 0) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (set! (-> self show-message?) #f) (set! (-> self goal-pos quad) (-> self goal-array 1 pos quad)) @@ -444,10 +435,7 @@ (set! (-> self arrow) (the-as handle #f)) (send-event (handle->process (-> self hud-timer)) 'hide-and-die) (set! (-> self start-time) 0) - (let ((gp-7 (current-time))) - (until (time-elapsed? gp-7 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (set! (-> self time-limit) (seconds 28)) (set-time! (-> self start-time)) @@ -467,10 +455,7 @@ (sound-play "special-pickup") (send-event (handle->process (-> self hud-timer)) 'hide-and-die) (set! (-> self start-time) 0) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (set! (-> self show-message?) #f) (set! (-> self goal-pos quad) (-> self goal-array 2 pos quad)) @@ -519,10 +504,7 @@ (set! (-> self arrow) (the-as handle #f)) (send-event (handle->process (-> self hud-timer)) 'hide-and-die) (set! (-> self start-time) 0) - (let ((gp-12 (current-time))) - (until (time-elapsed? gp-12 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (set! (-> self goal-pos quad) (-> self goal-array 3 pos quad)) (let ((gp-13 (new 'stack-no-clear 'task-arrow-params))) @@ -552,10 +534,7 @@ (set! (-> self arrow) (the-as handle #f)) (send-event (handle->process (-> self hud-timer)) 'hide-and-die) (set! (-> self start-time) 0) - (let ((gp-15 (current-time))) - (until (time-elapsed? gp-15 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (set! (-> self goal-pos quad) (-> self goal-array 4 pos quad)) (let ((gp-16 (new 'stack-no-clear 'task-arrow-params))) @@ -589,10 +568,7 @@ (set! (-> self arrow) (the-as handle #f)) (send-event (handle->process (-> self hud-timer)) 'hide-and-die) (set! (-> self start-time) 0) - (let ((gp-18 (current-time))) - (until (time-elapsed? gp-18 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (set! (-> self goal-pos quad) (-> self goal-array 5 pos quad)) (let ((gp-19 (new 'stack-no-clear 'task-arrow-params))) @@ -634,7 +610,3 @@ ) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/desert/rescue/desert-rescue_REF.gc b/test/decompiler/reference/jak3/levels/desert/rescue/desert-rescue_REF.gc index 51374c488f..3606006b4c 100644 --- a/test/decompiler/reference/jak3/levels/desert/rescue/desert-rescue_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/rescue/desert-rescue_REF.gc @@ -1992,11 +1992,7 @@ :virtual #t :event task-manager-event-handler :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self entity) #f) (dotimes (v1-2 (-> self passenger-pos length)) (if (-> self passenger-pos v1-2 is-final?) @@ -2786,10 +2782,7 @@ ((-> (method-of-type task-manager active) trans)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'fail) (sleep-code) diff --git a/test/decompiler/reference/jak3/levels/desert/wvehicle/w-parking-spot_REF.gc b/test/decompiler/reference/jak3/levels/desert/wvehicle/w-parking-spot_REF.gc index 89afaa23c2..e1c3c9b8d8 100644 --- a/test/decompiler/reference/jak3/levels/desert/wvehicle/w-parking-spot_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/wvehicle/w-parking-spot_REF.gc @@ -272,10 +272,7 @@ (w-parking-spot-method-23 self) ) (until #f - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.25)) - (suspend) - ) + (suspend-for (seconds 0.25) ) (w-parking-spot-method-21 self) (when (-> self should-spawn?) diff --git a/test/decompiler/reference/jak3/levels/desert/wvehicle/was-squad-control_REF.gc b/test/decompiler/reference/jak3/levels/desert/wvehicle/was-squad-control_REF.gc index 2672862cb4..afb95280c4 100644 --- a/test/decompiler/reference/jak3/levels/desert/wvehicle/was-squad-control_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/wvehicle/was-squad-control_REF.gc @@ -210,7 +210,7 @@ ) ) (when s4-0 - (let ((s5-1 (new 'stack-no-clear 'inline-array 'matrix 2))) + (let ((s5-1 (new 'stack-no-clear 'inline-array 'matrix 4))) (let* ((s3-0 (-> s5-1 0)) (a2-0 (camera-matrix)) (v1-4 (-> a2-0 rvec quad)) diff --git a/test/decompiler/reference/jak3/levels/desert/wvehicle/wcar-marauder_REF.gc b/test/decompiler/reference/jak3/levels/desert/wvehicle/wcar-marauder_REF.gc index f4e45728c4..558a8223fe 100644 --- a/test/decompiler/reference/jak3/levels/desert/wvehicle/wcar-marauder_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/wvehicle/wcar-marauder_REF.gc @@ -523,10 +523,6 @@ (if (and *target* (focus-test? *target* pilot-riding)) (turbo-pickup-spawn (-> self root trans)) ) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) ) diff --git a/test/decompiler/reference/jak3/levels/desert/wvehicle/wvehicle-states_REF.gc b/test/decompiler/reference/jak3/levels/desert/wvehicle/wvehicle-states_REF.gc index c66c64151b..4c189d7090 100644 --- a/test/decompiler/reference/jak3/levels/desert/wvehicle/wvehicle-states_REF.gc +++ b/test/decompiler/reference/jak3/levels/desert/wvehicle/wvehicle-states_REF.gc @@ -229,11 +229,7 @@ (defstate waiting (wvehicle) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (when (-> self minimap) @@ -419,7 +415,3 @@ (cleanup-for-death self) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/factory/car/hvehicle_REF.gc b/test/decompiler/reference/jak3/levels/factory/car/hvehicle_REF.gc index 0c292e9fce..6f3453383a 100644 --- a/test/decompiler/reference/jak3/levels/factory/car/hvehicle_REF.gc +++ b/test/decompiler/reference/jak3/levels/factory/car/hvehicle_REF.gc @@ -1257,11 +1257,7 @@ :enter (behavior () (rlet ((vf0 :class vf)) (init-vf0-vector) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (let ((gp-0 (-> self child))) (while gp-0 (send-event (ppointer->process gp-0) 'traffic-off) diff --git a/test/decompiler/reference/jak3/levels/factory/car/wcar-faccar_REF.gc b/test/decompiler/reference/jak3/levels/factory/car/wcar-faccar_REF.gc index 902b4f5696..0187ad5aab 100644 --- a/test/decompiler/reference/jak3/levels/factory/car/wcar-faccar_REF.gc +++ b/test/decompiler/reference/jak3/levels/factory/car/wcar-faccar_REF.gc @@ -173,10 +173,8 @@ process (lambda :behavior process ((arg0 handle)) - (let ((s5-0 (current-time)) - (s4-0 (current-time)) - ) - (until (time-elapsed? s4-0 (seconds 0.65)) + (let ((s5-0 (current-time))) + (suspend-for (seconds 0.65) (when (time-elapsed? s5-0 (seconds 0.06)) (set! s5-0 (current-time)) (let ((s3-0 (handle->process arg0))) @@ -200,7 +198,6 @@ ) ) ) - (suspend) ) ) #f @@ -440,7 +437,3 @@ ) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/factory/fac-gunturret_REF.gc b/test/decompiler/reference/jak3/levels/factory/fac-gunturret_REF.gc index 5d6f6f9d80..f2dc03c255 100644 --- a/test/decompiler/reference/jak3/levels/factory/fac-gunturret_REF.gc +++ b/test/decompiler/reference/jak3/levels/factory/fac-gunturret_REF.gc @@ -704,28 +704,25 @@ (sound-group) (-> self root trans) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.75)) - (let ((s5-2 (new 'stack-no-clear 'vector))) - (set! (-> s5-2 quad) (-> self aim-pos quad)) - (track-target self #t) - (vector-! s5-2 (-> self aim-pos) s5-2) - (when (time-elapsed? (-> self snd-cmd-time) (seconds 0.12)) - 0.0 - (vector-length s5-2) - (sound-play-by-name - (static-sound-name "smallturret-rot") - (-> self rotate-sound) - 1024 - (the int (* 1524.0 (* 0.5 (doppler-pitch-shift (-> self root trans) (-> self root transv))))) - 0 - (sound-group) - (-> self root trans) - ) - (set-time! (-> self snd-cmd-time)) + (suspend-for (seconds 0.75) + (let ((s5-2 (new 'stack-no-clear 'vector))) + (set! (-> s5-2 quad) (-> self aim-pos quad)) + (track-target self #t) + (vector-! s5-2 (-> self aim-pos) s5-2) + (when (time-elapsed? (-> self snd-cmd-time) (seconds 0.12)) + 0.0 + (vector-length s5-2) + (sound-play-by-name + (static-sound-name "smallturret-rot") + (-> self rotate-sound) + 1024 + (the int (* 1524.0 (* 0.5 (doppler-pitch-shift (-> self root trans) (-> self root transv))))) + 0 + (sound-group) + (-> self root trans) ) + (set-time! (-> self snd-cmd-time)) ) - (suspend) ) ) (when (-> self rotate-sound-playing) @@ -912,17 +909,11 @@ (let ((gp-1 (new 'stack-no-clear 'vector))) (set! (-> gp-1 quad) (-> self root trans quad)) (+! (-> gp-1 y) 12288.0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 2)) - (spawn (-> self part) gp-1) - (suspend) - ) + (suspend-for (seconds 2) + (spawn (-> self part) gp-1) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (while (-> self child) @@ -1151,7 +1142,3 @@ ;; failed to figure out what this is: 0 - - - - diff --git a/test/decompiler/reference/jak3/levels/factory/fac-robotank-turret_REF.gc b/test/decompiler/reference/jak3/levels/factory/fac-robotank-turret_REF.gc index 0454e12305..51c62ed625 100644 --- a/test/decompiler/reference/jak3/levels/factory/fac-robotank-turret_REF.gc +++ b/test/decompiler/reference/jak3/levels/factory/fac-robotank-turret_REF.gc @@ -930,10 +930,7 @@ ) (logior! (-> self flags) (fac-robotank-turret-flag frt3)) (set! (-> self firing-sight-pos quad) (-> self sight-pos quad)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (let ((gp-2 (max 2 (min 3 (rand-vu-int-range 0 3))))) 0 @@ -960,11 +957,8 @@ ) ) ) - (let ((f30-0 (rand-vu-float-range 0.05 0.43)) - (s4-2 (current-time)) - ) - (until (time-elapsed? s4-2 (the int (* 300.0 f30-0))) - (suspend) + (let ((f30-0 (rand-vu-float-range 0.05 0.43))) + (suspend-for (the int (* 300.0 f30-0)) ) ) ) @@ -982,10 +976,8 @@ 2.11 ) ) - (gp-3 (current-time)) ) - (until (time-elapsed? gp-3 (the int (* 300.0 f30-1))) - (suspend) + (suspend-for (the int (* 300.0 f30-1)) ) ) ) @@ -1004,10 +996,7 @@ ) 0 (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (-> self child) (suspend) @@ -1126,7 +1115,3 @@ (set! (-> self turn-sound-id) (new-sound-id)) (go-virtual ready) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/factory/fac-robotank_REF.gc b/test/decompiler/reference/jak3/levels/factory/fac-robotank_REF.gc index 33963db970..391ebd0e4e 100644 --- a/test/decompiler/reference/jak3/levels/factory/fac-robotank_REF.gc +++ b/test/decompiler/reference/jak3/levels/factory/fac-robotank_REF.gc @@ -604,10 +604,7 @@ ) :code (behavior () (logclear! (-> self flags) (robotank-flag r2)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (logior! (-> self flags) (robotank-flag r2)) (sleep-code) @@ -776,10 +773,7 @@ ) 0 (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (while (-> self child) (suspend) @@ -1016,7 +1010,3 @@ (the-as fac-robotank gp-0) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/factory/fac-tower_REF.gc b/test/decompiler/reference/jak3/levels/factory/fac-tower_REF.gc index e6b4b39c56..f77749884f 100644 --- a/test/decompiler/reference/jak3/levels/factory/fac-tower_REF.gc +++ b/test/decompiler/reference/jak3/levels/factory/fac-tower_REF.gc @@ -273,10 +273,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) ) :post ja-post @@ -1087,7 +1084,3 @@ ) :post transform-post ) - - - - diff --git a/test/decompiler/reference/jak3/levels/factory/factory-manager_REF.gc b/test/decompiler/reference/jak3/levels/factory/factory-manager_REF.gc index 0da4978651..aa143346e8 100644 --- a/test/decompiler/reference/jak3/levels/factory/factory-manager_REF.gc +++ b/test/decompiler/reference/jak3/levels/factory/factory-manager_REF.gc @@ -1929,11 +1929,7 @@ :virtual #t :enter (behavior () (send-event (handle->process (-> self hud-damage)) 'hide-and-die) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) ) diff --git a/test/decompiler/reference/jak3/levels/factory/factoryc-obs2_REF.gc b/test/decompiler/reference/jak3/levels/factory/factoryc-obs2_REF.gc index fcb4cc4768..a414a62b06 100644 --- a/test/decompiler/reference/jak3/levels/factory/factoryc-obs2_REF.gc +++ b/test/decompiler/reference/jak3/levels/factory/factoryc-obs2_REF.gc @@ -952,15 +952,12 @@ (process-entity-status! self (entity-perm-status subtask-complete) #t) (cond ((not arg0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.3)) - (let* ((f28-0 (lerp-clamp 0.0 3640.889 (* 0.011111111 (the float (- (current-time) (-> self state-time)))))) - (f30-0 (cos f28-0)) - (f0-2 (sin f28-0)) - ) - (quaternion-set! (-> self lever-jmod rotation) f0-2 0.0 0.0 f30-0) - ) - (suspend) + (suspend-for (seconds 0.3) + (let* ((f28-0 (lerp-clamp 0.0 3640.889 (* 0.011111111 (the float (- (current-time) (-> self state-time)))))) + (f30-0 (cos f28-0)) + (f0-2 (sin f28-0)) + ) + (quaternion-set! (-> self lever-jmod rotation) f0-2 0.0 0.0 f30-0) ) ) (let ((gp-2 (res-lump-struct (-> self entity) 'cutaway-camera structure))) @@ -969,11 +966,8 @@ (suspend) ) (set-setting! 'entity-name gp-2 0.0 0) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 3)) - '() - (suspend) - ) + (suspend-for (seconds 3) + '() ) (remove-setting! 'entity-name) (while (not (process-release? *target*)) @@ -1168,18 +1162,10 @@ :virtual #t :event plat-event :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) ) :code (behavior () - (let ((t9-1 (-> (find-parent-state) code))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler code) ) ) @@ -1237,14 +1223,11 @@ :trans plat-trans :code (behavior () (let ((f30-0 (-> self dead-set-time))) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (set! (-> self path-pos) - (lerp-clamp (get-norm! (-> self sync) 0) f30-0 (* 0.0011111111 (the float (- (current-time) gp-0)))) - ) - (get-point-at-percent-along-path! (-> self path) (-> self basetrans) (-> self path-pos) 'interp) - (suspend) - ) + (suspend-for (seconds 3) + (set! (-> self path-pos) + (lerp-clamp (get-norm! (-> self sync) 0) f30-0 (* 0.0011111111 (the float (- (current-time) time)))) + ) + (get-point-at-percent-along-path! (-> self path) (-> self basetrans) (-> self path-pos) 'interp) ) (suspend) (set! (-> self path-pos) f30-0) @@ -1345,18 +1328,10 @@ ) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) ) :code (behavior () - (let ((t9-1 (-> (find-parent-state) code))) - (if t9-1 - ((the-as (function none) t9-1)) - ) - ) + (call-parent-state-handler code) ) ) @@ -2147,7 +2122,3 @@ (go perish-immediately) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/factory/factoryc-obs_REF.gc b/test/decompiler/reference/jak3/levels/factory/factoryc-obs_REF.gc index 1bd1f9d7f2..0bccf52e9b 100644 --- a/test/decompiler/reference/jak3/levels/factory/factoryc-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/factory/factoryc-obs_REF.gc @@ -1204,78 +1204,73 @@ (defstate flickering (factory-elec-gate) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (let ((s5-0 (the-as int (rand-uint31-gen *random-generator*)))) - (let ((s4-0 0) - (s3-0 3) - ) - (while (>= s3-0 s4-0) - (cond - ((logtest? s5-0 1) - (when (not (-> self beams-on s4-0)) - (let ((v1-8 (-> self beams s4-0)) - (a0-1 1) - ) - (let ((a1-1 (!= a0-1 (-> v1-8 state mode)))) - (case a0-1 - ((3) - (if a1-1 - (set! (-> v1-8 state counter) 0.0) - ) - ) - ((1) - (set! (-> v1-8 state start-color) (-> v1-8 spec start-color)) - (set! (-> v1-8 state end-color) (-> v1-8 spec end-color)) - ) - ) + (suspend-for (seconds 3) + (let ((s5-0 (the-as int (rand-uint31-gen *random-generator*)))) + (let ((s4-0 0) + (s3-0 3) + ) + (while (>= s3-0 s4-0) + (cond + ((logtest? s5-0 1) + (when (not (-> self beams-on s4-0)) + (let ((v1-8 (-> self beams s4-0)) + (a0-1 1) + ) + (let ((a1-1 (!= a0-1 (-> v1-8 state mode)))) + (case a0-1 + ((3) + (if a1-1 + (set! (-> v1-8 state counter) 0.0) + ) + ) + ((1) + (set! (-> v1-8 state start-color) (-> v1-8 spec start-color)) + (set! (-> v1-8 state end-color) (-> v1-8 spec end-color)) + ) ) - (set! (-> v1-8 state mode) (the-as uint a0-1)) ) - (set! (-> self beams-on s4-0) #t) - (set-factoryc-light! 1.0 1) + (set! (-> v1-8 state mode) (the-as uint a0-1)) ) + (set! (-> self beams-on s4-0) #t) + (set-factoryc-light! 1.0 1) ) - (else - (when (-> self beams-on s4-0) - (let ((v1-17 (-> self beams s4-0)) - (a0-5 3) - ) - (let ((a1-12 (!= a0-5 (-> v1-17 state mode)))) - (case a0-5 - ((3) - (if a1-12 - (set! (-> v1-17 state counter) 0.0) - ) - ) - ((1) - (set! (-> v1-17 state start-color) (-> v1-17 spec start-color)) - (set! (-> v1-17 state end-color) (-> v1-17 spec end-color)) - ) - ) + ) + (else + (when (-> self beams-on s4-0) + (let ((v1-17 (-> self beams s4-0)) + (a0-5 3) + ) + (let ((a1-12 (!= a0-5 (-> v1-17 state mode)))) + (case a0-5 + ((3) + (if a1-12 + (set! (-> v1-17 state counter) 0.0) + ) + ) + ((1) + (set! (-> v1-17 state start-color) (-> v1-17 spec start-color)) + (set! (-> v1-17 state end-color) (-> v1-17 spec end-color)) + ) ) - (set! (-> v1-17 state mode) (the-as uint a0-5)) ) - (set! (-> self beams-on s4-0) #f) - (set-factoryc-light! 0.0 1) + (set! (-> v1-17 state mode) (the-as uint a0-5)) ) + (set! (-> self beams-on s4-0) #f) + (set-factoryc-light! 0.0 1) ) ) - (set! s5-0 (/ s5-0 2)) - (+! s4-0 1) ) + (set! s5-0 (/ s5-0 2)) + (+! s4-0 1) ) - (let ((s4-1 (current-time))) - (until (time-elapsed? s4-1 (seconds 0.1)) - (if (logand s5-0 1) - (sound-play "laser-loop" :id (-> self bzzt-sound) :position (-> self entity trans)) - ) - (suspend) + ) + (suspend-for (seconds 0.1) + (if (logand s5-0 1) + (sound-play "laser-loop" :id (-> self bzzt-sound) :position (-> self entity trans)) ) - ) ) - (suspend) ) + (empty-form) ) (process-entity-status! self (entity-perm-status subtask-complete) #t) (process-entity-status! self (entity-perm-status dead) #t) @@ -1363,7 +1358,3 @@ (go (method-of-object this flickering)) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/factory/lfacrm2-mood_REF.gc b/test/decompiler/reference/jak3/levels/factory/lfacrm2-mood_REF.gc index 9f30d7c421..430cc0ad48 100644 --- a/test/decompiler/reference/jak3/levels/factory/lfacrm2-mood_REF.gc +++ b/test/decompiler/reference/jak3/levels/factory/lfacrm2-mood_REF.gc @@ -32,11 +32,7 @@ :virtual #t :enter (behavior () (set! (-> self mysound) (sound-play "elevator-a")) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (sound-stop (-> self mysound)) @@ -67,11 +63,7 @@ (-> gp-0 id) ) ) - (let ((t9-5 (-> (find-parent-state) trans))) - (if t9-5 - (t9-5) - ) - ) + (call-parent-state-handler trans) ) :code (behavior () (when (not (nonzero? (res-lump-value (-> self entity) 'start-gate-up uint128 :time -1000000000.0))) @@ -81,11 +73,7 @@ (ja :num! (seek! max 1.333)) ) ) - (let ((t9-5 (-> (find-parent-state) code))) - (if t9-5 - ((the-as (function none) t9-5)) - ) - ) + (call-parent-state-handler code) ) ) @@ -114,11 +102,8 @@ (defstate dormant (fac-elevator-a) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.5)) - '() - (suspend) - ) + (suspend-for (seconds 1.5) + '() ) (ja-no-eval :group! fac-elevator-a-gate_down-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) @@ -238,7 +223,3 @@ 0 (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/factory/warf-projectile_REF.gc b/test/decompiler/reference/jak3/levels/factory/warf-projectile_REF.gc index 5d9f546f5a..9109d5d16d 100644 --- a/test/decompiler/reference/jak3/levels/factory/warf-projectile_REF.gc +++ b/test/decompiler/reference/jak3/levels/factory/warf-projectile_REF.gc @@ -720,11 +720,7 @@ ) (process-spawn warf-explosion-sphere gp-0 :name "warf-explosion-sphere" :to self) ) - (let ((t9-8 (-> (find-parent-state) enter))) - (if t9-8 - (t9-8) - ) - ) + (call-parent-state-handler enter) ) :code (behavior () (while (< (-> self hit-pos w) 245760.0) @@ -1651,7 +1647,3 @@ 0 (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/forest/forest-ring-chase_REF.gc b/test/decompiler/reference/jak3/levels/forest/forest-ring-chase_REF.gc index 43f4261bbd..12457ce49a 100644 --- a/test/decompiler/reference/jak3/levels/forest/forest-ring-chase_REF.gc +++ b/test/decompiler/reference/jak3/levels/forest/forest-ring-chase_REF.gc @@ -561,10 +561,7 @@ (if (nonzero? (-> self sound-id)) (sound-stop (-> self sound-id)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 8)) - (suspend) - ) + (suspend-for (seconds 8) ) ) ) @@ -1137,13 +1134,10 @@ (part-tracker-spawn part-tracker :to self :group (-> *part-group-id-table* 584) :duration (seconds 1)) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (if (nonzero? (-> self sound-id)) - (sound-play "statue-expl-bu" :id (-> self sound-id)) - ) - (suspend) - ) + (suspend-for (seconds 1) + (if (nonzero? (-> self sound-id)) + (sound-play "statue-expl-bu" :id (-> self sound-id)) + ) ) (if (nonzero? (-> self sound-id)) (sound-stop (-> self sound-id)) @@ -1179,10 +1173,7 @@ (transform-post) (sound-play "statue-explode") (for-statue-method-28 self) - (let ((gp-6 (current-time))) - (until (time-elapsed? gp-6 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (cleanup-for-death self) (let ((a1-15 (new 'stack-no-clear 'event-message-block))) @@ -2520,11 +2511,8 @@ ) (suspend) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 3)) - (format *stdebug* "task-manager-forest-ring-chase: done!~%") - (suspend) - ) + (suspend-for (seconds 3) + (format *stdebug* "task-manager-forest-ring-chase: done!~%") ) (while (-> self use-camera?) (suspend) @@ -2696,7 +2684,3 @@ ) (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/forest/forest-tasks_REF.gc b/test/decompiler/reference/jak3/levels/forest/forest-tasks_REF.gc index fdef21c44c..e05b12a804 100644 --- a/test/decompiler/reference/jak3/levels/forest/forest-tasks_REF.gc +++ b/test/decompiler/reference/jak3/levels/forest/forest-tasks_REF.gc @@ -88,10 +88,7 @@ :virtual #t :code (behavior () (local-vars (a1-12 event-message-block) (gp-3 symbol)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (until (and (-> self manager-entity) (= (-> *game-info* counter) 0.0)) (suspend) @@ -168,10 +165,7 @@ (until (process-grab? *target* #f) (suspend) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (let ((a1-14 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-14 from) (process->ppointer self)) @@ -328,10 +322,7 @@ (suspend) (set! (-> self manager-entity) (entity-by-name "for-machine-manager-1")) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((gp-1 (-> self entity extra perm))) (logior! (-> gp-1 status) (entity-perm-status bit-5)) @@ -350,10 +341,7 @@ ) (set! (-> gp-1 user-object 0) (+ (the-as int (-> gp-1 user-object 0)) 1)) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (set! sv-16 (new 'static 'res-tag)) (let ((v1-33 (res-lump-data (-> self manager-entity) 'actor-groups pointer :tag-ptr (& sv-16)))) diff --git a/test/decompiler/reference/jak3/levels/gungame/gun-dummy_REF.gc b/test/decompiler/reference/jak3/levels/gungame/gun-dummy_REF.gc index 3b6414f06c..75821f27c4 100644 --- a/test/decompiler/reference/jak3/levels/gungame/gun-dummy_REF.gc +++ b/test/decompiler/reference/jak3/levels/gungame/gun-dummy_REF.gc @@ -1195,11 +1195,7 @@ ((time-elapsed? (-> self arm-start-time) (seconds 2)) ) ) - (let ((t9-5 (-> (find-parent-state) trans))) - (if t9-5 - (t9-5) - ) - ) + (call-parent-state-handler trans) ) ) @@ -2310,7 +2306,3 @@ (defmethod gun-dummy-method-35 ((this gun-dummy-cit-clank)) 1 ) - - - - diff --git a/test/decompiler/reference/jak3/levels/gungame/gungame-manager_REF.gc b/test/decompiler/reference/jak3/levels/gungame/gungame-manager_REF.gc index bcac763312..6618eb9aaf 100644 --- a/test/decompiler/reference/jak3/levels/gungame/gungame-manager_REF.gc +++ b/test/decompiler/reference/jak3/levels/gungame/gungame-manager_REF.gc @@ -1822,11 +1822,7 @@ '() ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (if (search-process-tree *active-pool* (lambda ((arg0 process)) (type? arg0 gungame-manager))) (return 0) ) @@ -1961,22 +1957,12 @@ ) (set-setting! 'features 'clear (shr t1-0 32) t1-0) ) - (cond - ((>= 1 (-> self course-list length)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) - ) - ) - (else - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) + (if (>= 1 (-> self course-list length)) + (suspend-for (seconds 1) + ) + (suspend-for (seconds 0.5) ) ) - ) (let ((gp-2 (get-process *default-dead-pool* (-> self activated-course etype) #x4000 1))) (when gp-2 (let ((t9-3 (method-of-type process activate))) diff --git a/test/decompiler/reference/jak3/levels/gungame/gungame-obs_REF.gc b/test/decompiler/reference/jak3/levels/gungame/gungame-obs_REF.gc index 0a1e9f2952..db629001b8 100644 --- a/test/decompiler/reference/jak3/levels/gungame/gungame-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/gungame/gungame-obs_REF.gc @@ -153,11 +153,8 @@ :event gungame-door-handler :code (behavior () (sound-play "gungame-door") - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.2)) - (suspend) - (suspend) - ) + (suspend-for (seconds 0.2) + (suspend) ) (ja-no-eval :group! fort-entry-gate-idle-ja :num! (seek!) :frame-num 0.0) (until (ja-done? 0) @@ -335,7 +332,3 @@ (transform-post) (go (method-of-object this idle)) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/intro/intro-scenes_REF.gc b/test/decompiler/reference/jak3/levels/intro/intro-scenes_REF.gc index 17eae2e73c..c9cc2dbe6a 100644 --- a/test/decompiler/reference/jak3/levels/intro/intro-scenes_REF.gc +++ b/test/decompiler/reference/jak3/levels/intro/intro-scenes_REF.gc @@ -234,9 +234,8 @@ ) (set! (-> gp-0 scale-x) 1.0) (set! (-> gp-0 scale-y) 1.0) - (when (and s5-0 (-> gp-0 tid)) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 (seconds 3)) + (if (and s5-0 (-> gp-0 tid)) + (suspend-for (seconds 3) (let ((f0-2 1.0)) (cond ((< f30-0 1.0) @@ -256,10 +255,8 @@ (if (not (paused?)) (+! f30-0 (seconds-per-frame)) ) - (suspend) ) ) - ) ) (none) ) @@ -310,9 +307,8 @@ (set-vector! (-> gp-0 pos) 256 188 #xffffff 0) (set! (-> gp-0 tid) (the-as texture-id (get-texture JakIII inttitle-minimap))) (set! (-> s5-0 tid) (the-as texture-id #f)) - (when (and s4-0 (-> gp-0 tid)) - (let ((s3-0 (current-time))) - (until (time-elapsed? s3-0 (seconds 4.33)) + (if (and s4-0 (-> gp-0 tid)) + (suspend-for (seconds 4.33) (let ((f0-2 1.0)) (cond ((< f30-0 0.5) @@ -336,10 +332,8 @@ (if (not (paused?)) (+! f30-0 (seconds-per-frame)) ) - (suspend) ) ) - ) ) (none) ) @@ -358,13 +352,10 @@ (lambda :behavior scene-player () (talker-spawn-func (-> *talker-speech* 61) self (target-pos 0) (the-as region #f)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 5)) - (if (cpad-pressed? 0 square) - (return #f) - ) - (suspend) - ) + (suspend-for (seconds 5) + (if (cpad-pressed? 0 square) + (return #f) + ) ) (none) ) @@ -6186,7 +6177,3 @@ :on-complete #f ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/mhcity/destroy-dark-eco_REF.gc b/test/decompiler/reference/jak3/levels/mhcity/destroy-dark-eco_REF.gc index 895ff07d18..a927ca337e 100644 --- a/test/decompiler/reference/jak3/levels/mhcity/destroy-dark-eco_REF.gc +++ b/test/decompiler/reference/jak3/levels/mhcity/destroy-dark-eco_REF.gc @@ -330,10 +330,7 @@ ) 0 (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while *scene-player* (suspend) @@ -372,10 +369,7 @@ (part-tracker-spawn part-tracker :to *entity-pool* :group (-> *part-group-id-table* 325) :mat-joint gp-1) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (logior! (-> self draw status) (draw-control-status no-draw)) (let ((t0-2 (res-lump-struct (-> self entity) 'camera-name structure))) @@ -1433,11 +1427,7 @@ ) (send-event *target* 'change-mode 'darkjak #f (darkjak-stage force-on active)) ) - (let ((t9-3 (-> (find-parent-state) trans))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler trans) ) ) diff --git a/test/decompiler/reference/jak3/levels/mhcity/mhcity-obs2_REF.gc b/test/decompiler/reference/jak3/levels/mhcity/mhcity-obs2_REF.gc index 44841a9827..3f5a1e6414 100644 --- a/test/decompiler/reference/jak3/levels/mhcity/mhcity-obs2_REF.gc +++ b/test/decompiler/reference/jak3/levels/mhcity/mhcity-obs2_REF.gc @@ -437,11 +437,7 @@ :virtual #t :parent (mhcity-puffer-large puffer-active-base-state) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) ) :code (behavior () (ja-channel-push! 1 (seconds 0.1)) @@ -461,11 +457,7 @@ :virtual #t :parent (mhcity-puffer-large puffer-active-base-state) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) ) :code (behavior () (ja-channel-push! 1 (seconds 0.1)) @@ -479,7 +471,3 @@ #f ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/mhcity/mhcity-obs_REF.gc b/test/decompiler/reference/jak3/levels/mhcity/mhcity-obs_REF.gc index 452bec635a..8e63eb5945 100644 --- a/test/decompiler/reference/jak3/levels/mhcity/mhcity-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/mhcity/mhcity-obs_REF.gc @@ -924,10 +924,7 @@ (ja :num! (seek!)) ) (logior! (-> self draw status) (draw-control-status no-draw)) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (task-node-close! (game-task-node city-destroy-darkeco-resolution) 'event) (sleep-code) @@ -981,10 +978,7 @@ (label cfg-9) (ja-channel-push! 1 (seconds 0.5)) (ja :group! mhcity-dark-eco-door-idle-ja :num! (seek! 15.0) :frame-num 15.0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (go-virtual cracked) ) @@ -1318,10 +1312,7 @@ (part-tracker-spawn part-tracker :to *entity-pool* :group (-> *part-group-id-table* 326)) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (process-entity-status! self (entity-perm-status dead) #t) ) @@ -2452,7 +2443,3 @@ ) (go (method-of-object this idle)) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/mine/gekko_REF.gc b/test/decompiler/reference/jak3/levels/mine/gekko_REF.gc index bf82e546bf..55220c6335 100644 --- a/test/decompiler/reference/jak3/levels/mine/gekko_REF.gc +++ b/test/decompiler/reference/jak3/levels/mine/gekko_REF.gc @@ -2055,10 +2055,7 @@ (ja-channel-push! 1 (seconds 0.4)) (ja-no-eval :group! gekko-run0-a-ja :num! (seek!) :frame-num 0.0) (enable-ragdoll! (-> (the-as ragdoll-proc (handle->process (-> self ragdoll-proc))) ragdoll) self) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.4)) - (suspend) - ) + (suspend-for (seconds 0.4) ) (if (enemy-method-109 self) (go-die self) diff --git a/test/decompiler/reference/jak3/levels/mine/mine-obs_REF.gc b/test/decompiler/reference/jak3/levels/mine/mine-obs_REF.gc index 4e0ec94c8a..be59ef7f02 100644 --- a/test/decompiler/reference/jak3/levels/mine/mine-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/mine/mine-obs_REF.gc @@ -633,10 +633,7 @@ (suspend) (ja :num! (seek! max 0.03)) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (go-virtual inactive) ) @@ -1467,10 +1464,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((a1-0 (new 'stack-no-clear 'array 'symbol 3))) (set! (-> a1-0 2) 'mine6) @@ -1829,10 +1823,7 @@ :virtual #t :code (behavior () (sound-play "floor-switch") - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (when (not (task-node-closed? (game-task-node mine-blow-introduction))) (let ((a1-1 (new 'stack-no-clear 'array 'symbol 3))) diff --git a/test/decompiler/reference/jak3/levels/mine/mine-platforms_REF.gc b/test/decompiler/reference/jak3/levels/mine/mine-platforms_REF.gc index 2349de605e..4dfbd2be4f 100644 --- a/test/decompiler/reference/jak3/levels/mine/mine-platforms_REF.gc +++ b/test/decompiler/reference/jak3/levels/mine/mine-platforms_REF.gc @@ -503,10 +503,7 @@ ) :code (behavior () (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (let ((gp-1 (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> self root quat))) (s5-0 (vector-x-quaternion! (new 'stack-no-clear 'vector) (-> self root quat))) @@ -703,10 +700,7 @@ :trans plat-trans :code (behavior () (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (ja-channel-push! 1 0) (ja-no-eval :group! min-rotating-plat-idle-ja :num! min) @@ -1417,10 +1411,7 @@ ) :trans rider-trans :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.5)) - (suspend) - ) + (suspend-for (seconds 1.5) ) (when (-> self stop-sound) (set! (-> self stop-sound) #f) @@ -1641,10 +1632,7 @@ ) :code (behavior () (when (-> self play-ramp-sound?) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (until (= (get-status *gui-control* (-> self ramp-sound)) (gui-status ready)) (suspend) @@ -1829,10 +1817,7 @@ :trans rider-trans :code (behavior () (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.5)) - (suspend) - ) + (suspend-for (seconds 1.5) ) (when (-> self stop-bridge-sound) (set! (-> self stop-bridge-sound) #f) diff --git a/test/decompiler/reference/jak3/levels/mine/mine-train_REF.gc b/test/decompiler/reference/jak3/levels/mine/mine-train_REF.gc index ae7c27ff1f..8bbdb04575 100644 --- a/test/decompiler/reference/jak3/levels/mine/mine-train_REF.gc +++ b/test/decompiler/reference/jak3/levels/mine/mine-train_REF.gc @@ -528,10 +528,7 @@ (quaternion-normalize! (-> self root quat)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (when (type? (-> self root) collide-shape) (let ((v1-7 (-> self root root-prim))) @@ -989,7 +986,3 @@ ) (go (method-of-object this active)) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/mine/rat_REF.gc b/test/decompiler/reference/jak3/levels/mine/rat_REF.gc index 1ffc9e541a..12c960d875 100644 --- a/test/decompiler/reference/jak3/levels/mine/rat_REF.gc +++ b/test/decompiler/reference/jak3/levels/mine/rat_REF.gc @@ -763,11 +763,7 @@ (if (enemy-method-109 self) (go-virtual die) ) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) ) @@ -2086,10 +2082,7 @@ (logior! (-> self entity extra perm status) (entity-perm-status subtask-complete)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (-> self child) (suspend) diff --git a/test/decompiler/reference/jak3/levels/nest/egg-spider_REF.gc b/test/decompiler/reference/jak3/levels/nest/egg-spider_REF.gc index 9420d018b1..2b15e4ee76 100644 --- a/test/decompiler/reference/jak3/levels/nest/egg-spider_REF.gc +++ b/test/decompiler/reference/jak3/levels/nest/egg-spider_REF.gc @@ -1432,10 +1432,7 @@ (part-tracker-spawn part-tracker :to *entity-pool* :group (-> *part-group-id-table* 639)) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.6)) - (suspend) - ) + (suspend-for (seconds 0.6) ) (let ((v1-38 (-> self root root-prim))) (set! (-> v1-38 prim-core collide-as) (-> self root backup-collide-as)) @@ -1459,10 +1456,7 @@ ) ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6))) ) (ja-channel-push! 1 0) (ja-no-eval :group! egg-spider-crawl-from-ground-ja :num! (seek!) :frame-num 0.0) diff --git a/test/decompiler/reference/jak3/levels/nest/mh-bat_REF.gc b/test/decompiler/reference/jak3/levels/nest/mh-bat_REF.gc index 07b5a2b1d1..93314b1d80 100644 --- a/test/decompiler/reference/jak3/levels/nest/mh-bat_REF.gc +++ b/test/decompiler/reference/jak3/levels/nest/mh-bat_REF.gc @@ -1237,11 +1237,7 @@ (defstate ambush (mh-bat) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set-time! (-> self state-time)) (set! (-> self start-pos quad) (-> self root trans quad)) (set-vector! (-> self root transv) 0.0 -81920.0 0.0 0.0) @@ -1366,11 +1362,7 @@ (defstate hostile (mh-bat) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self bank-angle) 0.0) (set! (-> self pitch-angle) 0.0) (set! (-> self orbit-distance) (* 4096.0 (rnd-float-range self 17.0 30.0))) @@ -1925,7 +1917,3 @@ 0 (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/nest/nst-obs_REF.gc b/test/decompiler/reference/jak3/levels/nest/nst-obs_REF.gc index 5bc2aa3f32..aa2e360c9e 100644 --- a/test/decompiler/reference/jak3/levels/nest/nst-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/nest/nst-obs_REF.gc @@ -167,10 +167,7 @@ ) ) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (cleanup-for-death self) ) @@ -859,10 +856,7 @@ (when (-> self actor-group) (let ((f30-0 (* 0.0005 (the float (-> self actor-group length))))) (dotimes (gp-8 (-> self actor-group length)) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (the int (* 300.0 f30-0))) - (suspend) - ) + (suspend-for (the int (* 300.0 f30-0)) ) (let ((a1-24 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-24 from) (process->ppointer self)) @@ -1368,10 +1362,7 @@ ) :code (behavior () (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) (when (-> self anim) (-> self draw bounds w) @@ -1968,18 +1959,12 @@ (set! (-> self cycling?) #t) (spawn (-> self charge-up-part) (-> self node-list data 12 bone transform trans)) (set! (-> self cycle-rot) -1820.4445) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (ja :num! (loop!)) - (suspend) - ) + (suspend-for (seconds 0.5) + (ja :num! (loop!)) ) (set! (-> self cycle-rot) 1820.4445) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 0.5)) - (ja :num! (loop!)) - (suspend) - ) + (suspend-for (seconds 0.5) + (ja :num! (loop!)) ) (set! (-> self cycling?) #f) (set! (-> self shots-left) (the-as uint 4)) @@ -2162,18 +2147,12 @@ (if (>= (-> self palette-id) 0) (set-nstb-lights! (-> self palette-id) 4.0 8.0 #f) ) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (if (>= (-> self palette-id) 0) (set-nstb-lights! (-> self palette-id) 0.0 6.0 #f) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 0.35)) - (suspend) - ) + (suspend-for (seconds 0.35) ) (let ((gp-6 (-> self child))) (while gp-6 @@ -2778,7 +2757,3 @@ (ja-post) (go (method-of-object this idle)) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/precursor/precura-obs2_REF.gc b/test/decompiler/reference/jak3/levels/precursor/precura-obs2_REF.gc index d104361125..35da5d3d35 100644 --- a/test/decompiler/reference/jak3/levels/precursor/precura-obs2_REF.gc +++ b/test/decompiler/reference/jak3/levels/precursor/precura-obs2_REF.gc @@ -1793,10 +1793,7 @@ (let ((gp-0 (res-lump-data (-> self entity) 'actor-groups pointer :tag-ptr (& sv-16)))) (cond ((and gp-0 (nonzero? (-> sv-16 elt-count))) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (set! (-> self actor-group-count) (the-as int (-> sv-16 elt-count))) (set! (-> self actor-group) (the-as (pointer actor-group) gp-0)) diff --git a/test/decompiler/reference/jak3/levels/precursor/precura-obs_REF.gc b/test/decompiler/reference/jak3/levels/precursor/precura-obs_REF.gc index c0c6d2b2fb..9a04e27431 100644 --- a/test/decompiler/reference/jak3/levels/precursor/precura-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/precursor/precura-obs_REF.gc @@ -8,10 +8,8 @@ process (lambda :behavior process () - (let ((gp-0 (current-time)) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 (seconds 1)) + (let ((gp-0 (current-time))) + (suspend-for (seconds 1) (when (time-elapsed? gp-0 (seconds 0.03)) (set! gp-0 (current-time)) (process-drawable-shock-effect @@ -24,7 +22,6 @@ 40960.0 ) ) - (suspend) ) ) #f @@ -1165,26 +1162,17 @@ ) (logior! (-> self draw status) (draw-control-status no-draw)) (transform-post) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1.2)) - (suspend) - ) + (suspend-for (seconds 1.2) ) (when (res-lump-struct (-> self entity) 'art-name structure) (logclear! (-> self mask) (process-mask actor-pause)) (process-grab? *target* #f) (set-setting! 'entity-name "camera-359" 0.0 0) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (task-close! "precursor-tour-generator-trigger") (send-event (process-by-name "precur-door-b-4" *active-pool*) 'open) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (set-setting! 'interp-time 'abs 450.0 0) (remove-setting! 'entity-name) @@ -2796,10 +2784,7 @@ (not (and (-> self entity) (logtest? (-> self entity extra perm status) (entity-perm-status subtask-complete))) ) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1.5)) - (suspend) - ) + (suspend-for (seconds 1.5) ) (set-setting! 'entity-name "camera-420" 0.0 0) (process-grab? *target* #f) @@ -2877,10 +2862,7 @@ ) :code (behavior () (when (-> self precur-tour?) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2.5)) - (suspend) - ) + (suspend-for (seconds 2.5) ) (remove-setting! 'entity-name) (process-release? *target*) diff --git a/test/decompiler/reference/jak3/levels/sewer/mh-wasp_REF.gc b/test/decompiler/reference/jak3/levels/sewer/mh-wasp_REF.gc index 943c2ce01e..e6c8543e9a 100644 --- a/test/decompiler/reference/jak3/levels/sewer/mh-wasp_REF.gc +++ b/test/decompiler/reference/jak3/levels/sewer/mh-wasp_REF.gc @@ -914,10 +914,7 @@ 0 (set! (-> self hit-points) 0.0) (do-effect (-> self skel effect) (the-as string 'death-default) 0.0 -1) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (cleanup-for-death self) @@ -1421,7 +1418,3 @@ 0 (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/sewer/neo-juicer_REF.gc b/test/decompiler/reference/jak3/levels/sewer/neo-juicer_REF.gc index f64e9aa327..c6f294da5d 100644 --- a/test/decompiler/reference/jak3/levels/sewer/neo-juicer_REF.gc +++ b/test/decompiler/reference/jak3/levels/sewer/neo-juicer_REF.gc @@ -1343,57 +1343,55 @@ (s5-0 (+ (-> v1-29 attack-id) 1)) ) (set! (-> v1-29 attack-id) s5-0) - (let ((s4-0 (current-time))) - (until (time-elapsed? s4-0 (seconds 0.25)) - (ja-no-eval :group! neo-juicer-attack0-ja :num! (seek!) :frame-num 0.0) - (until (ja-done? 0) - (let ((s3-0 (handle->process (-> self focus handle)))) - (when s3-0 - (when (< 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable s3-0) 0))) - (spawn-proj! self (the-as process-focusable s3-0) s5-0) - (current-time) - (if (not gp-0) - (set! gp-0 #t) - ) - ) + (suspend-for (seconds 0.25) + (ja-no-eval :group! neo-juicer-attack0-ja :num! (seek!) :frame-num 0.0) + (until (ja-done? 0) + (let ((s3-0 (handle->process (-> self focus handle)))) + (when s3-0 + (when (< 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable s3-0) 0))) + (spawn-proj! self (the-as process-focusable s3-0) s5-0) + (current-time) + (if (not gp-0) + (set! gp-0 #t) + ) ) ) - (if (and (logtest? (-> self enemy-flags) (enemy-flag victory)) (-> self enemy-info use-victory)) - (go-virtual victory) - ) - (b! - (not (and (-> self using-turn-anim) (let ((v1-73 (ja-group))) - (not (and v1-73 (= v1-73 neo-juicer-attack-turn-ja))) - ) - ) - ) - cfg-31 - :delay (empty-form) - ) - (ja-channel-push! 1 (seconds 0.05)) - (ja :group! neo-juicer-attack-turn-ja) - (b! #t cfg-42 :delay (nop!)) - (label cfg-31) - (when (and (not (-> self using-turn-anim)) (let ((v1-84 (ja-group))) - (not (and v1-84 (= v1-84 neo-juicer-attack0-ja))) - ) - ) - (ja-channel-push! 1 (seconds 0.05)) - (ja :group! neo-juicer-attack0-ja) - ) - (label cfg-42) - (suspend) - (ja :num! (seek!)) ) - (send-event (handle->process (-> self current-projectile)) 'die) - (let ((a0-37 (handle->process (-> self focus handle)))) - (when a0-37 - (if (>= 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable a0-37) 0))) - (go-virtual circling) - ) + (if (and (logtest? (-> self enemy-flags) (enemy-flag victory)) (-> self enemy-info use-victory)) + (go-virtual victory) ) + (b! + (not (and (-> self using-turn-anim) (let ((v1-73 (ja-group))) + (not (and v1-73 (= v1-73 neo-juicer-attack-turn-ja))) + ) + ) + ) + cfg-31 + :delay (empty-form) ) + (ja-channel-push! 1 (seconds 0.05)) + (ja :group! neo-juicer-attack-turn-ja) + (b! #t cfg-42 :delay (nop!)) + (label cfg-31) + (when (and (not (-> self using-turn-anim)) (let ((v1-84 (ja-group))) + (not (and v1-84 (= v1-84 neo-juicer-attack0-ja))) + ) + ) + (ja-channel-push! 1 (seconds 0.05)) + (ja :group! neo-juicer-attack0-ja) + ) + (label cfg-42) (suspend) + (ja :num! (seek!)) + ) + (empty-form) + (send-event (handle->process (-> self current-projectile)) 'die) + (let ((a0-37 (handle->process (-> self focus handle)))) + (when a0-37 + (if (>= 28672.0 (vector-vector-distance (-> self root trans) (get-trans (the-as process-focusable a0-37) 0))) + (go-virtual circling) + ) + ) ) ) ) @@ -1863,7 +1861,3 @@ 0 (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/sewer/saberfish_REF.gc b/test/decompiler/reference/jak3/levels/sewer/saberfish_REF.gc index 05823a74a4..e14f9f4a5e 100644 --- a/test/decompiler/reference/jak3/levels/sewer/saberfish_REF.gc +++ b/test/decompiler/reference/jak3/levels/sewer/saberfish_REF.gc @@ -1100,11 +1100,7 @@ :virtual #t :enter (behavior () (sound-play "sabfish-gethit") - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) ) @@ -1115,11 +1111,7 @@ (if (saberfish-method-243 self) (go-virtual swimming-hostile) ) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () (let ((a0-1 (handle->process (-> self focus handle)))) @@ -1132,11 +1124,7 @@ (handle-cmd self a1-2) ) ) - (let ((t9-4 (-> (find-parent-state) trans))) - (if t9-4 - (t9-4) - ) - ) + (call-parent-state-handler trans) ) :post saberfish-chase-post ) @@ -3118,11 +3106,7 @@ (set! (-> self swim-travel-anim) 0) 0 ) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (set! (-> self scare-time) 0) @@ -3161,13 +3145,9 @@ ) ) (saberfish-swim-travel-trans) - (when (>= (the-as int (-> self focus aware)) 2) - (let ((t9-9 (-> (find-parent-state) trans))) - (if t9-9 - (t9-9) - ) + (if (>= (the-as int (-> self focus aware)) 2) + (call-parent-state-handler trans) ) - ) ) :code (behavior () (saberfish-swim-code) @@ -3308,18 +3288,10 @@ :enter (behavior () (set! (-> self knocked-under-water?) #f) (set! (-> self move-to-ground?) #f) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) ) ) @@ -3361,11 +3333,7 @@ (if (saberfish-method-243 self) (go-virtual knocked-recover-water) ) - (let ((t9-4 (-> (find-parent-state) enter))) - (if t9-4 - (t9-4) - ) - ) + (call-parent-state-handler enter) ) :code (behavior () (if (handle->process (-> self ragdoll-proc)) @@ -3373,10 +3341,7 @@ ) (ja-channel-push! 1 0) (ja-no-eval :group! saberfish-flip-up-start-ja :num! (seek!) :frame-num 0.0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.4)) - (suspend) - ) + (suspend-for (seconds 0.4) ) (ja-channel-push! 1 0) (ja-no-eval :group! saberfish-flip-up-ja :num! (seek!) :frame-num 0.0) @@ -3899,7 +3864,3 @@ ) ) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/sewer/sew-laser-guard_REF.gc b/test/decompiler/reference/jak3/levels/sewer/sew-laser-guard_REF.gc index 4c6d723674..95b2b2c2f5 100644 --- a/test/decompiler/reference/jak3/levels/sewer/sew-laser-guard_REF.gc +++ b/test/decompiler/reference/jak3/levels/sewer/sew-laser-guard_REF.gc @@ -16,7 +16,6 @@ ) ;; definition for method 3 of type gun-turret-params -;; INFO: this function exists in multiple non-identical object files (defmethod inspect ((this gun-turret-params)) (when (not this) (set! this this) @@ -655,17 +654,11 @@ (let ((gp-1 (new 'stack-no-clear 'vector))) (set! (-> gp-1 quad) (-> self root trans quad)) (+! (-> gp-1 y) 10240.0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 2)) - (spawn (-> self part) gp-1) - (suspend) - ) + (suspend-for (seconds 2) + (spawn (-> self part) gp-1) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (while (-> self child) @@ -813,7 +806,3 @@ ) :code sleep-code ) - - - - diff --git a/test/decompiler/reference/jak3/levels/sewer/sew-laser-turret_REF.gc b/test/decompiler/reference/jak3/levels/sewer/sew-laser-turret_REF.gc index 4173b60447..4acd27d7bd 100644 --- a/test/decompiler/reference/jak3/levels/sewer/sew-laser-turret_REF.gc +++ b/test/decompiler/reference/jak3/levels/sewer/sew-laser-turret_REF.gc @@ -16,7 +16,6 @@ ) ;; definition for method 3 of type gun-turret-params -;; INFO: this function exists in multiple non-identical object files (defmethod inspect ((this gun-turret-params)) (when (not this) (set! this this) @@ -1149,17 +1148,11 @@ (let ((gp-1 (new 'stack-no-clear 'vector))) (set! (-> gp-1 quad) (-> self root trans quad)) (+! (-> gp-1 y) 10240.0) - (let ((s5-1 (current-time))) - (until (time-elapsed? s5-1 (seconds 2)) - (spawn (-> self part) gp-1) - (suspend) - ) + (suspend-for (seconds 2) + (spawn (-> self part) gp-1) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (while (-> self child) diff --git a/test/decompiler/reference/jak3/levels/sewer/sew-platforms_REF.gc b/test/decompiler/reference/jak3/levels/sewer/sew-platforms_REF.gc index 4f1075ba0a..8e18111d04 100644 --- a/test/decompiler/reference/jak3/levels/sewer/sew-platforms_REF.gc +++ b/test/decompiler/reference/jak3/levels/sewer/sew-platforms_REF.gc @@ -162,18 +162,10 @@ :virtual #t :enter (behavior () (set! (-> self last-played-start?) #f) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (cond ((and (-> self last-played-start?) (< 0.9 (-> self path-pos))) (sound-play "moving-step-out") @@ -260,19 +252,11 @@ :virtual #t :enter (behavior () (set! (-> self last-played-start?) #f) - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set! (-> self last-val) -1.0) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (when (< (-> self path-pos) 0.5) (new 'stack-no-clear 'vector) (let ((gp-0 (new 'stack-no-clear 'matrix))) @@ -1016,7 +1000,3 @@ "Should this process be run? Checked by execute-process-tree." #t ) - - - - diff --git a/test/decompiler/reference/jak3/levels/sewer/sewer-obs2_REF.gc b/test/decompiler/reference/jak3/levels/sewer/sewer-obs2_REF.gc index 8f8e3baf30..000b148d19 100644 --- a/test/decompiler/reference/jak3/levels/sewer/sewer-obs2_REF.gc +++ b/test/decompiler/reference/jak3/levels/sewer/sewer-obs2_REF.gc @@ -254,19 +254,13 @@ :virtual #t :code (behavior () (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (set-setting! 'mode-name 'cam-fixed 0.0 0) (set-setting! 'interp-time 'abs 0.0 0) (set-setting! 'entity-name "camera-353" 0.0 0) (process-grab? *target* #f) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (sound-play "gate-open") (ja-no-eval :group! sew-m-gate-gate-open-ja :num! (seek! max 0.1) :frame-num 0.0) @@ -278,10 +272,7 @@ (remove-setting! 'mode-name) (remove-setting! 'interp-time) (remove-setting! 'entity-name) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (process-release? *target*) (go-virtual raised) @@ -430,19 +421,13 @@ :virtual #t :code (behavior () (process-entity-status! self (entity-perm-status subtask-complete) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (set-setting! 'mode-name 'cam-fixed 0.0 0) (set-setting! 'interp-time 'abs 0.0 0) (set-setting! 'entity-name "camera-352" 0.0 0) (process-grab? *target* #f) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (sound-play "pipe-lower") (set-time! (-> self state-time)) @@ -458,10 +443,7 @@ (remove-setting! 'mode-name) (remove-setting! 'interp-time) (remove-setting! 'entity-name) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (process-release? *target*) (go-virtual down) @@ -660,7 +642,3 @@ (set! (-> this opened-x) (+ -32768.0 (-> this root trans x))) (go (method-of-object this closed)) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/sewer/sewer-obs_REF.gc b/test/decompiler/reference/jak3/levels/sewer/sewer-obs_REF.gc index 69144bbd1f..49496114c1 100644 --- a/test/decompiler/reference/jak3/levels/sewer/sewer-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/sewer/sewer-obs_REF.gc @@ -269,10 +269,7 @@ (defstate active (sew-cam-sequencer) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (until (process-grab? *target* #f) (suspend) @@ -282,20 +279,14 @@ (sew-cam-eval-script a0-1) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (-> self timeout)) - (suspend) - ) + (suspend-for (-> self timeout) ) (let ((a0-3 (-> self activate-script))) (if a0-3 (sew-cam-eval-script a0-3) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (the-as time-frame (-> self offset))) - (suspend) - ) + (suspend-for (the-as time-frame (-> self offset)) ) (let ((a0-5 (-> self exit-script))) (if a0-5 @@ -1527,19 +1518,13 @@ ) (let ((v1-25 (res-lump-value (-> self entity) 'extra-id uint128 :time -1000000000.0))) (when (= (the-as uint v1-25) 1) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (set-setting! 'mode-name 'cam-fixed 0.0 0) (set-setting! 'interp-time 'abs 0.0 0) (set-setting! 'entity-name "camera-300" 0.0 0) (process-grab? *target* #f) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((gp-2 (-> self actor-group 1))) (dotimes (s5-0 (-> gp-2 length)) @@ -1560,18 +1545,12 @@ ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (remove-setting! 'mode-name) (remove-setting! 'interp-time) (remove-setting! 'entity-name) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (process-release? *target*) (go-virtual opened) @@ -2037,10 +2016,7 @@ (set-setting! 'entity-name "camera-224" 0.0 0) (set-setting! 'allow-progress #f 0.0 0) (process-grab? *target* #f) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (task-node-close! (game-task-node sewer-hum-kg-switch-off) 'event) (script-eval '(send-event "ctyinda-vingate-1" 'shutdown)) @@ -2055,10 +2031,7 @@ (the-as process #f) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 2.4)) - (suspend) - ) + (suspend-for (seconds 2.4) ) (set-setting! 'string-startup-vector 'abs (new 'static 'vector :x 1.0) 0) (remove-setting! 'entity-name) diff --git a/test/decompiler/reference/jak3/levels/stadium/dm-mine-spider_REF.gc b/test/decompiler/reference/jak3/levels/stadium/dm-mine-spider_REF.gc index f3f1cee5a6..7ff400e7d3 100644 --- a/test/decompiler/reference/jak3/levels/stadium/dm-mine-spider_REF.gc +++ b/test/decompiler/reference/jak3/levels/stadium/dm-mine-spider_REF.gc @@ -1122,10 +1122,7 @@ (set-time! (-> self state-time)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.6)) - (suspend) - ) + (suspend-for (seconds 0.6) ) (let ((v1-6 (-> self root root-prim))) (set! (-> v1-6 prim-core collide-as) (-> self root backup-collide-as)) @@ -1133,10 +1130,7 @@ ) (logclear! (-> self draw status) (draw-control-status no-draw)) (update-focus self) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (the int (* 300.0 (rnd-float-range self 0.0 0.6)))) - (suspend) - ) + (suspend-for (the int (* 300.0 (rnd-float-range self 0.0 0.6))) ) (ja-channel-push! 1 0) (ja-no-eval :group! dm-mine-spider-climb-start-ja :num! (seek!) :frame-num 0.0) diff --git a/test/decompiler/reference/jak3/levels/temple/hover-training_REF.gc b/test/decompiler/reference/jak3/levels/temple/hover-training_REF.gc index bca2484f81..1b1cca6a88 100644 --- a/test/decompiler/reference/jak3/levels/temple/hover-training_REF.gc +++ b/test/decompiler/reference/jak3/levels/temple/hover-training_REF.gc @@ -915,17 +915,11 @@ (until (process-grab? *target* #f) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (persist-with-delay *setting-control* 'interp-time (seconds 4) 'interp-time 'abs 0.0 0) (set-setting! 'entity-name "camera-354" 0.0 0) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (task-node-close! (game-task-node temple-tests-hover-training) 'event) (until (process-release? *target*) @@ -1341,7 +1335,3 @@ (logclear! (-> this mask) (process-mask actor-pause)) (go (method-of-object this idle)) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/temple/temple-obs2_REF.gc b/test/decompiler/reference/jak3/levels/temple/temple-obs2_REF.gc index 08a49474de..40ff0a9b3e 100644 --- a/test/decompiler/reference/jak3/levels/temple/temple-obs2_REF.gc +++ b/test/decompiler/reference/jak3/levels/temple/temple-obs2_REF.gc @@ -111,10 +111,7 @@ (suspend) ) (set-setting! 'entity-name "camera-356" 0.0 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) ) (sound-play "gate-raise") @@ -124,10 +121,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (let ((a1-6 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-6 from) (process->ppointer self)) @@ -145,16 +139,10 @@ ) ) (when (= (-> self extra-id) 1) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (remove-setting! 'entity-name) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 2.5)) - (suspend) - ) + (suspend-for (seconds 2.5) ) (until (process-release? *target*) (suspend) @@ -284,9 +272,9 @@ (within-outer-ring symbol) (within-inner-ring symbol) (ouched symbol) - (bound-cam basic) + (bound-cam string) (trans vector :inline) - (state-time uint64) + (state-time time-frame) (jak-in-hint-region symbol) (watchers-vulnerable symbol) ) @@ -420,7 +408,7 @@ (logior! (-> v1-8 status) (entity-perm-status bit-14)) ) ) - (set! (-> self bound-cam) (the-as basic (-> arg3 param 0))) + (set! (-> self bound-cam) (the-as string (-> arg3 param 0))) (set! (-> self ouched) #t) (go-virtual until-watchers-dead) ) @@ -468,10 +456,7 @@ :event tpl-watcher-manager-ehandler :trans watcher-man-trans :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (while (and *target* (focus-test? *target* dead)) (suspend) @@ -485,7 +470,7 @@ :virtual #t :event tpl-watcher-manager-ehandler :enter (behavior () - (set! (-> self state-time) (the-as uint (current-time))) + (set-time! (-> self state-time)) ) :trans watcher-man-trans :code (behavior () @@ -496,10 +481,7 @@ (suspend) ) (process-entity-status! self (entity-perm-status no-kill) #t) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2.5)) - (suspend) - ) + (suspend-for (seconds 2.5) ) (while (not (process-release? *target*)) (suspend) @@ -529,7 +511,7 @@ ) ) ) - (until (time-elapsed? (the-as int (-> self state-time)) (seconds 1)) + (until (time-elapsed? (-> self state-time) (seconds 1)) (suspend) ) (task-close! "temple-oracle-watchers-complete") @@ -633,7 +615,7 @@ standing-down ) (:methods - (tpl-watcher-method-32 (_type_) none) + (init-collision! (_type_) none) ) ) @@ -1014,11 +996,8 @@ ) ) (sound-play "wtcher-fire") - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - '() - (suspend) - ) + (suspend-for (seconds 1) + '() ) ) ) @@ -1088,10 +1067,7 @@ ) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 4)) - (suspend) - ) + (suspend-for (seconds 4) ) (while (-> self child) (suspend) @@ -1127,16 +1103,14 @@ :code (behavior () (let ((gp-0 (-> self root quat)) (s5-0 (-> self entity quat)) - (s4-0 (current-time)) ) - (until (time-elapsed? s4-0 (seconds 1.5)) + (suspend-for (seconds 1.5) (quaternion-slerp! (-> self root quat) gp-0 s5-0 (* 0.0022222223 (the float (- (current-time) (-> self state-time)))) ) - (suspend) ) ) (go-virtual idle) @@ -1146,7 +1120,7 @@ ;; definition for method 32 of type tpl-watcher ;; WARN: Return type mismatch collide-shape-moving vs none. -(defmethod tpl-watcher-method-32 ((this tpl-watcher)) +(defmethod init-collision! ((this tpl-watcher)) (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum usually-hit-by-player)))) (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process)) (set! (-> s5-0 reaction) cshape-reaction-default) @@ -1205,7 +1179,7 @@ (defmethod init-from-entity! ((this tpl-watcher) (arg0 entity-actor)) (local-vars (sv-16 res-tag)) (stack-size-set! (-> this main-thread) 384) - (tpl-watcher-method-32 this) + (init-collision! this) (process-drawable-from-entity! this arg0) (logior! (-> this mask) (process-mask enemy)) (initialize-skeleton @@ -1820,10 +1794,8 @@ ) (quaternion-normalize! s5-2) (set-time! (-> self state-time)) - (let ((f30-1 (lerp-scale 45.0 9.0 (-> self clock clock-ratio) 1.0 0.05)) - (s4-2 (current-time)) - ) - (until (time-elapsed? s4-2 (the int f30-1)) + (let ((f30-1 (lerp-scale 45.0 9.0 (-> self clock clock-ratio) 1.0 0.05))) + (suspend-for (the int f30-1) (quaternion-slerp! (-> self root quat) gp-3 @@ -1831,7 +1803,6 @@ (/ (the float (- (current-time) (-> self state-time))) f30-1) ) (quaternion-normalize! (-> self root quat)) - (suspend) ) ) (quaternion-copy! (-> self root quat) s5-2) @@ -1850,12 +1821,9 @@ :virtual #t :trans rider-trans :code (behavior () - (let ((f30-0 (res-lump-float (-> self entity) 'tpl-platform-predelay)) - (gp-0 (current-time)) - ) - (until (time-elapsed? gp-0 (the int (* 300.0 f30-0))) + (let ((f30-0 (res-lump-float (-> self entity) 'tpl-platform-predelay))) + (suspend-for (the int (* 300.0 f30-0)) '() - (suspend) ) ) (go-virtual flip) @@ -1912,11 +1880,8 @@ :code (behavior () (set-time! (-> self state-time)) (set! (-> self state-time) (-> *display* real-clock frame-counter)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.25)) - '() - (suspend) - ) + (suspend-for (seconds 0.25) + '() ) (while (< (+ (-> *display* real-clock frame-counter) (seconds -1)) (-> self last-ridden)) (suspend) @@ -2131,11 +2096,7 @@ :virtual #t :enter (behavior () (setup-masks (-> self draw) 3 0) - (let ((t9-2 (-> (find-parent-state) enter))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (setup-masks (-> self draw) 1 2) @@ -2274,3 +2235,7 @@ ((method-of-type process-focusable deactivate) (the-as process-focusable this)) (none) ) + + + + diff --git a/test/decompiler/reference/jak3/levels/temple/temple-obs_REF.gc b/test/decompiler/reference/jak3/levels/temple/temple-obs_REF.gc index dd4b1c3e45..d892fd1a57 100644 --- a/test/decompiler/reference/jak3/levels/temple/temple-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/temple/temple-obs_REF.gc @@ -486,18 +486,10 @@ (set! (-> gp-0 map-icon) (the-as uint 13)) (set! (-> self arrow-h) (process->handle (task-arrow-spawn gp-0 self))) ) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (when (-> self arrow-h) (let ((gp-0 (-> self arrow-h process 0))) (when (and (< (vector-vector-distance (-> (the-as process-drawable gp-0) root trans) (target-pos 0)) 20480.0) @@ -581,11 +573,7 @@ (if (and *target* (focus-test? *target* light)) (send-event self 'complete) ) - (let ((t9-3 (-> (find-parent-state) trans))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler trans) ) ) @@ -1114,10 +1102,7 @@ (until (process-grab? *target* #f) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) ) ) @@ -1139,10 +1124,7 @@ (set! (-> self root scale z) (-> self root scale x)) (when (= (-> self root scale x) 0.0) (send-event (handle->process (-> self perm-part)) 'die) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (until (process-release? *target*) (suspend) @@ -2014,44 +1996,30 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (the int (-> self cycle-offset))) - (suspend) - ) + (suspend-for (the int (-> self cycle-offset)) ) (until #f - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (the int (-> self cycle-time))) - (suspend) - ) + (suspend-for (the int (-> self cycle-time)) ) (sound-play "fan-shake" :position (-> self root trans)) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.01)) - (let ((f0-5 (* 36408.89 (the float (- (current-time) gp-3)))) - (f1-3 (* 0.33333334 (- 3.0 (the float (- (current-time) gp-3))))) - ) - (set! (-> self shudder-angle) (* 0.0018204444 f1-3 (sin f0-5))) - ) - (suspend) + (suspend-for (seconds 0.01) + (let ((f0-5 (* 36408.89 (the float (- (current-time) time)))) + (f1-3 (* 0.33333334 (- 3.0 (the float (- (current-time) time))))) + ) + (set! (-> self shudder-angle) (* 0.0018204444 f1-3 (sin f0-5))) ) ) (set! (-> self shudder-angle) 0.0) - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 0.04)) - (suspend) - ) + (suspend-for (seconds 0.04) ) (sound-play "fan-turn" :position (-> self root trans)) (let* ((f0-9 100.0) (f30-1 (* 16384.0 f0-9)) - (gp-6 (current-time)) ) - (until (time-elapsed? gp-6 (seconds 0.01)) + (suspend-for (seconds 0.01) (set! (-> self rot-angle) (the float (sar (shl (the int (+ (-> self rot-angle) (* f30-1 (seconds-per-frame)))) 48) 48)) ) - (suspend) ) ) (let ((v1-47 #x4000)) @@ -2488,10 +2456,7 @@ (script-eval (the-as pair gp-0)) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (cleanup-for-death self) (deactivate self) @@ -2678,10 +2643,7 @@ (script-eval (the-as pair gp-0)) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (cleanup-for-death self) (deactivate self) diff --git a/test/decompiler/reference/jak3/levels/title/title-obs_REF.gc b/test/decompiler/reference/jak3/levels/title/title-obs_REF.gc index 58c8a3dafb..c0d7caf3dd 100644 --- a/test/decompiler/reference/jak3/levels/title/title-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/title/title-obs_REF.gc @@ -220,10 +220,7 @@ (cond ((and (kiosk?) (or (cpad-pressed? 0 square) (time-elapsed? s5-1 (seconds 60)))) (initialize! *game-info* 'game (the-as game-save #f) (the-as string #f) (the-as resetter-spec #f)) - (let ((s5-2 (current-time))) - (until (time-elapsed? s5-2 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) (set! s5-1 (current-time)) ) @@ -285,10 +282,7 @@ #x33001 #t ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.4)) - (suspend) - ) + (suspend-for (seconds 0.4) ) (send-event (ppointer->process (-> *setting-control* user-current movie)) 'abort) (set! (-> *setting-control* user-current bg-a) 0.0) @@ -579,7 +573,7 @@ (set! (-> t0-2 y) 1.0) (set! (-> t0-2 z) 0.0) (set! (-> t0-2 w) 1.0) - (t9-6 (the-as bucket-id a0-31) (the-as art-group a1-15) (the-as int a2-5) a3-7 t0-2 (-> self level) 8) + (t9-6 a0-31 (the-as bucket-id a1-15) a2-5 a3-7 t0-2 (-> self level) 8) ) (set! (-> self active) #t) ) @@ -599,10 +593,7 @@ :code (behavior () (remove-setting! 'allow-timeout) (remove-setting! 'dialog-volume) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event (ppointer->process (-> self logo)) @@ -632,10 +623,7 @@ ) ) ) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (remove-setting! 'dust-storm-fog-scalar) (if (zero? (title-menu)) @@ -660,10 +648,7 @@ ) ) (until (= (-> *game-info* current-continue level) 'title) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) ) (go-virtual wait) @@ -1008,10 +993,7 @@ ) ) ) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 0.6)) - (suspend) - ) + (suspend-for (seconds 0.6) ) (process-spawn-function process @@ -2756,3 +2738,7 @@ ) :post target-no-move-post ) + + + + diff --git a/test/decompiler/reference/jak3/levels/tower/tower-obs_REF.gc b/test/decompiler/reference/jak3/levels/tower/tower-obs_REF.gc index fddcb36a67..4f81400e14 100644 --- a/test/decompiler/reference/jak3/levels/tower/tower-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/tower/tower-obs_REF.gc @@ -396,10 +396,7 @@ :virtual #t :code (behavior () (logclear! (-> self draw status) (draw-control-status force-fade)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (process-spawn scene-player @@ -593,10 +590,7 @@ (set-time! (-> self state-time)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.75)) - (suspend) - ) + (suspend-for (seconds 0.75) ) (let ((v1-6 (-> self root root-prim))) (set! (-> v1-6 prim-core collide-as) (-> self root backup-collide-as)) @@ -606,15 +600,12 @@ (logclear! (-> self draw status) (draw-control-status no-draw)) (let ((f30-0 1.0)) 0.0 - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (the int (* 300.0 f30-0))) - (let ((f0-2 (fmax 0.0 (fmin 1.0 (/ (the float (- (current-time) gp-2)) (* 300.0 f30-0)))))) - (set-vector! (-> self draw color-mult) f0-2 f0-2 f0-2 1.0) - ) - (spawn-from-cspace (-> self part) (joint-node tow-energy-bridge-lod0-jg main)) - (ja-post) - (suspend) + (suspend-for (the int (* 300.0 f30-0)) + (let ((f0-2 (fmax 0.0 (fmin 1.0 (/ (the float (- (current-time) time)) (* 300.0 f30-0)))))) + (set-vector! (-> self draw color-mult) f0-2 f0-2 f0-2 1.0) ) + (spawn-from-cspace (-> self part) (joint-node tow-energy-bridge-lod0-jg main)) + (ja-post) ) ) (process-entity-status! self (entity-perm-status subtask-complete) #t) diff --git a/test/decompiler/reference/jak3/levels/volcano/spiky-frog_REF.gc b/test/decompiler/reference/jak3/levels/volcano/spiky-frog_REF.gc index aa82bba473..aba9167ab0 100644 --- a/test/decompiler/reference/jak3/levels/volcano/spiky-frog_REF.gc +++ b/test/decompiler/reference/jak3/levels/volcano/spiky-frog_REF.gc @@ -950,13 +950,10 @@ :num! (identity (the float (+ (-> (the-as art-joint-anim spiky-frog-ball0-end-ja) frames num-frames) -1))) ) (enable-ragdoll! (-> (the-as ragdoll-proc (handle->process (-> self ragdoll-proc))) ragdoll) self) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.411)) - (if (!= (-> self root gspot-pos y) -40959590.0) - (seek! (-> self root trans y) (-> self root gspot-pos y) (* 409600.0 (seconds-per-frame))) - ) - (suspend) - ) + (suspend-for (seconds 0.411) + (if (!= (-> self root gspot-pos y) -40959590.0) + (seek! (-> self root trans y) (-> self root gspot-pos y) (* 409600.0 (seconds-per-frame))) + ) ) ) (else @@ -1180,7 +1177,3 @@ 0 (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/volcano/volcano-obs2_REF.gc b/test/decompiler/reference/jak3/levels/volcano/volcano-obs2_REF.gc index 7b39e48e6a..fec736909d 100644 --- a/test/decompiler/reference/jak3/levels/volcano/volcano-obs2_REF.gc +++ b/test/decompiler/reference/jak3/levels/volcano/volcano-obs2_REF.gc @@ -68,11 +68,7 @@ :virtual #t :event rigid-body-object-event-handler :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (get-point-at-percent-along-path! (-> self path) (-> self rbody position) (-> self path-u) 'interp) (ja-no-eval :group! vol-lava-plat-idle-ja :num! zero) (logclear! (-> self mask) (process-mask actor-pause)) @@ -1239,7 +1235,3 @@ (go-idle self) self ) - - - - diff --git a/test/decompiler/reference/jak3/levels/volcano/volcano-obs_REF.gc b/test/decompiler/reference/jak3/levels/volcano/volcano-obs_REF.gc index 367221fc1f..df0bab4b8a 100644 --- a/test/decompiler/reference/jak3/levels/volcano/volcano-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/volcano/volcano-obs_REF.gc @@ -1132,10 +1132,7 @@ (set! (-> self stopped-up-by) (the-as handle #f)) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (let ((a1-0 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-0 from) (process->ppointer self)) diff --git a/test/decompiler/reference/jak3/levels/volcano/volcanox-obs_REF.gc b/test/decompiler/reference/jak3/levels/volcano/volcanox-obs_REF.gc index 703922746a..c79643097a 100644 --- a/test/decompiler/reference/jak3/levels/volcano/volcanox-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/volcano/volcanox-obs_REF.gc @@ -397,10 +397,7 @@ (until (process-grab? *target* #f) (suspend) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) ) ) @@ -422,10 +419,7 @@ (set! (-> self root scale z) (-> self root scale x)) (when (= (-> self root scale x) 0.0) (send-event (handle->process (-> self perm-part)) 'die) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (until (process-release? *target*) (suspend) diff --git a/test/decompiler/reference/jak3/levels/wascity/defend/was-pre-game_REF.gc b/test/decompiler/reference/jak3/levels/wascity/defend/was-pre-game_REF.gc index cd9106ec79..9712e171b1 100644 --- a/test/decompiler/reference/jak3/levels/wascity/defend/was-pre-game_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/defend/was-pre-game_REF.gc @@ -2021,10 +2021,7 @@ ) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (-> self start-delay)) - (suspend) - ) + (suspend-for (-> self start-delay) ) (go-virtual fall) ) @@ -2292,10 +2289,7 @@ (sound-play "lose-icon") (send-event (ppointer->process (-> self parent)) 'done) (set! (-> self post-hook) #f) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 0.2)) - (suspend) - ) + (suspend-for (seconds 0.2) ) ) :post (behavior () @@ -3492,7 +3486,3 @@ (set-vector! (-> self draw color-emissive) 1.0 1.0 1.0 1.0) (go-virtual idle) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/wascity/dm-flyer_REF.gc b/test/decompiler/reference/jak3/levels/wascity/dm-flyer_REF.gc index fe99ce0a9c..40a17d7735 100644 --- a/test/decompiler/reference/jak3/levels/wascity/dm-flyer_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/dm-flyer_REF.gc @@ -213,11 +213,7 @@ ) ) :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) @@ -296,11 +292,7 @@ (defstate dissipate (dm-flyer-shot) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) diff --git a/test/decompiler/reference/jak3/levels/wascity/maker-projectile_REF.gc b/test/decompiler/reference/jak3/levels/wascity/maker-projectile_REF.gc index 5c40e5ffb8..47e02ce8e9 100644 --- a/test/decompiler/reference/jak3/levels/wascity/maker-projectile_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/maker-projectile_REF.gc @@ -766,11 +766,7 @@ ) ) :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (when (-> self minimap) (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) @@ -838,11 +834,8 @@ (set! (-> v1-85 prim-core collide-with) (collide-spec)) ) 0 - (let ((gp-4 (current-time))) - (until (time-elapsed? gp-4 (seconds 3)) - (suspend) - (suspend) - ) + (suspend-for (seconds 3) + (suspend) ) ) ) diff --git a/test/decompiler/reference/jak3/levels/wascity/palace/waspala-obs_REF.gc b/test/decompiler/reference/jak3/levels/wascity/palace/waspala-obs_REF.gc index 5da0f85be4..7302e83a44 100644 --- a/test/decompiler/reference/jak3/levels/wascity/palace/waspala-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/palace/waspala-obs_REF.gc @@ -291,10 +291,7 @@ ) (let ((gp-0 27)) (set-setting! 'change-gun #t 0.0 0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) (set! (-> self gui-id) (add-process *gui-control* self (gui-channel message) (gui-action play) (-> self name) 81920.0 0) diff --git a/test/decompiler/reference/jak3/levels/wascity/tizard_REF.gc b/test/decompiler/reference/jak3/levels/wascity/tizard_REF.gc index 299343104a..76fca82e39 100644 --- a/test/decompiler/reference/jak3/levels/wascity/tizard_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/tizard_REF.gc @@ -89,11 +89,8 @@ ) :code (behavior () (when (-> self first-run?) - (let ((gp-0 (the int (* 300.0 (rand-vu-float-range 0.05 0.12)))) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 gp-0) - (suspend) + (let ((gp-0 (the int (* 300.0 (rand-vu-float-range 0.05 0.12))))) + (suspend-for gp-0 ) ) (set! (-> self path-base-u) (the float (rand-vu-int-count (-> self path curve num-cverts)))) @@ -176,11 +173,8 @@ :virtual #t :event tizard-event-handler :code (behavior () - (let ((gp-0 (the int (* 300.0 (rand-vu-float-range 1.0 2.0)))) - (s5-0 (current-time)) - ) - (until (time-elapsed? s5-0 gp-0) - (suspend) + (let ((gp-0 (the int (* 300.0 (rand-vu-float-range 1.0 2.0))))) + (suspend-for gp-0 ) ) (if (< 17294.223 (acos (vector-dot (-> self rotation-matrix fvec) (-> self path-dir)))) @@ -500,7 +494,3 @@ (set! (-> this first-run?) #t) (go (method-of-object this idle)) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/wascity/wasall-tasks_REF.gc b/test/decompiler/reference/jak3/levels/wascity/wasall-tasks_REF.gc index 1fb33ca566..46cb263fef 100644 --- a/test/decompiler/reference/jak3/levels/wascity/wasall-tasks_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/wasall-tasks_REF.gc @@ -175,10 +175,7 @@ ) (set-setting! 'fog-special-interp-targ #f f0-0 0) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 15)) - (suspend) - ) + (suspend-for (seconds 15) ) ) #f @@ -283,7 +280,7 @@ (logior! (-> this minimap-temple flags) (minimap-flag fade-out)) (set! (-> this minimap-temple) #f) ) - (bigmap-method-16 *bigmap*) + (set-map-indices! *bigmap*) (when (and (not (-> this rod-of-god)) (!= (-> *bigmap* load-index) 18) (!= (-> *bigmap* load-index) 19) @@ -611,10 +608,7 @@ ) #f (label cfg-22) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (talker-spawn-func (-> *talker-speech* 88) *entity-pool* (target-pos 0) (the-as region #f)) (send-event self 'complete) @@ -740,10 +734,7 @@ (defstate active (oasis-defense-intro-manager) :virtual #t :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (open! (-> self node-info) 'event) (talker-spawn-func (-> *talker-speech* 83) *entity-pool* (target-pos 0) (the-as region #f)) @@ -910,11 +901,7 @@ (defstate active (task-manager-lock-wasdoors) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (set-setting! 'airlock #f 0.0 0) ) :trans (behavior () @@ -1282,7 +1269,3 @@ 0 (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/wascity/wascity-turret_REF.gc b/test/decompiler/reference/jak3/levels/wascity/wascity-turret_REF.gc index 9f68318c27..1733b3d662 100644 --- a/test/decompiler/reference/jak3/levels/wascity/wascity-turret_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/wascity-turret_REF.gc @@ -726,11 +726,7 @@ (defstate shutdown (wascity-turret) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (wct-show-flut self #t) @@ -765,11 +761,7 @@ (setup-masks (-> self draw) 0 2) (set-setting! 'matrix-blend-turret-rot 'abs 5.0 0) (set-setting! 'lock-sound-camera-to-target #t 0.0 0) - (let ((t9-4 (-> (find-parent-state) enter))) - (if t9-4 - (t9-4) - ) - ) + (call-parent-state-handler enter) ) :exit (behavior () (setup-masks (-> self draw) 2 0) @@ -782,11 +774,7 @@ ) :trans (behavior () (wascity-turret-method-59 self) - (let ((t9-2 (-> (find-parent-state) trans))) - (if t9-2 - (t9-2) - ) - ) + (call-parent-state-handler trans) ) ) diff --git a/test/decompiler/reference/jak3/levels/wascity/wasdef-manager_REF.gc b/test/decompiler/reference/jak3/levels/wascity/wasdef-manager_REF.gc index 3bbc7fc02d..cf67ac9478 100644 --- a/test/decompiler/reference/jak3/levels/wascity/wasdef-manager_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/wasdef-manager_REF.gc @@ -1819,10 +1819,7 @@ (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) ) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 4)) - (suspend) - ) + (suspend-for (seconds 4) ) ) :post (behavior () @@ -2248,10 +2245,7 @@ :code (behavior () (maker-method-38 self) (set! *maker-num-visible* (+ *maker-num-visible* -1)) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 3)) - (suspend) - ) + (suspend-for (seconds 3) ) (if (nonzero? (-> self explosion-sound-id)) (set-action! diff --git a/test/decompiler/reference/jak3/levels/wascity/wasgun-manager_REF.gc b/test/decompiler/reference/jak3/levels/wascity/wasgun-manager_REF.gc index c541d3dbff..a33215d7ab 100644 --- a/test/decompiler/reference/jak3/levels/wascity/wasgun-manager_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/wasgun-manager_REF.gc @@ -1369,10 +1369,7 @@ (logior! (-> self minimap flags) (minimap-flag fade-out)) (set! (-> self minimap) #f) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (sound-play "point-missed" :position (wascity-turret-gun-pos)) (let ((v1-49 (handle->process (-> self mgr)))) diff --git a/test/decompiler/reference/jak3/levels/wascity/wasstadium/nst-tasks_REF.gc b/test/decompiler/reference/jak3/levels/wascity/wasstadium/nst-tasks_REF.gc index 0cf4e62f92..5a5c8c67f8 100644 --- a/test/decompiler/reference/jak3/levels/wascity/wasstadium/nst-tasks_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/wasstadium/nst-tasks_REF.gc @@ -304,27 +304,19 @@ ) :code (behavior () (local-vars (a0-15 vector) (a1-7 vector) (gp-6 (function vector vector float))) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.1)) - (suspend) - ) + (suspend-for (seconds 0.1) ) (when (not (task-node-closed? (game-task-node nest-eggs-wall))) (until (level-get *level* 'wasdoors) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 1)) - (format *stdebug* "wait for player to get to garage~%") - (b! (task-node-closed? (game-task-node nest-eggs-wall)) cfg-34 :delay (nop!)) - (suspend) - ) + (suspend-for (seconds 1) + (format *stdebug* "wait for player to get to garage~%") + (b! (task-node-closed? (game-task-node nest-eggs-wall)) cfg-34 :delay (nop!)) + (empty-form) ) ) (setup-scorpion) (task-node-close! (game-task-node nest-eggs-get-to-scorpion) 'event) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) (let ((v1-20 (rand-vu-int-range 0 1))) (b! (nonzero? v1-20) cfg-11 :delay (empty-form)) @@ -336,10 +328,7 @@ ) ) (label cfg-13) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 4)) - (suspend) - ) + (suspend-for (seconds 4) ) (until (< (gp-6 a0-15 a1-7) 491520.0) (format *stdebug* "wait for player to drive to eggwall~%") @@ -366,19 +355,13 @@ (label cfg-25) (b! (handle->process (the-as handle gp-8)) cfg-24 :delay (nop!)) ) - (let ((gp-9 (current-time))) - (until (time-elapsed? gp-9 (seconds 0.5)) - (suspend) - ) + (suspend-for (seconds 0.5) ) ) (label cfg-34) (setup-scorpion) (set-setting! 'music 'nesteggs 0.0 0) - (let ((gp-10 (current-time))) - (until (time-elapsed? gp-10 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (let ((v1-57 (rand-vu-int-range 0 6))) (cond @@ -423,10 +406,7 @@ ) :code (behavior () (task-node-close! (-> self info final-node) 'event) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 0.6)) - (suspend) - ) + (suspend-for (seconds 0.6) ) (let ((v1-6 (rand-vu-int-range 0 3))) (cond @@ -444,17 +424,10 @@ ) ) ) - (let ((gp-5 (current-time))) - (until (time-elapsed? gp-5 (seconds 3)) - (format *stdebug* "task-manager-nest-cocoons: done!~%") - (suspend) - ) - ) - (let ((t9-12 (-> (find-parent-state) code))) - (if t9-12 - ((the-as (function none) t9-12)) - ) + (suspend-for (seconds 3) + (format *stdebug* "task-manager-nest-cocoons: done!~%") ) + (call-parent-state-handler code) ) ) @@ -523,7 +496,3 @@ (spawn-dust-storm-randomizer this) (none) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/wascity/wasstadium/wasstadb-obs_REF.gc b/test/decompiler/reference/jak3/levels/wascity/wasstadium/wasstadb-obs_REF.gc index 4d80ee3931..0b2f333689 100644 --- a/test/decompiler/reference/jak3/levels/wascity/wasstadium/wasstadb-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/wasstadium/wasstadb-obs_REF.gc @@ -1222,10 +1222,7 @@ ) ) :code (behavior () - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (set! *arena-trainer-checkpoint-valid* #t) (copy-string<-string (-> *training-fail* fail continue) "wasstada-checkpoint-3") @@ -1471,10 +1468,7 @@ ) (suspend) (ja-channel-set! 0) - (let ((gp-0 (current-time))) - (until (time-elapsed? gp-0 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (send-event self 'death-end) (while (-> self child) @@ -1576,7 +1570,3 @@ (logclear! (-> this mask) (process-mask actor-pause)) (go (method-of-object this idle)) ) - - - - diff --git a/test/decompiler/reference/jak3/levels/wascity/wasstadium/wasstadc-obs_REF.gc b/test/decompiler/reference/jak3/levels/wascity/wasstadium/wasstadc-obs_REF.gc index c4efc9eb70..fd701b5880 100644 --- a/test/decompiler/reference/jak3/levels/wascity/wasstadium/wasstadc-obs_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/wasstadium/wasstadc-obs_REF.gc @@ -34,18 +34,10 @@ (set! (-> gp-0 map-icon) (the-as uint 13)) (set! (-> self arrow-h) (process->handle (task-arrow-spawn gp-0 self))) ) - (let ((t9-3 (-> (find-parent-state) enter))) - (if t9-3 - (t9-3) - ) - ) + (call-parent-state-handler enter) ) :trans (behavior () - (let ((t9-1 (-> (find-parent-state) trans))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler trans) (when (-> self arrow-h) (let ((gp-0 (-> self arrow-h process 0))) (when (or (< (vector-vector-distance (-> (the-as process-drawable gp-0) root trans) (target-pos 0)) 12288.0) @@ -398,10 +390,7 @@ (suspend) (ja :num! (seek!)) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 1)) - (suspend) - ) + (suspend-for (seconds 1) ) (ja-no-eval :group! wstd-fight-house-a-open-ja :num! (seek! 0.0) :frame-num 5.0) (until (ja-done? 0) @@ -2356,10 +2345,7 @@ ) (let ((gp-1 (-> *game-info* gun-type))) (set-setting! 'change-gun #t 0.0 0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) (set! (-> self gui-id) (add-process *gui-control* self (gui-channel message) (gui-action play) (-> self name) 81920.0 0) @@ -2375,11 +2361,8 @@ (send-event (-> v1-33 extra process) 'off) ) ) - (let ((gp-2 (current-time))) - (until (time-elapsed? gp-2 (seconds 2)) - (print-text self (-> self text-id)) - (suspend) - ) + (suspend-for (seconds 2) + (print-text self (-> self text-id)) ) (send-event self 'complete) (until #f @@ -2452,10 +2435,7 @@ ) (let ((gp-2 32)) (set-setting! 'change-gun #t 0.0 0) - (let ((s5-0 (current-time))) - (until (time-elapsed? s5-0 (seconds 5)) - (suspend) - ) + (suspend-for (seconds 5) ) (set! (-> self gui-id) (add-process *gui-control* self (gui-channel message) (gui-action play) (-> self name) 81920.0 0) @@ -2470,11 +2450,8 @@ (send-event (-> v1-38 extra process) 'off) ) ) - (let ((gp-3 (current-time))) - (until (time-elapsed? gp-3 (seconds 2)) - (print-text self (-> self text-id)) - (suspend) - ) + (suspend-for (seconds 2) + (print-text self (-> self text-id)) ) (send-event self 'complete) (until #f @@ -2698,10 +2675,7 @@ (send-event (handle->process (-> self arrow-h)) 'leave) (send-event *target* 'end-mode 'darkjak) (send-event *target* 'end-mode 'grab) - (let ((gp-1 (current-time))) - (until (time-elapsed? gp-1 (seconds 2)) - (suspend) - ) + (suspend-for (seconds 2) ) (go-virtual complete) ) diff --git a/test/decompiler/reference/jak3/levels/wascity/wlander-male_REF.gc b/test/decompiler/reference/jak3/levels/wascity/wlander-male_REF.gc index ced7600953..28a6b37cf6 100644 --- a/test/decompiler/reference/jak3/levels/wascity/wlander-male_REF.gc +++ b/test/decompiler/reference/jak3/levels/wascity/wlander-male_REF.gc @@ -267,11 +267,7 @@ (defstate knocked-recover (wlander) :virtual #t :enter (behavior () - (let ((t9-1 (-> (find-parent-state) enter))) - (if t9-1 - (t9-1) - ) - ) + (call-parent-state-handler enter) (nav-enemy-method-184 self) (let ((a0-2 (-> self nav state)) (v1-5 *null-vector*) @@ -2859,7 +2855,3 @@ 0 (none) ) - - - - diff --git a/third-party/discord-rpc/.gitignore b/third-party/discord-rpc/.gitignore index 223c07d706..8b9c5b6729 100644 --- a/third-party/discord-rpc/.gitignore +++ b/third-party/discord-rpc/.gitignore @@ -1,5 +1,4 @@ /build*/ /.vscode/ -/thirdparty/ .vs/ .DS_Store \ No newline at end of file diff --git a/third-party/discord-rpc/CMakeLists.txt b/third-party/discord-rpc/CMakeLists.txt index d11bfed5b2..9c1e1392f2 100644 --- a/third-party/discord-rpc/CMakeLists.txt +++ b/third-party/discord-rpc/CMakeLists.txt @@ -27,22 +27,27 @@ if (CLANG_FORMAT_CMD) endif(CLANG_FORMAT_CMD) # thirdparty stuff -execute_process( - COMMAND mkdir ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty - ERROR_QUIET -) - -find_file(RAPIDJSONTEST NAMES rapidjson rapidjson-1.1.0 PATHS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty CMAKE_FIND_ROOT_PATH_BOTH) -if (NOT RAPIDJSONTEST) - message("no rapidjson, download") - set(RJ_TAR_FILE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/v1.1.0.tar.gz) - file(DOWNLOAD https://github.com/miloyip/rapidjson/archive/v1.1.0.tar.gz ${RJ_TAR_FILE}) - execute_process( - COMMAND ${CMAKE_COMMAND} -E tar xzf ${RJ_TAR_FILE} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty - ) - file(REMOVE ${RJ_TAR_FILE}) -endif(NOT RAPIDJSONTEST) +# execute_process( +# COMMAND mkdir ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty +# ERROR_QUIET +# ) + +# NOTE: Rapidjson has a bug that was fixed https://github.com/Tencent/rapidjson/pull/719 +# and is starting to cause problems in some environments +# +# But there is no way that I'm going to just blindly consume 8 years of updates...so commit rapidjson +# with the above linked fix. +# find_file(RAPIDJSONTEST NAMES rapidjson rapidjson-1.1.0 PATHS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty CMAKE_FIND_ROOT_PATH_BOTH) +# if (NOT RAPIDJSONTEST) +# message("no rapidjson, download") +# set(RJ_TAR_FILE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/v1.1.0.tar.gz) +# file(DOWNLOAD https://github.com/miloyip/rapidjson/archive/v1.1.0.tar.gz ${RJ_TAR_FILE}) +# execute_process( +# COMMAND ${CMAKE_COMMAND} -E tar xzf ${RJ_TAR_FILE} +# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty +# ) +# file(REMOVE ${RJ_TAR_FILE}) +# endif(NOT RAPIDJSONTEST) find_file(RAPIDJSON NAMES rapidjson rapidjson-1.1.0 PATHS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty CMAKE_FIND_ROOT_PATH_BOTH) diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/CMakeLists.txt b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/CMakeLists.txt new file mode 100644 index 0000000000..ceda71b1b6 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/CMakeLists.txt @@ -0,0 +1,173 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +if(POLICY CMP0025) + # detect Apple's Clang + cmake_policy(SET CMP0025 NEW) +endif() +if(POLICY CMP0054) + cmake_policy(SET CMP0054 NEW) +endif() + +SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules) + +PROJECT(RapidJSON CXX) + +set(LIB_MAJOR_VERSION "1") +set(LIB_MINOR_VERSION "1") +set(LIB_PATCH_VERSION "0") +set(LIB_VERSION_STRING "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_PATCH_VERSION}") + +# compile in release with debug info mode by default +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) +endif() + +# Build all binaries in a separate directory +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +option(RAPIDJSON_BUILD_DOC "Build rapidjson documentation." ON) +option(RAPIDJSON_BUILD_EXAMPLES "Build rapidjson examples." ON) +option(RAPIDJSON_BUILD_TESTS "Build rapidjson perftests and unittests." ON) +option(RAPIDJSON_BUILD_THIRDPARTY_GTEST + "Use gtest installation in `thirdparty/gtest` by default if available" OFF) + +option(RAPIDJSON_BUILD_CXX11 "Build rapidjson with C++11 (gcc/clang)" ON) + +option(RAPIDJSON_BUILD_ASAN "Build rapidjson with address sanitizer (gcc/clang)" OFF) +option(RAPIDJSON_BUILD_UBSAN "Build rapidjson with undefined behavior sanitizer (gcc/clang)" OFF) + +option(RAPIDJSON_HAS_STDSTRING "" OFF) +if(RAPIDJSON_HAS_STDSTRING) + add_definitions(-DRAPIDJSON_HAS_STDSTRING) +endif() + +find_program(CCACHE_FOUND ccache) +if(CCACHE_FOUND) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments -fcolor-diagnostics") + endif() +endif(CCACHE_FOUND) + +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -Wall -Wextra -Werror") + if (RAPIDJSON_BUILD_CXX11) + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7.0") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + endif() + endif() + if (RAPIDJSON_BUILD_ASAN) + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.8.0") + message(FATAL_ERROR "GCC < 4.8 doesn't support the address sanitizer") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + endif() + endif() + if (RAPIDJSON_BUILD_UBSAN) + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9.0") + message(FATAL_ERROR "GCC < 4.9 doesn't support the undefined behavior sanitizer") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined") + endif() + endif() +elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -Wall -Wextra -Werror -Wno-missing-field-initializers") + if (RAPIDJSON_BUILD_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + endif() + if (RAPIDJSON_BUILD_ASAN) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + endif() + if (RAPIDJSON_BUILD_UBSAN) + if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined") + endif() + endif() +elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + add_definitions(-D_CRT_SECURE_NO_WARNINGS=1) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") +endif() + +#add extra search paths for libraries and includes +SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The directory the headers are installed in") +SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE STRING "Directory where lib will install") +SET(DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/doc/${PROJECT_NAME}" CACHE PATH "Path to the documentation") + +IF(UNIX OR CYGWIN) + SET(_CMAKE_INSTALL_DIR "${LIB_INSTALL_DIR}/cmake/${PROJECT_NAME}") +ELSEIF(WIN32) + SET(_CMAKE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/cmake") +ENDIF() +SET(CMAKE_INSTALL_DIR "${_CMAKE_INSTALL_DIR}" CACHE PATH "The directory cmake fiels are installed in") + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) + +if(RAPIDJSON_BUILD_DOC) + add_subdirectory(doc) +endif() + +add_custom_target(travis_doc) +add_custom_command(TARGET travis_doc + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/travis-doxygen.sh) + +if(RAPIDJSON_BUILD_EXAMPLES) + add_subdirectory(example) +endif() + +if(RAPIDJSON_BUILD_TESTS) + if(MSVC11) + # required for VS2012 due to missing support for variadic templates + add_definitions(-D_VARIADIC_MAX=10) + endif(MSVC11) + add_subdirectory(test) + include(CTest) +endif() + +# pkg-config +IF (UNIX OR CYGWIN) + CONFIGURE_FILE (${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc.in + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc + @ONLY) + INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc + DESTINATION "${LIB_INSTALL_DIR}/pkgconfig" + COMPONENT pkgconfig) +ENDIF() + +install(FILES readme.md + DESTINATION "${DOC_INSTALL_DIR}" + COMPONENT doc) + +install(DIRECTORY include/rapidjson + DESTINATION "${INCLUDE_INSTALL_DIR}" + COMPONENT dev) + +install(DIRECTORY example/ + DESTINATION "${DOC_INSTALL_DIR}/examples" + COMPONENT examples + # Following patterns are for excluding the intermediate/object files + # from an install of in-source CMake build. + PATTERN "CMakeFiles" EXCLUDE + PATTERN "Makefile" EXCLUDE + PATTERN "cmake_install.cmake" EXCLUDE) + +# Provide config and version files to be used by other applications +# =============================== + +export(PACKAGE ${PROJECT_NAME}) + +# cmake-modules +CONFIGURE_FILE(${PROJECT_NAME}Config.cmake.in + ${PROJECT_NAME}Config.cmake + @ONLY) +CONFIGURE_FILE(${PROJECT_NAME}ConfigVersion.cmake.in + ${PROJECT_NAME}ConfigVersion.cmake + @ONLY) +INSTALL(FILES + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + DESTINATION "${CMAKE_INSTALL_DIR}" + COMPONENT dev) diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/CMakeModules/FindGTestSrc.cmake b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/CMakeModules/FindGTestSrc.cmake new file mode 100644 index 0000000000..f3cb8c9908 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/CMakeModules/FindGTestSrc.cmake @@ -0,0 +1,30 @@ + +SET(GTEST_SEARCH_PATH + "${GTEST_SOURCE_DIR}" + "${CMAKE_CURRENT_LIST_DIR}/../thirdparty/gtest/googletest") + +IF(UNIX) + IF(RAPIDJSON_BUILD_THIRDPARTY_GTEST) + LIST(APPEND GTEST_SEARCH_PATH "/usr/src/gtest") + ELSE() + LIST(INSERT GTEST_SEARCH_PATH 1 "/usr/src/gtest") + ENDIF() +ENDIF() + +FIND_PATH(GTEST_SOURCE_DIR + NAMES CMakeLists.txt src/gtest_main.cc + PATHS ${GTEST_SEARCH_PATH}) + + +# Debian installs gtest include directory in /usr/include, thus need to look +# for include directory separately from source directory. +FIND_PATH(GTEST_INCLUDE_DIR + NAMES gtest/gtest.h + PATH_SUFFIXES include + HINTS ${GTEST_SOURCE_DIR} + PATHS ${GTEST_SEARCH_PATH}) + +INCLUDE(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GTestSrc DEFAULT_MSG + GTEST_SOURCE_DIR + GTEST_INCLUDE_DIR) diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/glossary.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/glossary.json new file mode 100644 index 0000000000..d5ca56d195 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/glossary.json @@ -0,0 +1,22 @@ +{ + "glossary": { + "title": "example glossary", + "GlossDiv": { + "title": "S", + "GlossList": { + "GlossEntry": { + "ID": "SGML", + "SortAs": "SGML", + "GlossTerm": "Standard Generalized Markup Language", + "Acronym": "SGML", + "Abbrev": "ISO 8879:1986", + "GlossDef": { + "para": "A meta-markup language, used to create markup languages such as DocBook.", + "GlossSeeAlso": ["GML", "XML"] + }, + "GlossSee": "markup" + } + } + } + } +} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/menu.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/menu.json new file mode 100644 index 0000000000..acdf930ea5 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/menu.json @@ -0,0 +1,27 @@ +{"menu": { + "header": "SVG Viewer", + "items": [ + {"id": "Open"}, + {"id": "OpenNew", "label": "Open New"}, + null, + {"id": "ZoomIn", "label": "Zoom In"}, + {"id": "ZoomOut", "label": "Zoom Out"}, + {"id": "OriginalView", "label": "Original View"}, + null, + {"id": "Quality"}, + {"id": "Pause"}, + {"id": "Mute"}, + null, + {"id": "Find", "label": "Find..."}, + {"id": "FindAgain", "label": "Find Again"}, + {"id": "Copy"}, + {"id": "CopyAgain", "label": "Copy Again"}, + {"id": "CopySVG", "label": "Copy SVG"}, + {"id": "ViewSVG", "label": "View SVG"}, + {"id": "ViewSource", "label": "View Source"}, + {"id": "SaveAs", "label": "Save As"}, + null, + {"id": "Help"}, + {"id": "About", "label": "About Adobe CVG Viewer..."} + ] +}} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/readme.txt b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/readme.txt new file mode 100644 index 0000000000..c53bfb8b72 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/readme.txt @@ -0,0 +1 @@ +sample.json is obtained from http://code.google.com/p/json-test-suite/downloads/detail?name=sample.zip diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/sample.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/sample.json new file mode 100644 index 0000000000..30930e765d --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/sample.json @@ -0,0 +1,3315 @@ +{ + "a": { + "6U閆崬밺뀫颒myj츥휘:$薈mY햚#rz飏+玭V㭢뾿愴YꖚX亥ᮉ푊\u0006垡㐭룝\"厓ᔧḅ^Sqpv媫\"⤽걒\"˽Ἆ?ꇆ䬔未tv{DV鯀Tἆl凸g\\㈭ĭ즿UH㽤": null, + "b茤z\\.N": [[ + "ZL:ᅣዎ*Y|猫劁櫕荾Oj为1糕쪥泏S룂w࡛Ᏺ⸥蚙)", + { + "\"䬰ỐwD捾V`邀⠕VD㺝sH6[칑.:醥葹*뻵倻aD\"": true, + "e浱up蔽Cr෠JK軵xCʨ<뜡癙Y獩ケ齈X/螗唻?<蘡+뷄㩤쳖3偑犾&\\첊xz坍崦ݻ鍴\"嵥B3㰃詤豺嚼aqJ⑆∥韼@\u000b㢊\u0015L臯.샥": false, + "l?Ǩ喳e6㔡$M꼄I,(3᝝縢,䊀疅뉲B㴔傳䂴\u0088㮰钘ꜵ!ᅛ韽>": -5514085325291784739, + "o㮚?\"춛㵉<\/﬊ࠃ䃪䝣wp6ἀ䱄[s*S嬈貒pᛥ㰉'돀": [{ + "(QP윤懊FI<ꃣ『䕷[\"珒嶮?%Ḭ壍಻䇟0荤!藲끹bd浶tl\u2049#쯀@僞": {"i妾8홫": { + ",M맃䞛K5nAㆴVN㒊햬$n꩑&ꎝ椞阫?/ṏ세뉪1x쥼㻤㪙`\"$쟒薟B煌܀쨝ଢ଼2掳7㙟鴙X婢\u0002": "Vዉ菈᧷⦌kﮞఈnz*﷜FM\"荭7ꍀ-VR<\/';䁙E9$䩉\f @s?퍪o3^衴cඎ䧪aK鼟q䆨c{䳠5mᒲՙ蘹ᮩ": { + "F㲷JGo⯍P덵x뒳p䘧☔\"+ꨲ吿JfR㔹)4n紬G练Q፞!C|": true, + "p^㫮솎oc.೚A㤠??r\u000f)⾽⌲們M2.䴘䩳:⫭胃\\፾@Fᭌ\\K": false, + "蟌Tk愙潦伩": { + "a<\/@ᾛ慂侇瘎": -7271305752851720826, + "艓藬/>၄ṯ,XW~㲆w": {"E痧郶)㜓ha朗!N赻瞉駠uC\u20ad辠x퓮⣫P1ࠫLMMX'M刼唳됤": null, + "P쓫晥%k覛ዩIUᇸ滨:噐혲lMR5䋈V梗>%幽u頖\\)쟟": null, + "eg+昉~矠䧞难\b?gQ쭷筝\\eꮠNl{ಢ哭|]Mn銌╥zꖘzⱷ⭤ᮜ^": [ + -1.30142114406914976E17, + -1.7555215491128452E-19, + null, + "渾㨝ߏ牄귛r?돌?w[⚞ӻ~廩輫㼧/", + -4.5737191805302129E18, + null, + "xy࿑M[oc셒竓Ⓔx?뜓y䊦>-D켍(&&?XKkc꩖ﺸᏋ뵞K伕6ী)딀P朁yW揙?훻魢傎EG碸9類៌g踲C⟌aEX舲:z꒸许", + 3808159498143417627, + null, + {"m試\u20df1{G8&뚈h홯J<\/": { + "3ஸ厠zs#1K7:rᥞoꅔꯧ&띇鵼鞫6跜#赿5l'8{7㕳(b/j\"厢aq籀ꏚ\u0015厼稥": [ + -2226135764510113982, + true, + null, + { + "h%'맞S싅Hs&dl슾W0j鿏MםD놯L~S-㇡R쭬%": null, + "⟓咔謡칲\u0000孺ꛭx旑檉㶆?": null, + "恇I転;￸B2Y`z\\獓w,놏濐撐埵䂄)!䶢D=ഭ㴟jyY": { + "$ࡘt厛毣ൢI芁<겿骫⫦6tr惺a": [ + 6.385779736989334E-20, + false, + true, + true, + [ + -6.891946211462334E-19, + null, + { + "]-\\Ꟑ1/薓❧Ὂ\\l牑\u0007A郃)阜ᇒᓌ-塯`W峬G}SDb㬨Q臉⮻빌O鞟톴첂B㺱<ƈmu챑J㴹㷳픷Oㆩs": { + "\"◉B\"pᶉt骔J꩸ᄇᛐi╰栛K쉷㉯鐩!㈐n칍䟅難>盥y铿e୔蒏M貹ヅ8嘋퀯䉶ጥ㏢殊뻳\"絧╿ꉑ䠥?∃蓊{}㣣Gk긔H1哵峱": false, + "6.瀫cN䇮F㧺?\\椯=ڈT䘆4␘8qv": -3.5687501019676885E-19, + "Q?yऴr혴{஀䳘p惭f1ﹸ䅷䕋贲<ྃᄊ繲hq\\b|#QSTs1c-7(䵢\u2069匏絘ꯉ:l毴汞t戀oෟᵶ뮱፣-醇Jx䙬䐁햢0࣫ᡁgrㄛ": "\u0011_xM/蘇Chv;dhA5.嗀绱V爤ﰦi뵲M", + "⏑[\"ugoy^儣횎~U\\섯겜論l2jw஌yD腅̂\u0019": true, + "ⵯɇ䐲᫿࢚!㯢l샅笶戮1꣖0Xe": null, + "劅f넀識b宁焊E찓橵G!ʱ獓뭔雩괛": [{"p⹣켙[q>燣䍃㞽ᩲx:쓤삘7玑퇼0<\/q璂ᑁ[Z\\3䅵䧳\u0011㤧|妱緒C['췓Yꞟ3Z鳱雼P錻BU씧U`ᢶg蓱>.1ӧ譫'L_5V䏵Ц": [ + false, + false, + {"22䂍盥N霂얢躰e9⑩_뵜斌n@B}$괻Yᐱ@䧋V\"☒-諯cV돯ʠ": true, + "Ű螧ᔼ檍鍎땒딜qꄃH뜣<獧ूCY吓⸏>XQ㵡趌o끬k픀빯a(ܵ甏끆୯/6Nᪧ}搚ᆚ짌P牰泱鈷^d꣟#L삀\"㕹襻;k㸊\\f+": true, + "쎣\",|⫝̸阊x庿k잣v庅$鈏괎炔k쬪O_": [ + "잩AzZGz3v愠ꉈⵎ?㊱}S尳௏p\r2>췝IP䘈M)w|\u000eE", + -9222726055990423201, + null, + [ + false, + {"´킮'뮤쯽Wx讐V,6ᩪ1紲aႈ\u205czD": [ + -930994432421097536, + 3157232031581030121, + "l貚PY䃛5@䭄귻m㎮琸f": 1.0318894506812084E-19, + "࢜⩢Ш䧔1肽씮+༎ᣰ闺馺窃䕨8Mƶq腽xc(៯夐J5굄䕁Qj_훨/~価.䢵慯틠퇱豠㼇Qﵘ$DuSp(8Uญ<\/ಟ룴𥳐ݩ$": 8350772684161555590, + "ㆎQ䄾\u001bpᩭ${[諟^^骴᤮b^ㅥI┧T㉇⾞\"绦r䰂f矩'-7䡭桥Dz兔V9谶居㺍ᔊ䩯덲.\u001eL0ὅㅷ釣": [{ + "<쯬J卷^숞u࠯䌗艞R9닪g㐾볎a䂈歖意:%鐔|ﵤ|y}>;2,覂⶚啵tb*仛8乒㓶B࿠㯉戩oX 貘5V嗆렽낁߼4h䧛ꍺM空\\b꿋貼": 8478577078537189402, + "VD*|吝z~h譺aᯒ": { + "YI췢K<\/濳xNne玗rJo쾘3핰鴊\"↱AR:ࢷ\"9?\"臁說)?誚ꊏe)_D翾W?&F6J@뺾ꍰNZ醊Z쾈വH嶿?炫㷱鬰M겈᭨b,⻁鈵P䕡䀠८ⱄ홎鄣": { + "@?k2鶖㋮\"Oರ K㨇廪儲\u0017䍾J?);\b*묀㗠섳햭1MC V": null, + "UIICP!BUA`ᢈ㋸~袩㗪⾒=fB﮴l1ꡛ죘R辂여ҳ7쮡<䩲`熕8頁": 4481809488267626463, + "Y?+8먙ᚔ鋳蜩럶1㥔y璜౩`": [ + null, + 1.2850335807501874E-19, + "~V2", + 2035406654801997866, + { + "<숻1>\"": -8062468865199390827, + "M㿣E]}qwG莎Gn᝶(ꔙ\\D⬲iꇲs寢t駇S뀡ꢜ": false, + "pꝤ㎏9W%>M;-U璏f(^j1?&RB隧 忓b똊E": "#G?C8.躬ꥯ'?냪#< 渟&헿란zpo왓Kj}鷧XﻘMツb䕖;㪻", + "vE풤幉xz뱕쫥Ug㦲aH} ᣟp:鬼YᰟH3镔ᴚ斦\\鏑r*2橱G⼔F/.j": true, + "RK좬뎂a홠f*f㱉ᮍ⦋潙㨋Gu곌SGI3I뿐\\F',)t`荁蘯囯ﮉ裲뇟쥼_ገ驪▵撏ᕤV": 1.52738225997956557E18, + "^k굲䪿꠹B逤%F㱢漥O披M㽯镞竇霒i꼂焅륓\u00059=皫之눃\u2047娤閍銤唫ၕb<\/w踲䔼u솆맚,䝒ᝳ'/it": "B餹饴is権ꖪ怯ꦂẉဎt\"!凢谵⧿0\\<=(uL䷍刨쑪>俆揓Cy襸Q힆䆭涷<\/ᐱ0ɧ䗾䚹\\ኜ?ꄢᇘ`䴢{囇}᠈䴥X4퓪檄]ꥷ/3謒ሴn+g騍X", + "GgG꽬[(嫓몍6\u0004궍宩㙻/>\u0011^辍dT腪hxǑ%ꊇk,8(W⧂結P鬜O": [{ + "M㴾c>\\ᓲ\u0019V{>ꤩ혙넪㭪躂TS-痴໸闓⍵/徯O.M㏥ʷD囎⧔쁳휤T??鉬뇙=#ꢫ숣BX䭼<\/d똬졬g榿)eꨋﯪ좇첻\u001a\u0011\";~쓆BH4坋攊7힪", + "iT:L闞椕윚*滛gI≀Wਟඊ'ꢆ縺뱹鮚Nꩁ᧬蕼21줧\\䋯``⍐\\㏱鳨": 1927052677739832894, + "쮁缦腃g]礿Y㬙 fヺSɪ꾾N㞈": [ + null, + null, + { + "!t,灝Y 1䗉罵?c饃호䉂Cᐭ쒘z(즽sZG㬣sഖE4뢜㓕䏞丮Qp簍6EZឪ겛fx'ꩱQ0罣i{k锩*㤴㯞r迎jTⲤ渔m炅肳": [ + -3.3325685522591933E18, + [{"㓁5]A䢕1룥BC?Ꙍ`r룔Ⳛ䙡u伲+\u0001്o": [ + null, + 4975309147809803991, + null, + null, + {"T팘8Dﯲ稟MM☻㧚䥧/8ﻥ⥯aXLaH\"顾S☟耲ît7fS෉놁뮔/ꕼ䓈쁺4\\霶䠴ᩢ<\/t4?죵>uD5➶༆쉌럮⢀秙䘥\u20972ETR3濡恆vB? ~鸆\u0005": { + "`閖m璝㥉b뜴?Wf;?DV콜\u2020퍉౓擝宏ZMj3mJ먡-傷뱙yח㸷꥿ ໘u=M읝!5吭L4v\\?ǎ7C홫": null, + "|": false, + "~Ztᛋ䚘\\擭㗝傪W陖+㗶qᵿ蘥ᙄp%䫎)}=⠔6ᮢS湟-螾-mXH?cp": 448751162044282216, + "\u209fad놹j檋䇌ᶾ梕㉝bוּ": {"?苴ꩠD䋓帘5騱qﱖPF?☸珗顒yU ᡫcb䫎 S@㥚gꮒ쎘泴멖\\:I鮱TZ듒ᶨQ3+f7캙\"?\f풾\\o杞紟﻽M.⏎靑OP": [ + -2.6990368911551596E18, + [{"䒖@<᰿<\/⽬tTr腞&G%᳊秩蜰擻f㎳?S㵧\r*k뎾-乢겹隷j軛겷0룁鮁": {")DO0腦:춍逿:1㥨่!蛍樋2": [{ + ",ꌣf侴笾m๫ꆽ?1?U?\u0011ꌈꂇ": { + "x捗甠nVq䅦w`CD⦂惺嘴0I#vỵ} \\귂S끴D얾?Ԓj溯\"v餄a": { + "@翙c⢃趚痋i\u0015OQ⍝lq돆Y0pࢥ3쉨䜩^<8g懥0w)]䊑n洺o5쭝QL댊랖L镈Qnt⪟㒅십q헎鳒⮤眉ᔹ梠@O縠u泌ㄘb榚癸XޔFtj;iC": false, + "I&뱋゘|蓔䔕측瓯%6ᗻHW\\N1貇#?僐ᗜgh᭪o'䗈꽹Rc욏/蔳迄༝!0邔䨷푪8疩)[쭶緄㇈୧ፐ": { + "B+:ꉰ`s쾭)빼C羍A䫊pMgjdx䐝Hf9᥸W0!C樃'蘿f䫤סи\u0017Jve? 覝f둀⬣퓉Whk\"஼=չﳐ皆笁BIW虨쫓F廰饞": -642906201042308791, + "sb,XcZ<\/m㉹ ;䑷@c䵀s奤⬷7`ꘖ蕘戚?Feb#輜}p4nH⬮eKL트}": [ + "RK鳗z=袤Pf|[,u욺", + "Ẏᏻ罯뉋⺖锅젯㷻{H䰞쬙-쩓D]~\u0013O㳢gb@揶蔉|kᦂ❗!\u001ebM褐sca쨜襒y⺉룓", + null, + null, + true, + -1.650777344339075E-19, + false, + "☑lꄆs힨꤇]'uTന⌳농].1⋔괁沰\"IWഩ\u0019氜8쟇䔻;3衲恋,窌z펏喁횗?4?C넁问?ᥙ橭{稻Ⴗ_썔", + "n?]讇빽嗁}1孅9#ꭨ靶v\u0014喈)vw祔}룼쮿I", + -2.7033457331882025E18, + { + ";⚃^㱋x:饬ኡj'꧵T☽O㔬RO婎?향ᒭ搩$渣y4i;(Q>꿘e8q": "j~錘}0g;L萺*;ᕭꄮ0l潛烢5H▄쳂ꏒוֹꙶT犘≫x閦웧v", + "~揯\u2018c4職렁E~ᑅቚꈂ?nq뎤.:慹`F햘+%鉎O瀜쟏敛菮⍌浢<\/㮺紿P鳆ࠉ8I-o?#jﮨ7v3Dt赻J9": null, + "ࣝW䌈0ꍎqC逖,횅c၃swj;jJS櫍5槗OaB>D踾Y": {"㒰䵝F%?59.㍈cᕨ흕틎ḏ㋩B=9IېⓌ{:9.yw}呰ㆮ肒᎒tI㾴62\"ዃ抡C﹬B<\/촋jo朣", + [ + -7675533242647793366, + {"ᙧ呃:[㒺쳀쌡쏂H稈㢤\u001dᶗGG-{GHྻຊꡃ哸䵬;$?&d\\⥬こN圴됤挨-'ꕮ$PU%?冕눖i魁q騎Q": [ + false, + [[ + 7929823049157504248, + [[ + true, + "Z菙\u0017'eꕤ᱕l,0\\X\u001c[=雿8蠬L<\/낲긯W99g톉4ퟋb㝺\u0007劁'!麕Q궈oW:@X၎z蘻m絙璩귓죉+3柚怫tS捇蒣䝠-擶D[0=퉿8)q0ٟ", + "唉\nFA椭穒巯\\䥴䅺鿤S#b迅獘 ﶗ꬘\\?q1qN犠pX꜅^䤊⛤㢌[⬛휖岺q唻ⳡ틍\"㙙Eh@oA賑㗠y必Nꊑᗘ", + -2154220236962890773, + -3.2442003245397908E18, + "Wᄿ筠:瘫퀩?o貸q⊻(᎞KWf宛尨h^残3[U(='橄", + -7857990034281549164, + 1.44283696979059942E18, + null, + {"ꫯAw跭喀 ?_9\"Aty背F=9缉ྦྷ@;?^鞀w:uN㘢Rỏ": [ + 7.393662029337442E15, + 3564680942654233068, + [ + false, + -5253931502642112194, + "煉\\辎ೆ罍5⒭1䪁䃑s䎢:[e5}峳ﴱn騎3?腳Hyꏃ膼N潭錖,Yᝋ˜YAၓ㬠bG렣䰣:", + true, + null, + { + "⒛'P&%죮|:⫶춞": -3818336746965687085, + "钖m<\/0ݎMtF2Pk=瓰୮洽겎.": [[ + -8757574841556350607, + -3045234949333270161, + null, + { + "Ꮬr輳>⫇9hU##w@귪A\\C 鋺㘓ꖐ梒뒬묹㹻+郸嬏윤'+g<\/碴,}ꙫ>손;情d齆J䬁ຩ撛챝탹/R澡7剌tꤼ?ặ!`⏲睤\u00002똥଴⟏": null, + "\u20f2ܹe\\tAꥍư\\x当뿖렉禛;G檳ﯪS૰3~㘠#[J<}{奲 5箉⨔{놁<\/釿抋,嚠/曳m&WaOvT赋皺璑텁": [[ + false, + null, + true, + -5.7131445659795661E18, + "萭m䓪D5|3婁ఞ>蠇晼6nﴺPp禽羱DS<睓닫屚삏姿", + true, + [ + -8759747687917306831, + { + ">ⓛ\t,odKr{䘠?b퓸C嶈=DyEᙬ@ᴔ쨺芛髿UT퓻春<\/yꏸ>豚W釺N뜨^?꽴﨟5殺ᗃ翐%>퍂ဿ䄸沂Ea;A_\u0005閹殀W+窊?Ꭼd\u0013P汴G5썓揘": 4.342729067882445E-18, + "Q^즾眆@AN\u0011Kb榰냎Y#䝀ꀒᳺ'q暇睵s\"!3#I⊆畼寤@HxJ9": false, + "⿾D[)袨㇩i]웪䀤ᛰMvR<蟏㣨": {"v퇓L㪱ꖣ豛톤\\곱#kDTN": [{ + "(쾴䡣,寴ph(C\"㳶w\"憳2s馆E!n!&柄<\/0Pꈗſ?㿳Qd鵔": {"娇堰孹L錮h嵅⛤躏顒?CglN束+쨣ﺜ\\MrH": {"獞䎇둃ቲ弭팭^ꄞ踦涟XK錆쳞ឌ`;੶S炥騞ଋ褂B៎{ڒ䭷ᶼ靜pI荗虶K$": [{"◖S~躘蒉꫿輜譝Q㽙闐@ᢗ¥E榁iء5┄^B[絮跉ᰥ遙PWi3wㄾⵀDJ9!w㞣ᄎ{듒ꓓb6\\篴??c⼰鶹⟧\\鮇ꮇ": [[ + 654120831325413520, + -1.9562073916357608E-19, + { + "DC(昐衵ἡ긙갵姭|֛[t": 7.6979110359897907E18, + "J␅))嫼❳9Xfd飉j7猬ᩉ+⤻眗벎E鰉Zᄊ63zၝ69}ZᶐL崭ᦥ⡦靚⋛ꎨ~i㨃咊ꧭo䰠阀3C(": -3.5844809362512589E17, + "p꣑팱쒬ꎑ뛡Ꙩ挴恍胔&7ᔈ묒4Hd硶훐㎖zꢼ豍㿢aሃ=<\/湉鵲EӅ%$F!퍶棌孼{O駍਺geu+": ")\u001b잓kŀX쩫A밁®ڣ癦狢)扔弒p}k縕ꩋ,䃉tࣼi", + "ァF肿輸<솄G-䢹䛸ꊏl`Tqꕗ蒞a氷⸅ᴉ蠰]S/{J왲m5{9.uέ~㕚㣹u>x8U讁B덺襪盎QhVS맅킃i识{벂磄Iහ䙅xZy/抍૭Z鲁-霳V据挦ℒ": null, + "㯛|Nꐸb7ⵐb?拠O\u0014ކ?-(EꞨ4ꕷᄤYᯕOW瞺~螸\"욿ќe㺰\"'㌢ƐW\u0004瞕>0?V鷵엳": true, + "뤥G\\迋䠿[庩'꼡\u001aiᩮV쯁ᳪ䦪Ô;倱ନ뛁誈": null, + "쥹䄆䚟Q榁䎐᢭<\/2㕣p}HW蟔|䃏꿈ꚉ锳2Pb7㙑Tⅹᵅ": { + "Y?֭$>#cVBꩨ:>eL蒁務": { + "86柡0po 䏚&-捑Ћ祌<\/휃-G*㶢הּ쩍s㶟餇c걺yu꽎還5*턧簕Og婥SꝐ": null, + "a+葞h٥ࠆ裈嗫ﵢ5輙퀟ᛜ,QDﹼ⟶Y騠锪E_|x죗j侵;m蜫轘趥?븅w5+mi콛L": { + ";⯭ﱢ!买F⽍柤鶂n䵣V㫚墱2렾ELEl⣆": [ + true, + -3.6479311868339015E-18, + -7270785619461995400, + 3.334081886177621E18, + 2.581457786298155E18, + -6.605252412954115E-20, + -3.9232347037744167E-20, + { + "B6㊕.k1": null, + "ZAꄮJ鮷ᳱo갘硥鈠䠒츼": { + "ᕅ}럡}.@y陪鶁r業'援퀉x䉴ﵴl퍘):씭脴ᥞhiꃰblﲂ䡲엕8߇M㶭0燋標挝-?PCwe⾕J碻Ᾱ䬈䈥뷰憵賣뵓痬+": {"a췩v礗X⋈耓ፊf罅靮!㔽YYᣓw澍33⎔芲F|\"䜏T↮輦挑6ᓘL侘?ᅥ]덆1R௯✎餘6ꏽ<\/௨\\?q喷ꁫj~@ulq": {"嗫欆뾔Xꆹ4H㌋F嵧]ࠎ]㠖1ꞤT<$m뫏O i댳0䲝i": {"?෩?\u20cd슮|ꯆjs{?d7?eNs⢚嫥氂䡮쎱:鑵롟2hJꎒﯭ鱢3춲亄:뼣v䊭諱Yj択cVmR䩃㘬T\"N홝*ै%x^F\\_s9보zz4淗?q": [ + null, + "?", + 2941869570821073737, + "{5{殇0䝾g6밖퍋臩綹R$䖭j紋釰7sXI繳漪행y", + false, + "aH磂?뛡#惇d婅?Fe,쐘+늵䍘\"3r瘆唊勐j⳧࠴ꇓ<\/唕윈x⬌讣䋵%拗ᛆⰿ妴᝔M2㳗必꧂淲?ゥ젯檢<8끒MidX䏒3᳻Q▮佐UT|⤪봦靏⊏", + [[{ + "颉(&뜸귙{y^\"P퟉춝Ჟ䮭D顡9=?}Y誱<$b뱣RvO8cH煉@tk~4ǂ⤧⩝屋SS;J{vV#剤餓ᯅc?#a6D,s": [ + -7.8781018564821536E16, + true, + [ + -2.28770899315832371E18, + false, + -1.0863912140143876E-20, + -6282721572097446995, + 6767121921199223078, + -2545487755405567831, + false, + null, + -9065970397975641765, + [ + -5.928721243413937E-20, + {"6촊\u001a홯kB0w撨燠룉{绎6⳹!턍贑y▾鱧ժ[;7ᨷ∀*땒䪮1x霆Hᩭ☔\"r䝐7毟ᝰr惃3ꉭE+>僒澐": [ + "Ta쎩aƝt쵯ⰪVb", + [ + -5222472249213580702, + null, + -2851641861541559595, + null, + 4808804630502809099, + 5657671602244269874, + "5犲﨣4mᥣ?yf젫꾯|䋬잁$`Iⳉﴷ扳兝,'c", + false, + [ + null, + { + "DyUIN쎾M仼惀⮥裎岶泭lh扠\u001e礼.tEC癯튻@_Qd4c5S熯A<\/\6U윲蹴Q=%푫汹\\\u20614b[௒C⒥Xe⊇囙b,服3ss땊뢍i~逇PA쇸1": -2.63273619193485312E17, + "Mq꺋貘k휕=nK硍뫞輩>㾆~἞ࡹ긐榵l⋙Hw뮢帋M엳뢯v⅃^": 1877913476688465125, + "ᶴ뻗`~筗免⚽টW˃⽝b犳䓺Iz篤p;乨A\u20ef쩏?疊m㝀컩뫡b탔鄃ᾈV(遢珳=뎲ିeF仢䆡谨8t0醄7㭧瘵⻰컆r厡궥d)a阄፷Ed&c﯄伮1p": null, + "⯁w4曢\"(欷輡": "\"M᭫]䣒頳B\\燧ࠃN㡇j姈g⊸⺌忉ꡥF矉স%^", + "㣡Oᄦ昵⫮Y祎S쐐級㭻撥>{I$": -378474210562741663, + "䛒掷留Q%쓗1*1J*끓헩ᦢ﫫哉쩧EↅIcꅡ\\?ⴊl귛顮4": false, + "寔愆샠5]䗄IH贈=d﯊/偶?ॊn%晥D視N򗘈'᫂⚦|X쵩넽z질tskxDQ莮Aoﱻ뛓": true, + "钣xp?&\u001e侉/y䴼~?U篔蘚缣/I畚?Q绊": -3034854258736382234, + "꺲໣眀)⿷J暘pИfAV삕쳭Nꯗ4々'唄ⶑ伻㷯騑倭D*Ok꧁3b␽_<\/챣Xm톰ၕ䆄`*fl㭀暮滠毡?": [ + "D男p`V뙸擨忝븪9c麺`淂⢦Yw⡢+kzܖ\fY1䬡H歁)벾Z♤溊-혰셢?1<-\u0005;搢Tᐁle\\ᛵߓﭩ榩訝-xJ;巡8깊蠝ﻓU$K": { + "Vꕡ諅搓W=斸s︪vﲜ츧$)iꡟ싉e寳?ጭムVથ嵬i楝Fg<\/Z|៪ꩆ-5'@ꃱ80!燱R쇤t糳]罛逇dṌ֣XHiͦ{": true, + "Ya矲C멗Q9膲墅携휻c\\딶G甔<\/.齵휴": -1.1456247877031811E-19, + "z#.OO￝J": -8263224695871959017, + "崍_3夼ᮟ1F븍뽯ᦓ鴭V豈Ь": [{ + "N蒬74": null, + "yuB?厅vK笗!ᔸcXQ旦컶P-녫mᄉ麟_": "1R@ 톘xa_|﩯遘s槞d!d껀筤⬫薐焵먑D{\\6k共倌☀G~AS_D\"딟쬚뮥馲렓쓠攥WTMܭ8nX㩴䕅檹E\u0007ﭨN 2 ℆涐ꥏ꠵3▙玽|됨_\u2048", + "恐A C䧩G": {":M큣5e들\\ꍀ恼ᔄ靸|I﨏$)n": { + "|U䬫㟯SKV6ꛤ㗮\bn봻䲄fXT:㾯쳤'笓0b/ೢC쳖?2浓uO.䰴": "ཐ꼋e?``,ᚇ慐^8ꜙNM䂱\u0001IᖙꝧM'vKdꌊH牮r\\O@䊷ᓵ쀆(fy聻i툺\"?<\/峧ࣞ⓺ᤤ쵒߯ꎺ騬?)刦\u2072l慪y꺜ﲖTj+u", + "뽫hh䈵w>1ⲏ쐭V[ⅎ\\헑벑F_㖝⠗㫇h恽;῝汰ᱼ瀖J옆9RR셏vsZ柺鶶툤r뢱橾/ꉇ囦FGm\"謗ꉦ⨶쒿⥡%]鵩#ᖣ_蹎 u5|祥?O", + null, + 2.0150326776036215E-19, + null, + true, + false, + true, + {"\fa᭶P捤WWc᠟f뚉ᬏ퓗ⳀW睹5:HXH=q7x찙X$)모r뚥ᆟ!Jﳸf": [ + -2995806398034583407, + [ + 6441377066589744683, + "Mﶒ醹i)Gἦ廃s6몞 KJ౹礎VZ螺费힀\u0000冺업{谥'꡾뱻:.ꘘ굄奉攼Di᷑K鶲y繈욊阓v㻘}枭캗e矮1c?휐\"4\u0005厑莔뀾墓낝⽴洗ṹ䇃糞@b1\u0016즽Y轹", + { + "1⽕⌰鉟픏M㤭n⧴ỼD#%鐘⊯쿼稁븣몐紧ᅇ㓕ᛖcw嬀~ഌ㖓(0r⧦Q䑕髍ര铂㓻R儮\"@ꇱm❈௿᦯頌8}㿹犴?xn잆꥽R": 2.07321075750427366E18, + "˳b18㗈䃟柵Z曆VTAu7+㛂cb0﯑Wp執<\/臋뭡뚋刼틮荋벲TLP预庰܈G\\O@VD'鱃#乖끺*鑪ꬳ?Mޞdﭹ{␇圯쇜㼞顄︖Y홡g": [{ + "0a,FZ": true, + "2z̬蝣ꧦ驸\u0006L↛Ḣ4๚뿀'?lcwᄧ㐮!蓚䃦-|7.飑挴.樵*+1ﮊ\u0010ꛌ%貨啺/JdM:똍!FBe?鰴㨗0O财I藻ʔWA᫓G쳛u`<\/I": [{ + "$τ5V鴐a뾆両環iZp頻යn븃v": -4869131188151215571, + "*즢[⦃b礞R◚nΰꕢH=귰燙[yc誘g䆌?ଜ臛": { + "洤湌鲒)⟻\\䥳va}PeAMnN[": "㐳ɪ/(軆lZR,Cp殍ȮN啷\"3B婴?i=r$펽ᤐ쀸", + "阄R4㒿㯔ڀ69ZᲦ2癁핌噗P崜#\\-쭍袛&鐑/$4童V꩑_ZHA澢fZ3": {"x;P{긳:G閉:9?活H": [ + "繺漮6?z犞焃슳\">ỏ[Ⳛ䌜녏䂹>聵⼶煜Y桥[泥뚩MvK$4jtロ", + "E#갶霠좭㦻ୗ먵F+䪀o蝒ba쮎4X㣵 h", + -335836610224228782, + null, + null, + [ + "r1᫩0>danjY짿bs{", + [ + -9.594464059325631E-23, + 1.0456894622831624E-20, + null, + 5.803973284253454E-20, + -8141787905188892123, + true, + -4735305442504973382, + 9.513150514479281E-20, + "7넳$螔忷㶪}䪪l짴\u0007鹁P鰚HF銏ZJﳴ/⍎1ᷓ忉睇ᜋ쓈x뵠m䷐窥Ꮤ^\u0019ᶌ偭#ヂt☆၃pᎍ臶䟱5$䰵&๵分숝]䝈뉍♂坎\u0011<>", + "C蒑貑藁lﰰ}X喇몛;t밿O7/᯹f\u0015kI嘦<ዴ㟮ᗎZ`GWퟩ瑹࡮ᅴB꿊칈??R校s脚", + { + "9珵戬+AU^洘拻ቒy柭床'粙XG鞕᠜繀伪%]hC,$輙?Ut乖Qm떚W8઼}~q⠪rU䤶CQ痗ig@#≲t샌f㈥酧l;y闥ZH斦e⸬]j⸗?ঢ拻퀆滌": null, + "畯}㧢J罚帐VX㨑>1ꢶkT⿄蘥㝑o|<嗸層沈挄GEOM@-䞚䧰$만峬輏䠱V✩5宸-揂D'㗪yP掶7b⠟J㕻SfP?d}v㼂Ꮕ'猘": { + "陓y잀v>╪": null, + "鬿L+7:됑Y=焠U;킻䯌잫!韎ஔ\f": { + "駫WmGጶ": { + "\\~m6狩K": -2586304199791962143, + "ႜࠀ%͑l⿅D.瑢Dk%0紪dḨTI픸%뗜☓s榗኉\"?V籄7w髄♲쟗翛歂E䤓皹t ?)ᄟ鬲鐜6C": { + "_췤a圷1\u000eB-XOy缿請∎$`쳌eZ~杁튻/蜞`塣৙\"⪰\"沒l}蕌\\롃荫氌.望wZ|o!)Hn獝qg}": null, + "kOSܧ䖨钨:಼鉝ꭝO醧S`십`ꓭ쭁ﯢN&Et㺪馻㍢ⅳ㢺崡ຊ蜚锫\\%ahx켨|ż劻ꎄ㢄쐟A躊᰹p譞綨Ir쿯\u0016ﵚOd럂*僨郀N*b㕷63z": { + ":L5r+T㡲": [{ + "VK泓돲ᮙRy㓤➙Ⱗ38oi}LJቨ7Ó㹡৘*q)1豢⛃e᫛뙪壥镇枝7G藯g㨛oI䄽 孂L缊ꋕ'EN`": -2148138481412096818, + "`⛝ᘑ$(खꊲ⤖ᄁꤒ䦦3=)]Y㢌跨NĴ驳줟秠++d孳>8ᎊ떩EꡣSv룃 쯫أ?#E|᭙㎐?zv:5祉^⋑V": [ + -1.4691944435285607E-19, + 3.4128661569395795E17, + "㐃촗^G9佭龶n募8R厞eEw⺡_ㆱ%⼨D뉄퉠2ꩵᛅⳍ搿L팹Lවn=\"慉념ᛮy>!`g!풲晴[/;?[v겁軇}⤳⤁핏∌T㽲R홓遉㓥", + "愰_⮹T䓒妒閤둥?0aB@㈧g焻-#~跬x<\/舁P݄ꐡ=\\׳P\u0015jᳪᢁq;㯏l%᭗;砢觨▝,謁ꍰGy?躤O黩퍋Y㒝a擯\n7覌똟_䔡]fJ晋IAS", + 4367930106786121250, + -4.9421193149720582E17, + null, + { + ";ᄌ똾柉곟ⰺKpፇ䱻ฺ䖝{o~h!eꁿ઻욄ښ\u0002y?xUd\u207c悜ꌭ": [ + 1.6010824122815255E-19, + [ + "宨︩9앉檥pr쇷?WxLb", + "氇9】J玚\u000f옛呲~ 輠1D嬛,*mW3?n휂糊γ虻*ᴫ꾠?q凐趗Ko↦GT铮", + "㶢ថmO㍔k'诔栀Z蛟}GZ钹D", + false, + -6.366995517736813E-20, + -4894479530745302899, + null, + "V%᫡II璅䅛䓎풹ﱢ/pU9se되뛞x梔~C)䨧䩻蜺(g㘚R?/Ự[忓C뾠ࢤc왈邠买?嫥挤풜隊枕", + ",v碍喔㌲쟚蔚톬៓ꭶ", + 3.9625444752577524E-19, + null, + [ + "kO8란뿒䱕馔b臻⍟隨\"㜮鲣Yq5m퐔K#ꢘug㼈ᝦ=P^6탲@䧔%$CqSw铜랊0&m⟭<\/a逎ym\u0013vᯗ": true, + "洫`|XN뤮\u0018詞=紩鴘_sX)㯅鿻Ố싹": 7.168252736947373E-20, + "ꛊ饤ﴏ袁(逊+~⽫얢鈮艬O힉7D筗S곯w操I斞᠈븘蓷x": [[[[ + -7.3136069426336952E18, + -2.13572396712722688E18, + { + "硢3㇩R:o칢行E<=\u0018ၬYuH!\u00044U%卝炼2>\u001eSi$⓷ꒈ'렢gᙫ番ꯒ㛹럥嶀澈v;葷鄕x蓎\\惩+稘UEᖸﳊ㊈壋N嫿⏾挎,袯苷ኢ\\x|3c": 7540762493381776411, + "?!*^ᢏ窯?\u0001ڔꙃw虜돳FgJ?&⨫*uo籤:?}ꃹ=ٴ惨瓜Z媊@ત戹㔏똩Ԛ耦Wt轁\\枒^\\ꩵ}}}ꀣD\\]6M_⌫)H豣:36섘㑜": { + ";홗ᰰU஋㙛`D왔ཿЃS회爁\u001b-㢈`봆?盂㛣듿ᦾ蒽_AD~EEຆ㊋(eNwk=Rɠ峭q\"5Ἠ婾^>'ls\n8QAK)- Q䲌mo펹L_칍樖庫9꩝쪹ᘹ䑖瀍aK ?*趤f뭓廝p=磕", + "哑z懅ᤏ-ꍹux쀭", + [ + true, + 3998739591332339511, + "ጻ㙙?᳸aK<\/囩U`B3袗ﱱ?\"/k鏔䍧2l@쿎VZ쨎/6ꃭ脥|B?31+on颼-ꮧ,O嫚m ࡭`KH葦:粘i]aSU쓙$쐂f+詛頖b", + [{"^<9<箝&絡;%i﫡2攑紴\\켉h쓙-柂䚝ven\u20f7浯-Ꮏ\r^훁䓚헬\u000e?\\ㅡֺJ떷VOt": [{ + "-௄卶k㘆혐஽y⎱㢬sS઄+^瞥h;ᾷj;抭\u0003밫f<\/5Ⱗ裏_朻%*[-撵䷮彈-芈": { + "㩩p3篊G|宮hz䑊o곥j^Co0": [ + 653239109285256503, + {"궲?|\":N1ۿ氃NZ#깩:쇡o8킗ࡊ[\"됸Po핇1(6鰏$膓}⽐*)渽J'DN<썙긘毦끲Ys칖": { + "2Pr?Xjㆠ?搮/?㓦柖馃5뚣Nᦼ|铢r衴㩖\"甝湗ܝ憍": "\"뾯i띇筝牻$珲/4ka $匝휴译zbAᩁꇸ瑅&뵲衯ꎀᆿ7@ꈋ'ᶨH@ᠴl+", + "7뢽뚐v?4^ꊥ_⪛.>pởr渲<\/⢕疻c\"g䇘vU剺dஔ鮥꒚(dv祴X⼹\\a8y5坆": true, + "o뼄B욞羁hr﷔폘뒚⿛U5pꪴfg!6\\\"爑쏍䢱W<ﶕ\\텣珇oI/BK뺡'谑♟[Ut븷亮g(\"t⡎有?ꬊ躺翁艩nl F⤿蠜": 1695826030502619742, + "ۊ깖>ࡹ햹^ⵕ쌾BnN〳2C䌕tʬ]찠?ݾ2饺蹳ぶꌭ訍\"◹ᬁD鯎4e滨T輀ﵣ੃3\u20f3킙D瘮g\\擦+泙ၧ 鬹ﯨַ肋7놷郟lP冝{ߒhড়r5,꓋": null, + "ΉN$y{}2\\N﹯ⱙK'8ɜͣwt,.钟廣䎘ꆚk媄_": null, + "䎥eᾆᝦ읉,Jުn岪㥐s搖謽䚔5t㯏㰳㱊ZhD䃭f絕s鋡篟a`Q鬃┦鸳n_靂(E4迠_觅뷝_宪D(NL疶hL追V熑%]v肫=惂!㇫5⬒\u001f喺4랪옑": { + "2a輍85먙R㮧㚪Sm}E2yꆣꫨrRym㐱膶ᔨ\\t綾A☰.焄뙗9<쫷챻䒵셴᭛䮜.<\/慌꽒9叻Ok䰊Z㥪幸k": [ + null, + true, + {"쌞쐍": { + "▟GL K2i뛱iQ\"̠.옛1X$}涺]靎懠ڦ늷?tf灟ݞゟ{": 1.227740268699265E-19, + "꒶]퓚%ฬK❅": [{ + "(ෛ@Ǯっ䧼䵤[aテൖvEnAdU렖뗈@볓yꈪ,mԴ|꟢캁(而첸죕CX4Y믅": "2⯩㳿ꢚ훀~迯?᪑\\啚;4X\u20c2襏B箹)俣eỻw䇄", + "75༂f詳䅫ꐧ鏿 }3\u20b5'∓䝱虀f菼Iq鈆﨤g퍩)BFa왢d0뮪痮M鋡nw∵謊;ꝧf美箈ḋ*\u001c`퇚퐋䳫$!V#N㹲抗ⱉ珎(V嵟鬒_b㳅\u0019": null, + "e_m@(i㜀3ꦗ䕯䭰Oc+-련0뭦⢹苿蟰ꂏSV䰭勢덥.ྈ爑Vd,ᕥ=퀍)vz뱊ꈊB_6듯\"?{㒲&㵞뵫疝돡믈%Qw限,?\r枮\"? N~癃ruࡗdn&": null, + "㉹&'Pfs䑜공j<\/?|8oc᧨L7\\pXᭁ 9᪘": -2.423073789014103E18, + "䝄瑄䢸穊f盈᥸,B뾧푗횵B1쟢f\u001f凄": "魖⚝2儉j꼂긾껢嗎0ࢇ纬xI4](੓`蕞;픬\fC\"斒\")2櫷I﹥迧", + "ퟯ詔x悝령+T?Bg⥄섅kOeQ큼㻴*{E靼6氿L缋\u001c둌๶-㥂2==-츫I즃㠐Lg踞ꙂEG貨鞠\"\u0014d'.缗gI-lIb䋱ᎂDy缦?": null, + "紝M㦁犿w浴詟棓쵫G:䜁?V2ힽ7N*n&㖊Nd-'ຊ?-樹DIv⊜)g䑜9뉂ㄹ푍阉~ꅐ쵃#R^\u000bB䌎䦾]p.䀳": [{"ϒ爛\"ꄱ︗竒G䃓-ま帳あ.j)qgu扐徣ਁZ鼗A9A鸦甈!k蔁喙:3T%&㠘+,䷞|챽v䚞문H<\/醯r셓㶾\\a볜卺zE䝷_죤ဵ뿰᎟CB": [ + 6233512720017661219, + null, + -1638543730522713294, + false, + -8901187771615024724, + [ + 3891351109509829590, + true, + false, + -1.03836679125188032E18, + { + "j랎:g曞ѕᘼ}链N", + -1.1103819473845426E-19, + true, + [ + true, + null, + -7.9091791735309888E17, + true, + {"}蔰鋈+ꐨ啵0?g*사%`J?*": [{ + "\"2wG?yn,癷BK\\龞䑞x?蠢": -3.7220345009853505E-19, + ";饹়❀)皋`噿焒j(3⿏w>偍5X薙婏聿3aFÆÝ": "2,ꓴg?_섦_>Y쪥션钺;=趘F~?D㨫\bX?㹤+>/믟kᠪ멅쬂Uzỵ]$珧`m雁瑊ඖ鯬cꙉ梢f묛bB", + "♽n$YjKiXX*GO贩鏃豮祴遞K醞眡}ꗨv嵎꼷0୸+M菋eH徸J꣆:⼐悥B켽迚㯃b諂\u000bjꠜ碱逮m8": [ + "푷᣺ﻯd8ﱖ嬇ភH鹎⡱᱅0g:果6$GQ췎{vᷧYy-脕x偹砡館⮸C蓼ꏚ=軄H犠G谖ES詤Z蠂3l봟hᅭ7䦹1GPQG癸숟~[#駥8zQ뛣J소obg,", + null, + 1513751096373485652, + null, + -6.851466660824754E-19, + {"䩂-⴮2ٰK솖풄꾚ႻP앳1H鷛wmR䗂皎칄?醜<\/&ࠧ㬍X濬䵈K`vJ륒Q/IC묛!;$vϑ": { + "@-ꚗxྐྵ@m瘬\u0010U絨ﮌ驐\\켑寛넆T=tQ㭤L연@脸삯e-:⩼u㎳VQ㋱襗ຓ<Ⅶ䌸cML3+\u001e_C)r\\9+Jn\\Pﺔ8蠱檾萅Pq鐳话T䄐I": -1.80683891195530061E18, + "ᷭዻU~ཷsgSJ`᪅'%㖔n5픆桪砳峣3獮枾䌷⊰呀": { + "Ş੉䓰邟自~X耤pl7间懑徛s첦5ਕXexh⬖鎥᐀nNr(J컗|ૃF\"Q겮葲놔엞^겄+㈆话〾희紐G'E?飕1f❼텬悚泬먐U睬훶Qs": false, + "(\u20dag8큽튣>^Y{뤋.袊䂓;_g]S\u202a꽬L;^'#땏bႌ?C緡<䝲䲝断ꏏ6\u001asD7IK5Wxo8\u0006p弊⼂ꯍ扵\u0003`뵂픋%ꄰ⫙됶l囏尛+䗅E쟇\\": [ + true, + { + "\n鱿aK㝡␒㼙2촹f;`쾏qIࡔG}㝷䐍瓰w늮*粅9뒪ㄊCj倡翑閳R渚MiUO~仨䜶RꙀA僈㉋⦋n{㖥0딿벑逦⥻0h薓쯴Ꝼ": [ + 5188716534221998369, + 2579413015347802508, + 9.010794400256652E-21, + -6.5327297761238093E17, + 1.11635352494065523E18, + -6656281618760253655, + { + "": ")?", + "TWKLꑙ裑꺔UE俸塑炌Ũ᜕-o\"徚#": {"M/癟6!oI51ni퐚=댡>xꍨ\u0004 ?": { + "皭": {"⢫䋖>u%w잼<䕏꘍P䋵$魋拝U䮎緧皇Y훂&|羋ꋕ잿cJ䨈跓齳5\u001a삱籷I꿾뤔S8㌷繖_Yឯ䲱B턼O歵F\\l醴o_欬6籏=D": [ + false, + true, + {"Mt|ꏞD|F궣MQ뵕T,띺k+?㍵i": [ + 7828094884540988137, + false, + { + "!༦鯠,&aﳑ>[euJꏽ綷搐B.h": -7648546591767075632, + "-n켧嘰{7挐毄Y,>❏螵煫乌pv醑Q嶚!|⌝責0왾덢ꏅ蛨S\\)竰'舓Q}A釡5#v": 3344849660672723988, + "8閪麁V=鈢1녈幬6棉⪮둌\u207d᚛驉ꛃ'r䆉惏ै|bἧﺢᒙ<=穊强s혧eꮿ慩⌡ \\槳W븧J檀C,ᘉ의0俯퀉M;筷ࣴ瓿{늊埂鄧_4揸Nn阼Jੵ˥(社": true, + "o뼀vw)4A뢵(a䵢)p姃뛸\u000fK#KiQp\u0005ꅍ芅쏅": null, + "砥$ꥸ┇耽u斮Gc{z빔깎밇\\숰\u001e괷各㶇쵿_ᴄ+h穢p촀Ნ䃬z䝁酳ӂ31xꔄ1_砚W렘G#2葊P ": [ + -3709692921720865059, + null, + [ + 6669892810652602379, + -135535375466621127, + "뎴iO}Z? 馢녱稹ᄾ䐩rSt帤넆&7i騏멗畖9誧鄜'w{Ͻ^2窭외b㑎粖i矪ꦨ탪跣)KEㆹ\u0015V8[W?⽉>'kc$䨘ᮛ뉻٬M5", + 1.10439588726055846E18, + false, + -4349729830749729097, + null, + [ + false, + "_蠢㠝^䟪/D녒㡋ỎC䒈판\u0006એq@O펢%;鹐쏌o戥~A[ꡉ濽ỳ&虃᩾荣唙藍茨Ig楡꒻M窓冉?", + true, + 2.17220752996421728E17, + -5079714907315156164, + -9.960375974658589E-20, + "ᾎ戞༒", + true, + false, + [[ + "ⶉᖌX⧕홇)g엃⹪x뚐癟\u0002", + -5185853871623955469, + { + "L㜤9ợㇶK鐰⋓V뽋˖!斫as|9"፬䆪?7胜&n薑~": -2.11545634977136992E17, + "O8뀩D}캖q萂6༣㏗䈓煮吽ਆᎼDᣘ폛;": false, + "YTᡅ^L㗎cbY$pᣞ縿#fh!ꘂb삵玊颟샞ဢ$䁗鼒몁~rkH^:닮먖츸륈⪺쒉砉?㙓扫㆕꣒`R䢱B酂?C뇞<5Iޚ讳騕S瞦z": null, + "\\RB?`mG댵鉡幐物䵎有5*e骄T㌓ᛪ琾駒Ku\u001a[柆jUq8⋈5鿋츿myﻗ?雍ux঴?": 5828963951918205428, + "n0晅:黯 xu씪^퓞cB㎊ᬍ⺘٤փ~B岚3㥕擄vᲂ~F?C䶖@$m~忔S왖㲚?챴⊟W#벌{'㰝I䝠縁s樘\\X뢻9핡I6菍ㄛ8쯶]wॽ0L\"q": null, + "x增줖j⦦t䏢᎙㛿Yf鼘~꫓恄4惊\u209c": "oOhbᤃ᛽z&Bi犑\\3B㩬劇䄑oŁ쨅孥멁ຖacA㖫借㞝vg싰샂㐜#譞⢤@k]鋰嘘䜾L熶塥_<\/⍾屈ﮊ_mY菹t뙺}Ox=w鮮4S1ꐩמּ'巑", + "㗓蟵ꂾe蠅匳(JP䗏෸\u0089耀왲": [{ + "ᤃ㵥韎뤽\r?挥O쯡⇔㞚3伖\u0005P⋪\"D궣QLn(⚘罩䩢Ŏv䤘尗뼤됛O淽鋋闚r崩a{4箙{煷m6〈": { + "l곺1L": { + "T'ਤ?砅|੬Km]䄩\"(࿶<\/6U爢䫈倔郴l2㴱^줣k'L浖L鰄Rp今鎗⒗C얨M훁㡧ΘX粜뫈N꤇輊㌻켑#㮮샶-䍗룲蠝癜㱐V>=\\I尬癤t=": 7648082845323511446, + "鋞EP:<\/_`ၧe混ㇹBd⯢㮂驋\\q碽饩跓྿ᴜ+j箿렏㗑yK毢宸p謹h䦹乕U媣\\炤": [[ + "3", + [ + true, + 3.4058271399411134E-20, + true, + "揀+憱f逮@먻BpW曉\u001a㣐⎊$n劈D枤㡞좾\u001aᛁ苔౩闝1B䷒Ṋ݋➐ꀞꐃ磍$t੤_:蘺⮼(#N", + 697483894874368636, + [ + "vᘯ锴)0訶}䳅⩚0O壱韈ߜ\u0018*U鍾䏖=䧉뽑单휻ID쿇嘗?ꌸῬ07", + -5.4858784319382006E18, + 7.5467775182251151E18, + -8911128589670029195, + -7531052386005780140, + null, + [ + null, + true, + [[{ + "1欯twG<\/Q:0怯押殃탷聫사<ỗꕧ蚨䡁nDꌕ\u001c녬~蓩鲃g儊>ꏡl㻿/⑷*챳6㻜W毤緛ﹺᨪ4\u0013뺚J髬e3쳸䘦伧?恪&{L掾p+꬜M䏊d娘6": { + "2p첼양棜h䜢﮶aQ*c扦v︥뮓kC寵횂S銩&ǝ{O*य़iH`U큅ࡓr䩕5ꄸ?`\\᧫?ᮼ?t〟崾훈k薐ì/iy꤃뵰z1<\/AQ#뿩8jJ1z@u䕥": 1.82135747285215155E18, + "ZdN &=d년ᅆ'쑏ⅉ:烋5&៏ᄂ汎来L㯄固{钧u\\㊏튚e摑&t嗄ꖄUb❌?m䴘熚9EW": [{ + "ଛ{i*a(": -8.0314147546006822E17, + "⫾ꃆY\u000e+W`௸ \"M뒶+\\뷐lKE}(NT킶Yj選篒쁶'jNQ硾(똡\\\"逌ⴍy? IRꜘ὞鄬﨧:M\\f⠋Cꚜ쫊ᚴNV^D䕗ㅖἔIao꿬C⍏8": [ + 287156137829026547, + { + "H丞N逕⯲": {"": { + "7-;枮阕梒9ᑄZ": [[[[ + null, + { + "": [[[[ + -7.365909561486078E-19, + 2948694324944243408, + null, + [ + true, + "荒\"并孷䂡쵼9o䀘F\u0002龬7⮹Wz%厖/*? a*R枈㌦됾g뒠䤈q딄㺿$쮸tᶎ릑弣^鏎<\/Y鷇驜L鿽<\/춋9Mᲆឨ^<\/庲3'l낢", + "c鮦\u001b두\\~?眾ಢu݆綑෪蘛轋◜gȃ<\/ⴃcpkDt誩܅\"Y", + [[ + null, + null, + [ + 3113744396744005402, + true, + "v(y", + { + "AQ幆h쾜O+꺷铀ꛉ練A蚗⼺螔j㌍3꽂楎䥯뎸먩?": null, + "蠗渗iz鱖w]擪E": 1.2927828494783804E-17, + "튷|䀭n*曎b✿~杤U]Gz鄭kW|㴚#㟗ഠ8u擨": [[ + true, + null, + null, + {"⾪壯톽g7?㥜ώQꑐ㦀恃㧽伓\\*᧰閖樧뢇赸N휶䎈pI氇镊maᬠ탷#X?A+kНM ༑᩟؝?5꧎鰜ṚY즫궔 =ঈ;ﳈ?*s|켦蜌wM笙莔": [ + null, + -3808207793125626469, + [ + -469910450345251234, + 7852761921290328872, + -2.7979740127017492E18, + 1.4458504352519893E-20, + true, + "㽙깹?먏䆢:䴎ۻg殠JBTU⇞}ꄹꗣi#I뵣鉍r혯~脀쏃#釯:场:䔁>䰮o'㼽HZ擓௧nd", + [ + 974441101787238751, + null, + -2.1647718292441327E-19, + 1.03602824249831488E18, + [ + null, + 1.0311977941822604E-17, + false, + true, + { + "": -3.7019778830816707E18, + "E峾恆茍6xLIm縂0n2视֯J-ᤜz+ᨣ跐mYD豍繹⹺䊓몓ﴀE(@詮(!Y膽#᎙2䟓섣A䈀㟎,囪QbK插wcG湎ꤧtG엝x⥏俎j'A一ᯥ뛙6ㅑ鬀": 8999803005418087004, + "よ殳\\zD⧅%Y泥簳Uꈩ*wRL{3#3FYHା[d岀䉯T稉駅䞘礄P:闈W怏ElB㤍喬赔bG䠼U଄Nw鰯闀楈ePsDꥷ꭬⊊": [ + 6.77723657904486E-20, + null, + [ + "ཚ_뷎꾑蹝q'㾱ꂓ钚蘞慵렜떆`ⴹ⎼櫯]J?[t9Ⓢ !컶躔I᮸uz>3a㠕i,錃L$氰텰@7녫W㸮?羧W뇧ꃞ,N鋮숪2ɼ콏┍䁲6", + "&y?뢶=킕올Za惻HZk>c\u20b58i?ꦶcfBv잉ET9j䡡", + "im珊Ճb칧校\\뼾쯀", + 9.555715121193197E-20, + true, + { + "<㫚v6腓㨭e1㕔&&V∌ᗈT奄5Lጥ>탤?튣瑦㳆ꉰ!(ᙪ㿬擇_n쌯IMΉ㕨␰櫈ᱷ5풔蟹&L.첽e鰷쯃劼﫭b#ﭶ퓀7뷄Wr㢈๧Tʴશ㶑澕鍍%": -1810142373373748101, + "fg晌o?߲ꗄ;>C>?=鑰監侯Kt굅": true, + "䫡蓺ꑷ]C蒹㦘\"1ః@呫\u0014NL䏾eg呮፳,r$裢k>/\\?ㄤᇰﻛ쉕1஥'Ċ\" \\_?쨔\"ʾr: 9S䘏禺ᪧꄂ㲄", + [[{ + "*硙^+E쌺I1䀖ju?:⦈Ꞓl๴竣迃xKC/饉:\fl\"XTFᄄ蟭,芢<\/骡軺띜hꏘ\u001f銿<棔햳▨(궆*=乥b8\\媦䷀뫝}닶ꇭ(Kej䤑M": [{ + "1Ꮼ?>옿I╅C<ގ?ꊌ冉SV5A㢊㶆z-๎玶绢2F뵨@㉌뀌o嶔f9-庒茪珓뷳4": null, + ";lᰳ": "CbB+肻a䄷苝*/볳+/4fq=㰁h6瘉샴4铢Y骐.⌖@哼猎㦞+'gꋸ㒕ߤ㞑(䶒跲ti⑴a硂#No볔", + "t?/jE幸YHT셵⩎K!Eq糦ꗣv刴w\"l$ο:=6:移": { + "z]鑪醊嫗J-Xm銌翁絨c里됏炙Ep㣋鏣똼嚌䀓GP﹖cmf4鹭T䅿꣭姧␸wy6ꦶ;S&(}ᎧKxᾂQ|t뻳k\"d6\"|Ml췆hwLt꼼4$&8Պ褵婶鯀9": {"嵃닢ᒯ'd᧫䳳#NXe3-붋鸿ଢ떓%dK\u0013䲎ꖍYV.裸R⍉rR3蟛\\:젯:南ĺLʆ넕>|텩鴷矔ꋅⒹ{t孶㓑4_": [ + true, + null, + [ + false, + "l怨콈lᏒ", + { + "0w䲏嬧-:`䉅쉇漧\\܂yㄨb%㽄j7ᦶ涶<": 3.7899452730383747E-19, + "ꯛTẀq纤q嶏V⿣?\"g}ი艹(쥯B T騠I=仵및X": {"KX6颠+&ᅃ^f畒y[": { + "H?뱜^?꤂-⦲1a㋞&ꍃ精Ii᤾챪咽쬘唂쫷<땡劈훫놡o㥂\\ KⴙD秼F氮[{'좴:례晰Iq+I쭥_T綺砸GO煝䟪ᚪ`↹l羉q쐼D꽁ᜅ훦: vUV": true, + "u^yﳍ0㱓#[y뜌앸ꊬL㷩?蕶蘾⻍KӼ": -7931695755102841701, + "䤬轉車>\u001c鴵惋\"$쯃྆⇻n뽀G氠S坪]ಲꨍ捇Qxኻ椕駔\\9ࣼ﫻읜磡煮뺪ᶚ볝l㕆t+sζ": [[[ + true, + false, + [ + null, + 3363739578828074923, + true, + { + "\"鸣詩 볰㑵gL㯦῅춝旫}ED辗ﮈI쀤-ꧤ|㠦Z\"娑ᕸ4爏騍㣐\"]쳝Af]茛⬻싦o蚁k䢯䩐菽3廇喑ޅ": 4.5017999150704666E17, + "TYႇ7ʠ值4챳唤~Zo&ݛ": false, + "`塄J袛㭆끺㳀N㺣`꽐嶥KﯝSVᶔ∲퀠獾N딂X\"ᤏhNﬨvI": {"\u20bb㭘I䖵䰼?sw䂷쇪](泒f\"~;꼪Fԝsᝦ": {"p,'ꉂ軿=A蚶?bƉ㏵䅰諬'LYKL6B깯⋩겦뎙(ᜭ\u0006噣d꾆㗼Z;䄝䚔cd<情@䞂3苼㸲U{)<6&ꩻ钛\u001au〷N숨囖愙j=BXW욕^x芜堏Ῑ爂뛷꒻t✘Q\b": [[ + "籛&ଃ䩹.ꃩ㦔\\C颫#暪&!勹ꇶ놽攺J堬镙~軌C'꾖䣹㮅岃ᙴ鵣", + 4.317829988264744E15, + 6.013585322002147E-20, + false, + true, + null, + null, + -3.084633632357326E-20, + false, + null, + { + "\"짫愔昻 X\"藣j\"\"먁ཅѻ㘤㬯0晲DU꟒㸃d벀윒l䦾c੻*3": null, + "谈Wm陧阦咟ฯ歖擓N喴㋐銭rCCnVࢥ^♼Ⅾ젲씗刊S༝+_t赔\\b䚍뉨ꬫ6펛cL䊘᜼<\/澤pF懽&H": [ + null, + { + "W\"HDUuΌ퀟M'P4࿰H똆ⰱﮯ<\/凐蘲\"C鴫ﭒж}ꭩ쥾t5yd诪ﮡ퍉ⴰ@?氐醳rj4I6Qt": 6.9090159359219891E17, + "絛ﳛ⺂": {"諰P㗮聦`ZQ?ꫦh*റcb⧱}埌茥h{棩렛툽o3钛5鮁l7Q榛6_g)ὄ\u0013kj뤬^爖eO4Ⱈ槞鉨ͺ订%qX0T썗嫷$?\\\"봅늆'%": [ + -2.348150870600346E-19, + [[ + true, + -6619392047819511778, + false, + [[ + -1.2929189982356161E-20, + 1.7417192219309838E-19, + {"?嵲2࿐2\u0001啑㷳c縯": [ + null, + [ + false, + true, + 2578060295690793218, + { + "?\"殃呎#㑑F": true, + "}F炊_殛oU헢兔Ꝉ,赭9703.B数gTz3⏬": { + "5&t3,햓Mݸᵣ㴵;꣫䩍↳#@뫷䠅+W-ࣇzᓃ鿕ಔ梭?T䮑ꥬ旴]u뫵막bB讍:왳둛lEh=숾鱠p咐$짏#?g⹷ᗊv㷵.斈u頻\u0018-G.": "뽙m-ouࣤ஫牷\"`Ksꕞ筼3HlȨvC堈\"I]㖡玎r먞#'W賜鴇k'c룼髋䆿飉㗆xg巤9;芔cጐ/ax䊨♢큓r吓㸫೼䢗da᩾\"]屣`", + ":M딪<䢥喠\u0013㖅x9蕐㑂XO]f*Q呰瞊吭VP@9,㨣 D\\穎vˤƩs㜂-曱唅L걬/롬j㈹EB8g<\/섩o渀\"u0y&룣": ">氍緩L/䕑돯Ꟙ蕞^aB뒣+0jK⪄瑨痜LXK^힦1qK{淚t츔X:Vm{2r獁B뾄H첚7氥?쉟䨗ꠂv팳圎踁齀\\", + "D彤5㢷Gꪻ[lㄆ@὜⓰絳[ଃ獽쮹☒[*0ꑚ㜳": 9022717159376231865, + "ҖaV銣tW+$魿\u20c3亜~뫡ᙰ禿쨽㏡fṼzE/h": "5臐㋇Ჯ쮺? 昨탰Wム밎#'\"崲钅U?幫뺀⍾@4kh>騧\\0ҾEV=爐͌U捀%ꉼ 㮋<{j]{R>:gԩL\u001c瀈锌ﯲﳡꚒ'⫿E4暍㌗뵉X\"H᝜", + "ᱚגּ;s醒}犍SἿ㦣&{T$jkB\\\tḮ앾䤹o<避(tW": "vb⯽䴪䮢@|)", + "⥒퐁껉%惀뗌+녣迺顀q條g⚯i⤭룐M琹j̈́⽜A": -8385214638503106917, + "逨ꊶZ<\/W⫟솪㎮ᘇb?ꠔi\"H㧺x෷韒Xꫨฟ|]窽\u001a熑}Agn?Mᶖa9韲4$3Ỵ^=쏍煤ፐ돷2䣃%鷠/eQ9頸쥎", + 2398360204813891033, + false, + 3.2658897259932633E-19, + null, + "?ꚃ8Nn㞷幵d䲳䱲뀙ꪛQ瑓鎴]䩋-鰾捡䳡??掊", + false, + -1309779089385483661, + "ᦲxu_/yecR.6芏.ᜇ過 ~", + -5658779764160586501, + "쒌:曠=l썜䢜wk#s蕚\"互㮉m䉤~0듐䋙#G;h숄옥顇෤勹(C7㢅雚㐯L⠅VV簅<", + null, + -4.664877097240962E18, + -4.1931322262828017E18, + { + ",": { + "v㮟麑䄠뤵g{M띮.\u001bzt뢜뵡0Ǥ龍떟Ᾰ怷ϓRT@Lꀌ樂U㏠⾕e扉|bJg(뵒㠶唺~ꂿ(땉x⻫싉쁊;%0鎻V(o\f,N鏊%nk郼螺": -1.73631993428376141E18, + "쟧摑繮Q@Rᕾ㭚㾣4隅待㓎3蒟": [ + 4971487283312058201, + 8973067552274458613, + { + "`a揙ᣗ\u0015iBo¸": 4.3236479112537999E18, + "HW&퉡ぁ圍Y?瑡Qy훍q!帰敏s舠㫸zꚗaS歲v`G株巷Jp6킼 (귶鍔⾏⡈>M汐㞍ቴ꙲dv@i㳓ᇆ?黍": [ + null, + 4997607199327183467, + "E㻎蠫ᐾ高䙟蘬洼旾﫠텛㇛?'M$㣒蔸=A_亀绉앭rN帮", + null, + [{ + "Eᑞ)8餧A5u&㗾q?": [ + -1.969987519306507E-19, + null, + [ + 3.42437673373841E-20, + true, + "e걷M墁\"割P␛퍧厀R䱜3ﻴO퓫r﹉⹊", + [ + -8164221302779285367, + [ + true, + null, + "爘y^-?蘞Ⲽꪓa␅ꍨ}I", + 1.4645984996724427E-19, + [{ + "tY좗⧑mrzﺝ㿥ⴖ᥷j諅\u0000q賋譁Ꞅ⮱S\nࡣB/큃굪3Zɑ复o<\/;롋": null, + "彟h浠_|V4䦭Dᙣ♞u쿻=삮㍦\u001e哀鬌": [{"6횣楠,qʎꗇ鎆빙]㱭R굋鈌%栲j分僅ペ䇰w폦p蛃N溈ꡐꏀ?@(GI뉬$ﮄ9誁ꓚ2e甸ڋ[䁺,\u0011\u001cࢃ=\\+衪䷨ᯕ鬸K": [[ + "ㅩ拏鈩勥\u000etgWVXs陂規p狵w퓼{뮵_i\u0002ퟑႢ⬐d6鋫F~챿搟\u0096䚼1ۼ칥0꣯儏=鋷牋ⅈꍞ龐", + -7283717290969427831, + true, + [ + 4911644391234541055, + { + "I鈒첽P릜朸W徨觘-Hᎄ퐟⓺>8kr1{겵䍃〛ᬡ̨O귑o䝕'쿡鉕p5": "fv粖RN瞖蛐a?q꤄\u001d⸥}'ꣴ犿ꦼ?뤋?鵆쥴덋䡫s矷̄?ඣ/;괱絢oWfV<\/\u202cC,㖦0䑾%n賹g&T;|lj_欂N4w", + "짨䠗;䌕u i+r๏0": [{"9䥁\\఩8\"馇z䇔<\/ႡY3e狚쐡\"ุ6ﰆZ遖c\"Ll:ꮾ疣<\/᭙O◌납୕湞9⡳Und㫜\u0018^4pj1;䧐儂䗷ୗ>@e톬": { + "a⑂F鋻Q螰'<퇽Q贝瀧{ᘪ,cP&~䮃Z?gI彃": [ + -1.69158726118025933E18, + [ + "궂z簽㔛㮨瘥⤜䛖Gℤ逆Y⪾j08Sn昞ꘔ캻禀鴚P謦b{ꓮmN靐Mᥙ5\"睏2냑I\u0011.L&=?6ᄠ뻷X鸌t刑\"#z)o꫚n쳟줋", + null, + 7517598198523963704, + "ኑQp襟`uᩄr方]*F48ꔵn俺ሙ9뇒", + null, + null, + 6645782462773449868, + 1219168146640438184, + null, + { + ")ယ넌竀Sd䰾zq⫣⏌ʥ\u0010ΐ' |磪&p牢蔑mV蘸૰짬꺵;K": [ + -7.539062290108008E-20, + [ + true, + false, + null, + true, + 6574577753576444630, + [[ + 1.2760162530699766E-19, + [ + null, + [ + "顊\\憎zXB,", + [{ + "㇆{CVC9-MN㜋ઘR눽#{h@ퟨ!鼚׼XOvXS\u0017ᝣ=cS+梽៲綆16s덽휐y屬?ᇳG2ᴭ\u00054쫖y룇nKcW̭炦s/鰘ᬽ?J|퓀髣n勌\u0010홠P>j": false, + "箴": [ + false, + "鍞j\"ꮾ*엇칬瘫xṬ⭽쩁䃳\"-⋵?ᦽ댎Ĝ": true, + "Pg帯佃籛n㔠⭹࠳뷏≻࿟3㞱!-쒾!}쭪䃕!籿n涻J5ਲ਼yvy;Rኂ%ᔡጀ裃;M⣼)쵂쑈": 1.80447711803435366E18, + "ꈑC⡂ᑆ㤉壂뎃Xub<\/쀆༈憓ق쨐ק\\": [ + 7706977185172797197, + {"": {"K╥踮砆NWࡆFy韣7ä밥{|紒︧䃀榫rᩛꦡTSy잺iH8}ퟴ,M?Ʂ勺ᴹ@T@~꾂=I㙕뾰_涀쑜嫴曣8IY?ҿo줫fऒ}\\S\"ᦨ뵼#nDX": { + "♘k6?଱癫d68?㽚乳䬳-V顷\u0005蝕?\u0018䞊V{邾zじl]雏k臤~ൖH뒐iꢥ]g?.G碄懺䔛pR$䅒X觨l봜A刊8R梒',}u邩퉕?;91Ea䈈믁G⊶芔h袪&廣㺄j;㡏綽\u001bN頸쳘橆": -2272208444812560733, + "拑Wﵚj鵼駳Oࣿ)#㾅顂N傓纝y僱栜'Bꐍ-!KF*ꭇK¦?䈴^:啤wG逭w᧯": "xᣱmYe1ۏ@霄F$ě꧘푫O䤕퀐Pq52憬ꀜ兴㑗ᡚ?L鷝ퟐ뭐zJꑙ}╆ᅨJB]\"袌㺲u8䯆f", + "꿽၅㔂긱Ǧ?SI": -1669030251960539193, + "쇝ɨ`!葎>瞺瘡驷錶❤ﻮ酜=": -6961311505642101651, + "?f7♄꫄Jᡔ훮e읇퍾፣䭴KhखT;Qty}O\\|뫁IῒNe(5惁ꥶㆷY9ﮡ\\ oy⭖-䆩婁m#x봉>Y鈕E疣s驇↙ᙰm<": {"퉻:dꂁ&efᅫ쫢[\"돈늖꺙|Ô剐1͖-K:ʚ᭕/;쏖㷛]I痐职4gZ4⍜kเꛘZ⥺\\Bʫᇩ鄨魢弞&幟ᓮ2̊盜", + -9006004849098116748, + -3118404930403695681, + { + "_彃Y艘-\"Xx㤩㳷瑃?%2䐡鵛o귵옔夘v*탋职&㳈챗|O钧": [ + false, + "daꧺdᗹ羞쯧H㍤鄳頳<型孒ン냆㹀f4㹰\u000f|C*ሟ鰠(O<ꨭ峹ipຠ*y೧4VQ蔔hV淬{?ᵌEfrI_", + "j;ꗣ밷邍副]ᗓ", + -4299029053086432759, + -5610837526958786727, + [ + null, + [ + -1.3958390678662759E-19, + { + "lh좈T_믝Y\"伨\u001cꔌG爔겕ꫳ晚踍⿻읐T䯎]~e#฽燇\"5hٔ嶰`泯r;ᗜ쮪Q):/t筑,榄&5懶뎫狝(": [{ + "2ፁⓛ]r3C攟וּ9賵s⛔6'ஂ|\"ⵈ鶆䐹禝3\"痰ࢤ霏䵩옆䌀?栕r7O簂Isd?K᫜`^讶}z8?z얰T:X倫⨎ꑹ": -6731128077618251511, + "|︦僰~m漿햭\\Y1'Vvخ굇ቍ챢c趖": [null] + }], + "虌魿閆5⛔煊뎰㞤ᗴꥰF䮥蘦䂪樳-K᝷-(^\u20dd_": 2.11318679791770592E17 + } + ] + ] + ]}, + "묗E䀳㧯᳀逞GMc\b墹㓄끖Ơ&U??펌鑍 媋k))ᄊ": null, + "묥7콽벼諌J_DɯﮪM殴䣏,煚ྼ`Y:씧<\/⩫%yf䦀!1Ჶk춎Q米W∠WC跉鬽*ᛱi㴕L꘻ꀏ쓪\"_g鿄'#t⽙?,Wg㥖|D鑆e⥏쪸僬h鯔咼ඡ;4TK聎졠嫞" + } + ] + ] + } + ] + ] + ]}} + } + ]} + }, + "뿋뀾淣截䔲踀&XJ펖꙯^Xb訅ꫥgᬐ>棟S\"혧騾밫겁7-": "擹8C憎W\"쵮yR뢩浗絆䠣簿9䏈引Wcy䤶孖ꯥ;퐌]輩䍐3@{叝 뽸0ᡈ쵡Ⲇ\u001dL匁꧐2F~ݕ㪂@W^靽L襒ᦘ~沦zZ棸!꒲栬R" + } + ] + ], + "Z:덃൛5Iz찇䅄駠㭧蓡K1": "e8᧤좱U%?ⵇ䯿鿝\u0013縮R∱骒EO\u000fg?幤@֗퉙vU`", + "䐃쪈埽້=Ij,쭗쓇చ": false + }]}} + ] + } + ]} + } + ] + ] + ], + "咰긖VM]᝼6䓑쇎琺etDҌ?㞏ꩄ퇫밉gj8蠃\"⩐5䛹1ࣚ㵪": "ക蹊?⎲⧘⾚̀I#\"䈈⦞돷`wo窭戕෱휾䃼)앷嵃꾞稧,Ⴆ윧9S?೗EMk3Მ3+e{⹔Te驨7䵒?타Ulg悳o43" + } + ], + "zQᤚ纂땺6#ٽ﹧v￿#ࠫ휊冟蹧텈ꃊʆ?&a䥯De潝|쿓pt瓞㭻啹^盚2Ꝋf醪,얏T窧\\Di䕎谄nn父ꋊE": -2914269627845628872, + "䉩跐|㨻ᷢ㝉B{蓧瞸`I!℄욃힕#ೲᙾ竛ᔺCjk췒늕貭词\u0017署?W딚%(pꍁ⤼띳^=on뺲l䆼bzrﳨ[&j狸䠠=ᜑꦦ\u2061յnj=牲攑)M\\龏": false, + "뎕y絬᫡⥮Ϙᯑ㌔/NF*˓.,QEzvK!Iwz?|쥾\"ꩻL꼗Bꔧ賴緜s뉣隤茛>ロ?(?^`>冺飒=噸泥⺭Ᲊ婓鎔븜z^坷裮êⓅ໗jM7ﶕ找\\O": 1.376745434746303E-19 + }, + "䐛r滖w㏤,|Nዜ": false + } + ]], + "@꿙?薕尬 gd晆(띄5躕ﻫS蔺4)떒錸瓍?~": 1665108992286702624, + "w믍nᏠ=`঺ᅥC>'從됐槷䤝眷螄㎻揰扰XᅧC贽uჍ낟jKD03T!lDV쀉Ӊy뢖,袛!终캨G?鉮Q)⑗1쾅庅O4ꁉH7?d\u0010蠈줘월ސ粯Q!낇껉6텝|{": null, + "~˷jg쿤촖쉯y": -5.5527605669177098E18, + "펅Wᶺzꐆと푭e?4j仪열[D<鈑皶婆䵽ehS?袪;HꍨM뗎ば[(嗏M3q퍟g4y╸鰧茀[Bi盤~﫝唎鋆彺⦊q?B4쉓癚O洙킋툈䶯_?ퟲ": null + } + ] + ]] + ]], + "꟱Ԕ㍤7曁聯ಃ錐V䷰?v㪃૦~K\"$%请|ꇹn\"k䫛㏨鲨\u2023䄢\u0004[︊VJ?䶟ាꮈ䗱=깘U빩": -4863152493797013264 + } + ]}]} + ] + }}} + ], + "쏷쐲۹퉃~aE唙a챑,9㮹gLHd'䔏|킗㍞䎥&KZYT맵7䥺Nⱳ同莞鿧w\\༌疣n/+ꎥU\"封랾○ퟙAJᭌ?9䛝$?驔9讐짘魡T֯c藳`虉C읇쐦T" + } + ], + "谶개gTR￐>ၵ͚dt晑䉇陏滺}9㉸P漄": -3350307268584339381 + }] + ] + ] + ]] + ] + ], + "0y꟭馋X뱔瑇:䌚￐廿jg-懲鸭䷭垤㒬茭u賚찶ಽ+\\mT땱\u20821殑㐄J쩩䭛ꬿNS潔*d\\X,壠뒦e殟%LxG9:摸": 3737064585881894882, + "풵O^-⧧ⅶvѪ8廸鉵㈉ר↝Q㿴뺟EႳvNM:磇>w/៻唎뷭୥!냹D䯙i뵱貁C#⼉NH6`柴ʗ#\\!2䂗Ⱨf?諳.P덈-返I꘶6?8ꐘ": -8934657287877777844, + "溎-蘍寃i诖ര\"汵\"\ftl,?d⼡쾪⺋h匱[,෩I8MҧF{k瓿PA'橸ꩯ綷퉲翓": null + } + ] + ], + "ោ係؁<元": 1.7926963090826924E-18 + }}] + } + ] + ]]}] + }] + ] + ] + ] + ], + "ጩV<\"ڸsOᤘ": 2.0527167903723048E-19 + }] + ]} + ] + ]], + "∳㙰3젴p᧗䱙?`yZA8Ez0,^ᙛ4_0븢\u001ft:~䎼s.bb룦明yNP8弆C偯;⪾짍'蕴뮛": -6976654157771105701, + "큵ꦀ\\㇑:nv+뒤燻䀪ﴣ﷍9ᚈ኷K㚊誦撪䚛,ꮪxሲ쳊\u0005HSf?asg昱dqꬌVꙇ㼺'k*'㈈": -5.937042203633044E-20 + } + ] + }], + "?}\u20e0],s嶳菋@#2u쒴sQS䩗=ꥮ;烌,|ꘔ䘆": "ᅩ영N璠kZ먕眻?2ቲ芋眑D륟渂⸑ﴃIRE]啗`K'" + }}, + "쨀jmV賂ﰊ姐䂦玞㬙ᏪM᪟Վ씜~`uOn*ॠ8\u000ef6??\\@/?9見d筜ﳋB|S䝬葫㽁o": true + }, + "즛ꄤ酳艚␂㺘봿㎨iG৕ࡿ?1\"䘓您\u001fSኝ⺿溏zៀ뻤B\u0019?윐a䳵᭱䉺膷d:<\/": 3935553551038864272 + } + ] + ]} + ]] + ]] + ]} + } + ] + } + ]]}}, + "᥺3h↛!ꋰy\"攜(ெl䪕oUkc1A㘞ᡲ촾ᣫ<\/䒌E㛝潨i{v?W౾H\\RჅpz蝬R脾;v:碽✘↯삞鷱o㸧瑠jcmK7㶧뾥찲n": true, + "ⶸ?x䊺⬝-䰅≁!e쩆2ꎿ准G踌XXᩯ1߁}0?.헀Z馟;稄\baDꟹ{-寪⚈ꉷ鮸_L7ƽᾚ<\u001bጨA䧆송뇵⨔\\礍뗔d设룱㶉cq{HyぱR㥽吢ſtp": -7985372423148569301, + "緫#콮IB6<\/=5Eh礹\t8럭@饹韠r㰛斣$甝LV췐a갵'请o0g:^": "䔨(.", + "띳℡圤pン௄ĝ倧訜B쁟G䙔\"Sb⓮;$$▏S1J뢙SF|赡g*\"Vu䲌y": "䪈&틐),\\kT鬜1풥;뷴'Zေ䩹@J鞽NぼM?坥eWb6榀ƩZڮ淽⺞삳煳xჿ絯8eⶍ羷V}ჿ쎱䄫R뱃9Z>'\u20f1ⓕ䏜齮" + } + ] + ]]] + }} + } + ] + ]}, + "펮b.h粔폯2npX詫g錰鷇㇒<쐙S値bBi@?镬矉`剔}c2壧ଭfhY깨R()痩⺃a\\⍔?M&ﯟ<劜꺄멊ᄟA\"_=": null + }, + "~潹Rqn榢㆓aR鬨侅?䜑亡V_翅㭔(䓷w劸ၳDp䀅<\/ﰎ鶊m䵱팱긽ꆘ긓准D3掱;o:_ќ)껚콥8곤d矦8nP倥ꃸI": null, + "뾎/Q㣩㫸벯➡㠦◕挮a鶧⋓偼\u00001뱓fm覞n?㛅\"": 2.8515592202045408E17 + }], + ",": -5426918750465854828, + "2櫫@0柡g䢻/gꆑ6演&D稒肩Y?艘/놘p{f투`飷ᒉ챻돎<늛䘍ﴡ줰쫄": false, + "8(鸑嵀⵹ퟡ<9㣎Tߗ┘d슒ل蘯&㠦뮮eࠍk砝g 엻": false, + "d-\u208b?0ﳮ嵙'(J`蔿d^踅⤔榥\\J⵲v7": 6.8002426206715341E17, + "ཎ耰큓ꐕ㱷\u0013y=詽I\"盈xm{0쾽倻䉚ષso#鰑/8㸴짯%ꀄ떸b츟*\\鲷礬ZQ兩?np㋄椂榨kc᡹醅3": false, + "싊j20": false + }]] + ]], + "俛\u0017n緽Tu뫉蜍鼟烬.ꭠIⰓ\"Ἀ᜾uC쎆J@古%ꛍm뻨ᾀ画蛐휃T:錖㑸ዚ9죡$": true + } + ] + ], + "㍵⇘ꦖ辈s}㱮慀밒s`\"㞟j:`i픻Z섫^諎0Ok{켿歁෣胰a2﨤[탳뚬쎼嫭뉮m": 409440660915023105, + "w墄#*ᢄ峠밮jLa`ㆪ꺊漓Lで끎!Agk'ꁛ뢃㯐岬D#㒦": false, + "ଦPGI䕺L몥罭ꃑ궩﮶#⮈ᢓӢ䚬p7웼臧%~S菠␌힀6&t䳙y㪘냏\\*;鉏ᅧ鿵'嗕pa\"oL쇿꬈Cg": "㶽1灸D⟸䴅ᆤ뉎﷛渤csx 䝔цꬃ锚捬?ຽ+x~꘩uI࡞\u0007栲5呚ẓem?袝\")=㥴䨃pac!/揎Y", + "ᷱo\\||뎂몷r篙|#X䦜I#딌媸픕叞RD斳X4t⯩夬=[뭲r=绥jh뷱츝⪘%]⚋܈㖴スH텹m(WO曝劉0~K3c柢Ր㏉着逳~": false, + "煽_qb[첑\\륌wE❽ZtCNﭝ+餌ᕜOꛭ": "{ﳾ쉌&s惧ᭁⵆ3䢫;䨞팑꒪흘褀࢖Q䠿V5뭀䎂澻%받u5텸oA⮥U㎦;B䳌wz䕙$ឿ\\௅婺돵⪾퐆\\`Kyौꋟ._\u0006L챯l뇠Hi䧈偒5", + "艊佁ࣃ롇䱠爬!*;⨣捎慓q靓|儑ᨋL+迥=6㒺딉6弄3辅J-㕎뛄듘SG㆛(\noAzQꝱ䰩X*ぢO퀌%펠낌mo틮a^<\/F&_눊ᾉ㨦ы4\"8H": 2974648459619059400, + "鬙@뎣䫳ၮ끡?){y?5K;TA*k溱䫜J汃ꂯ싔썍\u001dA}룖(<\/^,": false, + "몏@QꋦFꊩᒐ뎶lXl垨4^郣|ꮇ;䝴ᝓ}쵲z珖": null + } + ]]]], + ":_=닧弗D䙋暨鏛. 㱻붘䂍J儒&ZK/녩䪜r囁⽯D喠죥7⹌䪥c\u001a\u2076￞妈朹oLk菮F౟覛쐧㮏7T;}蛙2{9\"崓bB<\/⡷룀;즮鿹)丒툃୤뷠5W⊢嶜(fb뭳갣": "E{响1WM" + }}, + "䘨tjJ驳豨?y輊M*᳑梵瞻઻ofQG瑮e": 2.222802939724948E-19, + "䮴=❑➶T෋w䞜\"垦ꃼUt\u001dx;B$뵣䙶E↌艣ᡥ!᧟;䱀[䔯k쬃`੍8饙른熏'2_'袻tGf蒭J땟as꯳╖&啒zWࡇᒫYSᏬ\u0014ℑ첥鈤|cG~Pᓮ\">\"": "ႆl\f7V儊㦬nHꄬꨧC{쐢~C⮃⛓嶦vꄎ1w鰠嘩뿠魄&\"_qMⵖ釔녮ꝇ 㝚{糍J哋 cv?-jkﻯྌ鹑L舟r", + "龧葆yB✱H盋夔ﶉ?n*0(": "ꧣኆ㢓氥qZZ酒ຜ)鮢樛)X䣆gTSґG텞k.J圬疝롫쯭z L:\\ྤ@w炋塜쿖ᾳy뢀䶃뱝N䥨㚔勇겁#p", + "도畎Q娡\"@S/뼋:䵏!P衅촚fVHQs✜ᐫi㻑殡B䜇%믚k*U#濨낄~": "ꍟዕ쳸ꍈ敋&l妏\u0005憡멗瘌uPgᅪm<\/To쯬锩h뒓k" + } + ] + }], + "墥홞r绚<\/⸹ⰃB}<躅\\Y;๑@䔸>韫䜲뱀X뗩鿥쩗SI%ﴞ㳕䛇?<\/\u00018x\\&侂9鋙a[LR㋭W胕)⡿8㞙0JF,}?허d1cDMᐃ␛鄝ⱕ%X)!XQ": "ⳍꗳ=橇a;3t⦾꼑仈ူaᚯ⯋ꕃAs鴷N⍕_䎃ꙎAz\u0016䯷\\<࿫>8q{}キ?ᣰ}'0ᴕ펓B┦lF#趤厃T?㕊#撹圂䆲" + }, + "܋닐龫論c웑": false, + "ㇿ/q\"6-co髨휝C큦#\u001b4~?3䐹E삇<<": 7.600917488140322E-20, + "䁝E6?㣖ꃁ间t祗*鑠{ḣV(浾h逇큞=W?ૉ?nꇽ8ꅉຉj으쮺@Ꚅ㰤u]Oyr": "v≁᫸_*όAඤԆl)ۓᦇQ}폠z༏q滚", + "ソ᥊/넺I": true + }]] + ] + ] + ] + ]] + }, + "䭑Ik攑\u0002QV烄:芩.麑㟴㘨≕": true, + "坄꿕C쇻풉~崍%碼\\8\"䬦꣙": null, + "欌L圬䅘Y8c(♺2?ON}o椳s宥2䉀eJ%闹r冁O^K諭%凞⺉⡻,掜?$ꥉ?略焕찳㯊艼誜4?\"﯎<゛XፈINT:詓 +": -1.0750456770694562E-19, + "獒àc뜭싼ﺳ뎤K`]p隨LtE": null, + "甙8䵊神EIꩤ鐯ᢀ,ﵮU䝑u疒ử驺䚿≚ഋ梶秓F`覤譐#짾蔀묊4<媍쬦靪_Yzgcࡶ4k紥`kc[Lﮗ簐*I瀑[⾰L殽鑥_mGȠ<\/|囹灠g桰iri": true, + "챓ꖙꟻ좝菇ou,嗠0\\jK핻뜠qwQ?ഩ㼕3Y彦b\u009bJ榶N棨f?됦鏖綃6鳵M[OE봨u햏.Ꮁ癜蟳뽲ꩌ뻾rM豈R嗀羫 uDꎚ%": null + }, + "V傜2<": 7175127699521359521 + }], + "铫aG切<\/\"ী⊆e<^g࢛)D顝nאַ饼\u008c猪繩嵿ﱚCꡬ㻊g엺A엦\u000f暿_f꿤볝㦕桦`蒦䎔j甬%岝rj 糏": "䚢偎눴Au<4箞7礦Iﱔ坠eȧ䪸u䵁p|逹$嗫쨘ꖾ﷐!胠z寓팢^㨔|u8Nሇe텔ꅦ抷]،鹎㳁#༔繁 ", + "낂乕ꃻ볨ϱ-ꇋ㖍fs⿫)zꜦ/K?솞♞ꑌ宭hJ᤭瑥Fu": false, + "쟰ぜ魛G\u0003u?`㾕ℾ㣭5螠烶這趩ꖢ:@咕ꐶx뒘느m䰨b痃렐0鳊喵熬딃$摉_~7*ⱦ녯1錾GKhJ惎秴6'H妈Tᧅ窹㺒疄矤铟wላ": null, + "쯆q4!3錕㲏ⵆ㇛꘷Z瑩뭆\\◪NH\u001d\\㽰U~㯶<\"쑣낞3ᵤ'峉eꢬ;鬹o꣒木X*長PXᘱu\"䠹n惞": null, + "ᅸ祊\"&ꥴCjࢼ﴿?䡉`U效5殼㮞V昽ꏪ#ﺸ\\&t6x꠹盥꣰a[\u001aꪍSpe鎿蠹": -1.1564713893659811E-19 + } + ]] + ] + ] + ], + "羵䥳H,6ⱎ겾|@t\"#햊1|稃 섭)띜=뻔ꡜ???櫎~*ῡ꫌/繣ﻠq": null + } + ]} + ]}, + "츤": false + }}, + "s": 3.7339341963399598E18 + } + ], + "N,I?1+㢓|ࣱ嶃쩥V2\u0012(4EE虪朶$|w颇v步": "~읢~_,Mzr㐫YB溓E淚\"ⅹ䈔ᏺ抙 b,nt5V㐒J檶ꏨ⻔?", + "Q껑ꡡ}$넎qH煔惍/ez^!ẳF댙䝌馻剁8": "梲;yt钰$i冄}AL%a j뜐奷걳뚾d꿽*ሬuDY3?뮟鼯뮟w㍪틱V", + "o{Q/K O胟㍏zUdꀐm&⨺J舕⾏魸訟㌥[T籨櫉唐킝 aṭ뱫촙莛>碶覆⧬짙쭰ׯdAiH໥벤퐥_恸[ 0e:죃TC弼荎뵁DA:w唵ꣁ": null, + "὏樎䵮軧|?౗aWH쩃1 ꅭsu": null + } + ] + }, + "勂\\&m鰈J釮=Ⲽ鳋+䂡郑": null, + "殣b綊倶5㥗惢⳷萢ᑀ䬄镧M^ﱴ3⣢翣n櫻1㨵}ኯ뗙顖Z.Q➷ꮨ뗇\u0004": "ꔙ䁼>n^[GीA䨟AM琢ᒊS쨲w?d㶣젊嘶纝麓+愣a%気ྞSc됓ᔘ:8bM7Xd8㶑臌]Ꙥ0ꐭ쒙䫣挵C薽Dfⵃ떼᷸", + "?紡.셪_෨j\u0013Ox┠$Xᶨ-ᅇo薹-}軫;y毝㪜K㣁?.EV쮱4둽⛻䤜'2盡\u001f60(|e쐰㼎ᦀ㒧-$l@ﻑ坳\u0003䭱响巗WFo5c㧆T턁Y맸♤(": -2.50917882560589088E17 + }} + ], + "侸\\릩.᳠뎠狣살cs项䭩畳H1s瀉븇19?.w骴崖㤊h痠볭㞳㞳䁮Ql怠㦵": "@䟴-=7f", + "鹟1x௢+d ;vi䭴FSDS\u0004hꎹ㚍?⒍⦏ў6u,扩@됷Su)Pag휛TᒗV痩!瞏釀ꖞ蘥&ೞ蘐ꭰꞇᝎ": "ah懱Ժ&\u20f7䵅♎඀䞧鿪굛ౕ湚粎蚵ᯋ幌YOE)५襦㊝Y*^\"R+ඈ咷蝶9ꥂ榨艦멎헦閝돶v좛咊E)K㓷ྭr", + "搆q쮦4綱켙셁.f4<\/g<籽늷?#蚴픘:fF\u00051㹉뀭.ᰖ풎f֦Hv蔎㧤.!䭽=鞽]음H:?\"-4": 8.740133984938656E-20 + }]} + } + ], + "tVKn딩꘥⊾蹓᤹{\u0003lR꼽ᄲQFᅏ傅ﱋ猢⤊ᔁ,E㓒秤nTතv`♛I\u0000]꫔ṞD\"麵c踝杰X&濿또꣹깳౥葂鿎\\aꡨ?": 3900062609292104525 + } + ], + "ਉ샒⊩Lu@S䧰^g": -1.1487677090371648E18, + "⎢k⑊꬗yᏫ7^err糎Dt\u000bJ礯확ㆍ沑サꋽe赔㝢^J\u0004笲㿋idra剰-᪉C錇/Ĝ䂾ညS지?~콮gR敉⬹'䧭": 1901472137232418266, + "灗k䶥:?촽贍쓉꓈㒸g獘[뵎\\胕?\u0014_榙p.j稶,$`糉妋0>Fᡰly㘽$?": "]ꙛO赎&#㠃돱剳\"<◆>0誉齐_|z|裵씪>ᐌ㼍\"Z[琕}O?G뚇諦cs⠜撺5cu痑U圲\u001c?鴴計l춥/╓哼䄗茏ꮅ뫈댽A돌롖뤫V窗讬sHd&\nOi;_u" + } + ], + "Uﺗ\\Y\\梷䄬~\u0002": null, + "k\"Y磓ᗔ휎@U冈<\/w컑)[": false, + "曏J蝷⌻덦\u001f㙳s꥓⍟邫P늮쥄c∬ྡྷ舆렮칤Z趣5콡넛A쳨\\뀙骫(棻.*&輛LiIfi{@EA婳KᬰTXT": -4.3088230431977587E17 + }]} + ] + ], + "곃㲧<\/dఓꂟs其ࡧ&N葶=?c㠤Ჴ'횠숄臼#\u001a~": false + } + ] + ]}] + }] + }} + ], + "2f`⽰E쵟>J笂裭!〛觬囀ۺ쟰#桊l鹛ⲋ|RA_Vx፭gE됓h﵀mfỐ|?juTU档[d⢼⺻p濚7E峿": 5613688852456817133 + }, + "濘끶g忮7㏵殬W팕Q曁 뫰)惃廊5%-蹚zYZ樭ﴷQ锘쯤崫gg": true, + "絥ᇑ⦏쒓븣爚H.㗊߄o蘵貆ꂚ(쎔O᥉ﮓ]姨Wꁓ!RMA|o퉢THx轮7M껁U즨'i뾘舯o": "跥f꜃?" + }} + ], + "鷰鹮K-9k;ﰰ?_ݦѷ-ꅣ䩨Zꥱ\"mꠟ屎/콑Y╘2&鸞脇㏢ꀇ࠺ⰼ拾喭틮L꽩bt俸墶 [l/웄\"꾦\u20d3iও-&+\u000fQ+໱뵞": -1.296494662286671E-19 + }, + "HX੹/⨇୕붷Uﮘ旧\\쾜͔3l鄈磣糂̖䟎Eᐳw橖b῀_딕hu葰窳闹вU颵|染H죶.fP䗮:j䫢\\b뎖i燕ꜚG⮠W-≚뉗l趕": "ଊ칭Oa᡺$IV㷧L\u0019脴셀붿餲햪$迳向쐯켂PqfT\" ?I屉鴼쿕@硙z^鏕㊵M}㚛T젣쓌-W⩐-g%⺵<뮱~빅╴瑿浂脬\u0005왦燲4Ⴭb|D堧 <\/oEQh", + "䘶#㥘੐캔f巋ἡAJ䢚쭈ࣨ뫒*mᇊK,ࣺAꑱ\u000bR<\/A\"1a6鵌㯀bh곿w(\"$ꘁ*rಐ趣.d࿩k/抶면䒎9W⊃9": "漩b挋Sw藎\u0000", + "畀e㨼mK꙼HglKb,\"'䤜": null + }]}] + ] + ] + }] + ]} + ] + ]} + ], + "歙>駿ꣂ숰Q`J΋方樛(d鱾뼣(뫖턭\u20f9lচ9歌8o]8윶l얶?镖G摄탗6폋폵+g:䱫홊<멀뀿/س|ꭺs걐跶稚W々c㫣⎖": "㣮蔊깚Cꓔ舊|XRf遻㆚︆'쾉췝\\&言", + "殭\"cށɨꝙ䞘:嬮e潽Y펪㳅/\"O@ࠗ겴]췖YǞ(t>R\"N?梳LD恭=n氯T豰2R諸#N}*灧4}㶊G䍣b얚": null, + "襞<\/啧 B|싞W瓇)6簭鼡艆lN쩝`|펭佡\\間邝[z릶&쭟愱ꅅ\\T᰽1鯯偐栈4̸s윜R7⒝/똽?치X": "⏊躖Cﱰ2Qẫ脐&இ?%냝悊", + ",鰧偵셣싹xᎹ힨᯳EṬH㹖9": -4604276727380542356 + } + } + ]]]], + "웺㚑xs}q䭵䪠馯8?LB犯zK'os䚛HZ\"L?셎s^㿧㴘Cv2": null + }] + ] + ] + ], + "Kd2Kv+|z": 7367845130646124107, + "ᦂⶨ?ᝢ 祂些ഷ牢㋇操\"腭䙾㖪\\(y4cE뽺ㆷ쫺ᔖ%zfۻ$ў1柦,㶢9r漢": -3.133230960444846E-20, + "琘M焀q%㢟f鸯O⣏蓑맕鯊$O噷|)z褫^㢦⠮ꚯ꫞`毕1qꢚ{ĭ䎀বώT\"뱘3G൴?^^of": null + } + ], + "a8V᯺?:ﺃ/8ꉿBq|9啓댚;*i2": null, + "cpT瀇H珰Ừpೃi鎪Rr␣숬-鹸ҩ䠚z脚цGoN8入y%趌I┽2ឪЀiJNcN)槣/▟6S숆牟\"箑X僛G殱娇葱T%杻:J諹昰qV쨰": 8331037591040855245 + }], + "G5ᩜ䄗巢껳": true + } + }, + "Ồ巢ゕ@_譙A`碫鄐㡥砄㠓(^K": "?܃B혢▦@犑ὺD~T⧁|醁;o=J牌9냚⢽㨘{4觍蚔9#$∺\u0016p囅\\3Xk阖⪚\"UzA穕롬✎➁㭒춺C㣌ဉ\"2瓑员ᅽꝶ뫍}꽚ꞇ鶂舟彺]ꍽJC蝧銉", + "␆Ě膝\"b-퉐ACR言J謈53~V튥x䜢?ꃽɄY뮩ꚜ": "K/↾e萃}]Bs⾿q룅鷦-膋?m+死^魊镲6", + "粡霦c枋AHퟁo礼Ke?qWcA趸㡔ꂏ?\u000e춂8iতᦜ婪\u0015㢼nﵿꍻ!ᐴ関\u001d5j㨻gfῩUK5Ju丝tかTI'?㓏t>⼟o a>i}ᰗ;뤕ܝ": false, + "ꄮ匴껢ꂰ涽+䜨B蛹H䛓-k蕞fu7kL谖,'涃V~챳逋穞cT\"vQ쓕ObaCRQ㓡Ⲯ?轭⫦輢墳?vA餽=h䮇킵n폲퉅喙?\"'1疬V嬗Qd灗'Lự": "6v!s믁㭟㣯獃!磸餠ቂh0C뿯봗F鷭gꖶ~コkK<ᦈTt\\跓w㭣횋钘ᆹ듡䑚W䟾X'ꅔ4FL勉Vܴ邨y)2'〚쭉⽵-鞣E,Q.?块", + "?(˧쩯@崟吋歄K": null + }, + "Gc럃녧>?2DYI鴿\\륨)澔0ᔬlx'觔7젘⤡縷螩%Sv׫묈/]↱&S h\u0006歋ᑛxi̘}ひY蔯_醨鯘煑橾8?䵎쨋z儬ꁏ*@츾:": null + } + } + } + ] + ] + ]} + }, + "HO츧G": 3.694949578823609E17, + "QC\u0012(翻曇Tf㷟bGBJ옉53\\嚇ᛎD/\u001b夾၉4\"핀@祎)쫆yD\"i먎Vn㿿V1W᨝䶀": -6150931500380982286, + "Z㓮P翸鍱鉼K䋞꘺튿⭁Y": -7704503411315138850, + "]모开ꬖP븣c霤<[3aΠ\"黁䖖䰑뮋ꤦ秽∼㑷冹T+YUt\"싳F↭䖏&鋌": -2.7231911483181824E18, + "tꎖ": -4.9517948741799555E-19, + "䋘즊.⬅IꬃۣQ챢ꄑ黐|f?C⾺|兕읯sC鬸섾整腨솷V": "旆柩l쪦sᖸMy㦅울썉瘗㎜檵9ꍂ駓ૉᚿ/u3씅徐拉[Z䞸ࡗ1ꆱ&Q풘?ǂ8\u0011BCDY2볨;鸏": null, + "幫 n煥s쁇펇 왊-$C\"衝:\u0014㣯舼.3뙗Yl⋇\"K迎멎[꽵s}9鉳UK8쐥\"掄㹖h㙈!얄સ?Ꜳ봺R伕UTD媚I䜘W鏨蔮": -4.150842714188901E-17, + "ﺯ^㄄\b죵@fྉkf颡팋Ꞧ{/Pm0V둳⻿/落韒ꊔᚬ@5螺G\\咸a谆⊪ቧ慷绖?财(鷇u錝F=r၍橢ឳn:^iᴵtD볠覅N赴": null + }] + }] + } + ] + ]} + ]}, + "謯?w厓奰T李헗聝ឍ貖o⪇弒L!캶$ᆅ": -4299324168507841322, + "뺊奉_垐浸延몏孄Z舰2i$q붿좾껇d▵餏\"v暜Ҭ섁m￴g>": -1.60911932510533427E18 + } + ] + } + ] + ]], + "퉝꺔㠦楶Pꅱ": 7517896876489142899, + "": false + } + ]}, + "是u&I狻餼|谖j\"7c됮sסּ-踳鉷`䣷쉄_A艣鳞凃*m⯾☦椿q㎭N溔铉tlㆈ^": 1.93547720203604352E18, + "kⲨ\\%vr#\u000bⒺY\\t<\/3﬌R訤='﹠8蝤Ꞵ렴曔r": false + } + ]}, + "阨{c?C\u001d~K?鎌Ԭ8烫#뙣P초遗t㭱E­돒䆺}甗[R*1!\\~h㕅᰺@<9JꏏષI䳖栭6綘걹ᅩM\"▯是∔v鬽顭⋊譬": "운ﶁK敂(欖C취پ℄爦賾" + } + }} + }], + "鷨赼鸙+\\䭣t圙ڹx᜾ČN<\/踘\"S_맶a鷺漇T彚⎲i㈥LT-xA캔$\u001cUH=a0츺l릦": "溣㣂0濕=鉵氬駘>Pꌢpb솇쬤h힊줎獪㪬CrQ矠a&脍꼬爼M茴/΅\u0017弝轼y#Ꞡc6둴=?R崏뷠麖w?" + }, + "閕ᘜ]CT)䵞l9z'xZF{:ؐI/躅匽졁:䟇AGF૸\u001cퟗ9)駬慟ꡒꆒRS״툋A<>\u0010\"ꂔ炃7g덚E৏bꅰ輤]o㱏_뷕ܘ暂\"u": "芢+U^+㢩^鱆8*1鈶鮀\u0002뺰9⬳ꪮlL䃣괟,G8\u20a8DF㉪錖0ㄤ瓶8Nଷd?眡GLc陓\\_죌V쁰ल二?c띦捱 \u0019JC\u0011b⤉zẒT볕\"绣蘨뚋cꡉkI\u001e鳴", + "ꃣI'{6u^㡃#཰Kq4逹y൒䧠䵮!㱙/n??{L풓ZET㙠퍿X2᩟綳跠葿㚙w཮x캽扳B唕S|尾}촕%N?o䪨": null, + "ⰴFjෟ셈[\u0018辷px?椯\\1<ﲻ栘ᣁ봢憠뉴p": -5263694954586507640 + } + ] + ]] + ]} + ]}] + ] + ], + "?#癘82禩鋆ꊝty?&": -1.9419029518535086E-19 + } + ] + ] + ]} + ] + ] + ], + "훊榲.|῕戄&.㚏Zꛦ2\"䢥ሆ⤢fV_摕婔?≍Fji冀탆꜕i㏬_ẑKᅢ꫄蔻XWc|饡Siẘ^㲦?羡2ぴ1縁ᙅ?쐉Ou": false + }]] + ]}}}, + "慂뗄卓蓔ᐓ匐嚖/颹蘯/翻ㆼL?뇊,텵<\\獷ごCボ": null + }, + "p溉ᑟi짣z:䒤棇r^٫%G9缑r砌롧.물农g?0׼ሩ4ƸO㣥㯄쩞ጩ": null, + "껎繥YxK\"F젷쨹뤤1wq轫o?鱑뜀瘊?뎃h灑\\ꛣ}K峐^ኖ⤐林ꉓhy": null + } + ], + "᱀n肓ㄛ\"堻2>m殮'1橌%Ꞵ군=Ӳ鯨9耛<\/n據0u彘8㬇៩f᏿诙]嚊": "䋯쪦S럶匏ㅛ#)O`ሀX_鐪渲⛀㨻宅闩➈ꢙஶDR⪍" + }, + "tA썓龇 ⋥bj왎录r땽✒롰;羋^\\?툳*┎?썀ma䵳넅U䳆૘〹䆀LQ0\b疀U~u$M}(鵸g⳾i抦뛹?䤈땚검.鹆?ꩡtⶥGĒ;!ቹHS峻B츪켏f5≺": 2366175040075384032, + "전pJjleb]ួ": -7.5418493141528422E18, + "n.鎖ጲ\n?,$䪘": true + }, + "欈Ar㉣螵᪚茩?O)": null + }, + "쫸M#x}D秱欐K=侫们丐.KꕾxẠ\u001e㿯䣛F܍캗qq8꟞ṢFD훎⵳簕꭛^鳜\u205c٫~⑟~冫ऊ2쫰<\/戲윱o<\"": true + }, + "㷝聥/T뱂\u0010锕|内䞇x侁≦㭖:M?iM᣿IJe煜dG࣯尃⚩gPt*辂.{磼럾䝪@a\\袛?}ᓺB珼": true + } + } + ]]}]}}, + "tn\"6ꫤ샾䄄;銞^%VBPwu묪`Y僑N.↺Ws?3C⤻9唩S䠮ᐴm;sᇷ냞඘B/;툥B?lB∤)G+O9m裢0kC햪䪤": -4.5941249382502277E18, + "ᚔt'\\愫?鵀@\\びꂕP큠<<]煹G-b!S?\nꖽ鼫,ݛ&頺y踦?E揆릱H}햧캡b@手.p탻>췽㣬ꒅ`qe佭P>ᓂ&?u}毚ᜉ蟶頳졪ᎏzl2wO": -2.53561440423275936E17 + }]} + } + ] + ]], + "潈촒⿂叡": 5495738871964062986 + } + ]] + } + ] + ]} + ]] + ]] + ]} + ] + ]}, + "ႁq킍蓅R`謈蟐ᦏ儂槐僻ﹶ9婌櫞釈~\"%匹躾ɢ뤥>࢟瀴愅?殕节/냔O✬H鲽엢?ᮈੁ⋧d␽㫐zCe*": 2.15062231586689536E17, + "㶵Ui曚珰鋪ᾼ臧P{䍏䷪쨑̟A뼿T渠誈䏚D1!잶<\/㡍7?)2l≣穷᛾稝{:;㡹nemיּ訊`G": null, + "䀕\"飕辭p圁f#뫆䶷뛮;⛴ᩍ3灚덏ᰝ쎓⦷詵%᜖Մfs⇫(\u001e~P|ﭗCⲾផv湟W첋(텪બT<บSꏉ੗⋲X婵i ӵ⇮?L䬇|ꈏ?졸": 1.548341247351782E-19 + } + ] + }, + "t;:N\u0015q鐦Rt缆{ꮐC?஛㷱敪\\+鲊㉫㓪몗릙竏(氵kYS": "XᰂT?൮ô", + "碕飦幑|+ 㚦鏶`镥ꁩ B<\/加륙": -4314053432419755959, + "秌孳(p!G?V傫%8ሽ8w;5鲗㦙LI檸\u2098": "zG N볞䆭鎍흘\\ONK3횙<\/樚立圌Q튅k쩎Ff쁋aׂJK銆ઘ즐狩6༥✙䩜篥CzP(聻駇HHퟲ讃%,ά{렍p而刲vy䦅ክ^톺M楒鍢㹳]Mdg2>䤉洞", + "踛M젧>忔芿㌜Zk": 2215369545966507819, + "씐A`$槭頰퍻^U覒\bG毲aᣴU;8!팲f꜇E⸃_卵{嫏羃X쀳C7뗮m(嚼u N܁谟D劯9]#": true, + "ﻩ!뵸-筚P᭛}ἰ履lPh?౮ⶹꆛ穉뎃g萑㑓溢CX뾇G㖬A錟]RKaꄘ]Yo+@䘁's섎襠$^홰}F": null + }, + "粘ꪒ4HXᕘ蹵.$區\r\u001d묁77pPc^y笲Q<\/ꖶ 訍䃍ᨕG?*": 1.73773035935040224E17 + }, + "婅拳?bkU;#D矠❴vVN쩆t㜷A풃갮娪a%鮏絪3dAv룒#tm쑬⌛qYwc4|L8KZ;xU⓭㳔밆拓EZ7襨eD|隰ऌ䧼u9Ԣ+]贴P荿": 2.9628516456987075E18 + }]}}] + ]} + }} + ]}] + ], + "|g翉F*湹̶\u0005⏐1脉̀eI쩓ᖂ㫱0碞l䴨ꑅ㵽7AtἈ턧yq䳥塑:z:遀ᄐX눔擉)`N3昛oQ셖y-ڨ⾶恢ꈵq^<\/": null, + "菹\\랓G^璬x৴뭸ゆUS겧﮷Bꮤ ┉銜᯻0%N7}~f洋坄Xꔼ<\/4妟Vꄟ9:౟곡t킅冩䧉笭裟炂4봋ⱳ叺怊t+怯涗\"0㖈Hq": false, + "졬믟'ﺇফ圪쓬멤m邸QLব䗁愍4jvs翙 ྍ꧀艳H-|": null, + "컮襱⣱뗠 R毪/鹙꾀%헳8&": -5770986448525107020 + } + ], + "B䔚bꐻ뙏姓展槰T-똌鷺tc灿᫽^㓟䏀o3o$꘭趙萬I顩)뇭Ἑ䓝\f@{ᣨ`x3蔛": null + } + ] + ] + }], + "⦖扚vWꃱ꥙㾠壢輓{-⎳鹷贏璿䜑bG倛⋐磎c皇皩7a~ﳫU╣Q࠭ꎉS摅姽OW.홌ೞ.": null, + "蚪eVlH献r}ᮏ믠ﰩꔄ@瑄ⲱ": null, + "퀭$JWoꩢg역쁍䖔㑺h&ୢtXX愰㱇?㾫I_6 OaB瑈q裿": null, + "꽦ﲼLyr纛Zdu珍B絟쬴糔?㕂짹䏵e": "ḱ\u2009cX9멀i䶛簆㳀k" + } + ]]]], + "(_ꏮg່澮?ᩑyM<艷\u001aꪽ\\庼뙭Z맷㰩Vm\\lY筺]3㋲2㌩㄀Eਟ䝵⨄쐨ᔟgङHn鐖⤇놋瓇Q탚單oY\"♆臾jHᶈ征ቄ??uㇰA?#1侓": null + }, + "觓^~ሢ&iI띆g륎ḱ캀.ᓡꀮ胙鈉": 1.0664523593012836E-19, + "y詭Gbᔶऽs댁U:杜⤎ϲ쁗⮼D醄诿q뙰I#즧v蔎xHᵿt᡽[**?崮耖p缫쿃L菝,봬ꤦC쯵#=X1瞻@OZc鱗CQTx": null + } + ] + }}], + "剘紁\u0004\\Xn⊠6,တױ;嵣崇}讃iႽ)d1\\䔓": null + }, + "脨z\"{X,1u찜<'k&@?1}Yn$\u0015Rd輲ーa쮂굄+B$l": true, + "諳>*쭮괐䵟Ґ+<箁}빀䅱⡔檏臒hIH脟ꩪC핝ଗP좕\"0i<\/C褻D۞恗+^5?'ꂱ䚫^7}㡠cq6\\쨪ꔞꥢ?纖䫀氮蒫侲빦敶q{A煲G": -6880961710038544266 + }}] + }, + "5s⨲JvಽῶꭂᄢI.a৊": null, + "?1q꽏쿻ꛋDR%U娝>DgN乭G": -1.2105047302732358E-19 + } + ] + ]}, + "qZz`撋뙹둣j碇쁏\\ꆥ\u0018@藴疰Wz)O{F䶛l᷂绘訥$]뮍夻䢋䩇萿獰樧猵⣭j萶q)$꬚⵷0馢W:Ⱍ!Qoe": -1666634370862219540, + "t": "=wp|~碎Q鬳Ӎ\\l-<\/^ﳊhn퐖}䍔t碵ḛ혷?靻䊗", + "邙쇡㯇%#=,E4勃驆V繚q[Y댻XV㡸[逹ᰏ葢B@u=JS5?bLRn얮㍉⏅ﰳ?a6[&큟!藈": 1.2722786745736667E-19 + }, + "X블땨4{ph鵋ꉯ웸 5p簂䦭s_E徔濧d稝~No穔噕뽲)뉈c5M윅>⚋[岦䲟懷恁?鎐꓆ฬ爋獠䜔s{\u001bm鐚儸煛%bﯿXT>ꗘ@8G": 1157841540507770724, + "媤娪Q杸\u0011SAyᡈ쿯": true, + "灚^ಸ%걁<\/蛯?\"祴坓\\\\'흍": -3.4614808555942579E18, + "釴U:O湛㴑䀣렑縓\ta)(j:숾却䗌gCiB뽬Oyuq輥厁/7)?今hY︺Q": null + } + ] + ]]]}] + ], + "I笔趠Ph!<ཛྷ㸞诘X$畉F\u0005笷菟.Esr릙!W☆䲖뗷莾뒭U\"䀸犜Uo3Gꯌx4r蔇᡹㧪쨢準<䂀%ࡡꟼ瑍8炝Xs0䀝销?fi쥱ꆝલBB": -8571484181158525797, + "L⦁o#J|\"⽩-㱢d㌛8d\\㶤傩儻E[Y熯)r噤὘勇 }": "e(濨쓌K䧚僒㘍蠤Vᛸ\"络QJL2,嬓왍伢㋒䴿考澰@(㏾`kX$끑эE斡,蜍&~y", + "vj.|统圪ᵮPL?2oŶ`밧\"勃+0ue%⿥绬췈체$6:qa렐Q;~晘3㙘鹑": true, + "ශؙ4獄⶿c︋i⚅:ん閝Ⳙ苆籦kw{䙞셕pC췃ꍬ␜꟯ꚓ酄b힝hwk꭭M鬋8B耳쑘WQ\\偙ac'唀x᪌\u2048*h짎#ፇ鮠뾏ឿ뀌": false, + "⎀jꄒ牺3Ⓝ컴~?親ꕽぼܓ喏瘘!@<튋㐌꿱⩦{a?Yv%⪧笯Uܱ栅E搚i뚬:ꄃx7䙳ꦋ&䓹vq☶I䁘ᾘ涜\\썉뺌Lr%Bc㍜3?ꝭ砿裞]": null, + "⭤뙓z(㡂%亳K䌽꫿AԾ岺㦦㼴輞낚Vꦴw냟鬓㹈뽈+o3譻K1잞": 2091209026076965894, + "ㇲ\t⋇轑ꠤ룫X긒\"zoY읇희wj梐쐑l侸`e%s": -9.9240075473576563E17, + "啸ꮑ㉰!ᚓ}銏": -4.0694813896301194E18, + ">]囋੽EK뇜>_ꀣ緳碖{쐐裔[<ನ\"䇅\"5L?#xTwv#罐\u0005래t应\\N?빗;": "v쮽瞭p뭃" + } + ]], + "斴槾?Z翁\"~慍弞ﻆ=꜡o5鐋dw\"?K蠡i샾ogDﲰ_C*⬟iㇷ4nય蟏[㟉U꽌娛苸 ঢ়操贻洞펻)쿗૊許X⨪VY츚Z䍾㶭~튃ᵦ<\/E臭tve猑x嚢": null, + "锡⛩<\/칥ꈙᬙ蝀&Ꚑ籬■865?_>L詏쿨䈌浿弥爫̫lj&zx<\/C쉾?覯n?": null, + "꾳鑤/꼩d=ᘈn挫ᑩ䰬ZC": "3錢爋6Ƹ䴗v⪿Wr益G韠[\u0010屗9쁡钁u?殢c䳀蓃樄욂NAq赟c튒瘁렶Aૡɚ捍" + } + ] + ] + ]} + ] + ] + }]]]}} + ]}], + "Ej䗳U<\/Q=灒샎䞦,堰頠@褙g_\u0003ꤾfⶽ?퇋!łB〙ד3CC䌴鈌U:뭔咎(Qો臃䡬荋BO7㢝䟸\"Yb": 2.36010731779814E-20, + "逸'0岔j\u000e눘먷翌C츊秦=ꭣ棭ှ;鳸=麱$XP⩉駚橄A\\좱⛌jqv䰞3Ь踌v㳆¹gT┌gvLB賖烡m?@E঳i": null + }, + "曺v찘ׁ?&绫O័": 9107241066550187880 + } + ] + ], + "(e屄\u0019昜훕琖b蓘ᬄ0/۲묇Z蘮ဏ⨏蛘胯뢃@㘉8ሪWᨮ⦬ᅳ䅴HI၇쨳z囕陻엣1赳o": true, + ",b刈Z,ၠ晐T솝ŕB⩆ou'퐼≃绗雗d譊": null, + "a唥KB\"ﳝ肕$u\n^⅄P䟼냉䞸⩪u윗瀱ꔨ#yşs꒬=1|ﲤ爢`t౐튼쳫_Az(Ṋ擬㦷좕耈6": 2099309172767331582, + "?㴸U<\/䢔ꯡ阽扆㐤q鐋?f㔫wM嬙-;UV죫嚔픞G&\"Cᗍ䪏풊Q": "VM7疹+陕枡툩窲}翡䖶8欞čsT뮐}璤:jﺋ鎴}HfA൝⧻Zd#Qu茅J髒皣Y-︴[?-~쉜v딏璮㹚䅊﩯<-#\u000e걀h\u0004u抱﵊㼃U<㱷⊱IC進" + }, + "숌dee節鏽邺p넱蹓+e罕U": true + } + ], + "b⧴룏??ᔠ3ぱ>%郿劃翐ꏬꠛW瞳᫏누躨狀ໄy੽\"ីuS=㨞馸k乆E": "トz݈^9R䬑<ﮛGRꨳ\u000fTT泠纷꽀MRᴱ纊:㠭볮?%N56%鈕1䗍䜁a䲗j陇=뿻偂衋࿘ᓸ?ᕵZ+<\/}H耢b䀁z^f$&㝒LkꢳI脚뙛u": 5.694374481577558E-20 + }] + } + ]], + "obj": {"key": "wrong value"}, + "퓲꽪m{㶩/뇿#⼢&᭙硞㪔E嚉c樱㬇1a綑᝖DḾ䝩": null + }, + "key": "6.908319653520691E8", + "z": { + "6U閆崬밺뀫颒myj츥휘:$薈mY햚#rz飏+玭V㭢뾿愴YꖚX亥ᮉ푊\u0006垡㐭룝\"厓ᔧḅ^Sqpv媫\"⤽걒\"˽Ἆ?ꇆ䬔未tv{DV鯀Tἆl凸g\\㈭ĭ즿UH㽤": null, + "b茤z\\.N": [[ + "ZL:ᅣዎ*Y|猫劁櫕荾Oj为1糕쪥泏S룂w࡛Ᏺ⸥蚙)", + { + "\"䬰ỐwD捾V`邀⠕VD㺝sH6[칑.:醥葹*뻵倻aD\"": true, + "e浱up蔽Cr෠JK軵xCʨ<뜡癙Y獩ケ齈X/螗唻?<蘡+뷄㩤쳖3偑犾&\\첊xz坍崦ݻ鍴\"嵥B3㰃詤豺嚼aqJ⑆∥韼@\u000b㢊\u0015L臯.샥": false, + "l?Ǩ喳e6㔡$M꼄I,(3᝝縢,䊀疅뉲B㴔傳䂴\u0088㮰钘ꜵ!ᅛ韽>": -5514085325291784739, + "o㮚?\"춛㵉<\/﬊ࠃ䃪䝣wp6ἀ䱄[s*S嬈貒pᛥ㰉'돀": [{ + "(QP윤懊FI<ꃣ『䕷[\"珒嶮?%Ḭ壍಻䇟0荤!藲끹bd浶tl\u2049#쯀@僞": {"i妾8홫": { + ",M맃䞛K5nAㆴVN㒊햬$n꩑&ꎝ椞阫?/ṏ세뉪1x쥼㻤㪙`\"$쟒薟B煌܀쨝ଢ଼2掳7㙟鴙X婢\u0002": "Vዉ菈᧷⦌kﮞఈnz*﷜FM\"荭7ꍀ-VR<\/';䁙E9$䩉\f @s?퍪o3^衴cඎ䧪aK鼟q䆨c{䳠5mᒲՙ蘹ᮩ": { + "F㲷JGo⯍P덵x뒳p䘧☔\"+ꨲ吿JfR㔹)4n紬G练Q፞!C|": true, + "p^㫮솎oc.೚A㤠??r\u000f)⾽⌲們M2.䴘䩳:⫭胃\\፾@Fᭌ\\K": false, + "蟌Tk愙潦伩": { + "a<\/@ᾛ慂侇瘎": -7271305752851720826, + "艓藬/>၄ṯ,XW~㲆w": {"E痧郶)㜓ha朗!N赻瞉駠uC\u20ad辠x퓮⣫P1ࠫLMMX'M刼唳됤": null, + "P쓫晥%k覛ዩIUᇸ滨:噐혲lMR5䋈V梗>%幽u頖\\)쟟": null, + "eg+昉~矠䧞难\b?gQ쭷筝\\eꮠNl{ಢ哭|]Mn銌╥zꖘzⱷ⭤ᮜ^": [ + -1.30142114406914976E17, + -1.7555215491128452E-19, + null, + "渾㨝ߏ牄귛r?돌?w[⚞ӻ~廩輫㼧/", + -4.5737191805302129E18, + null, + "xy࿑M[oc셒竓Ⓔx?뜓y䊦>-D켍(&&?XKkc꩖ﺸᏋ뵞K伕6ী)딀P朁yW揙?훻魢傎EG碸9類៌g踲C⟌aEX舲:z꒸许", + 3808159498143417627, + null, + {"m試\u20df1{G8&뚈h홯J<\/": { + "3ஸ厠zs#1K7:rᥞoꅔꯧ&띇鵼鞫6跜#赿5l'8{7㕳(b/j\"厢aq籀ꏚ\u0015厼稥": [ + -2226135764510113982, + true, + null, + { + "h%'맞S싅Hs&dl슾W0j鿏MםD놯L~S-㇡R쭬%": null, + "⟓咔謡칲\u0000孺ꛭx旑檉㶆?": null, + "恇I転;￸B2Y`z\\獓w,놏濐撐埵䂄)!䶢D=ഭ㴟jyY": { + "$ࡘt厛毣ൢI芁<겿骫⫦6tr惺a": [ + 6.385779736989334E-20, + false, + true, + true, + [ + -6.891946211462334E-19, + null, + { + "]-\\Ꟑ1/薓❧Ὂ\\l牑\u0007A郃)阜ᇒᓌ-塯`W峬G}SDb㬨Q臉⮻빌O鞟톴첂B㺱<ƈmu챑J㴹㷳픷Oㆩs": { + "\"◉B\"pᶉt骔J꩸ᄇᛐi╰栛K쉷㉯鐩!㈐n칍䟅難>盥y铿e୔蒏M貹ヅ8嘋퀯䉶ጥ㏢殊뻳\"絧╿ꉑ䠥?∃蓊{}㣣Gk긔H1哵峱": false, + "6.瀫cN䇮F㧺?\\椯=ڈT䘆4␘8qv": -3.5687501019676885E-19, + "Q?yऴr혴{஀䳘p惭f1ﹸ䅷䕋贲<ྃᄊ繲hq\\b|#QSTs1c-7(䵢\u2069匏絘ꯉ:l毴汞t戀oෟᵶ뮱፣-醇Jx䙬䐁햢0࣫ᡁgrㄛ": "\u0011_xM/蘇Chv;dhA5.嗀绱V爤ﰦi뵲M", + "⏑[\"ugoy^儣횎~U\\섯겜論l2jw஌yD腅̂\u0019": true, + "ⵯɇ䐲᫿࢚!㯢l샅笶戮1꣖0Xe": null, + "劅f넀識b宁焊E찓橵G!ʱ獓뭔雩괛": [{"p⹣켙[q>燣䍃㞽ᩲx:쓤삘7玑퇼0<\/q璂ᑁ[Z\\3䅵䧳\u0011㤧|妱緒C['췓Yꞟ3Z鳱雼P錻BU씧U`ᢶg蓱>.1ӧ譫'L_5V䏵Ц": [ + false, + false, + {"22䂍盥N霂얢躰e9⑩_뵜斌n@B}$괻Yᐱ@䧋V\"☒-諯cV돯ʠ": true, + "Ű螧ᔼ檍鍎땒딜qꄃH뜣<獧ूCY吓⸏>XQ㵡趌o끬k픀빯a(ܵ甏끆୯/6Nᪧ}搚ᆚ짌P牰泱鈷^d꣟#L삀\"㕹襻;k㸊\\f+": true, + "쎣\",|⫝̸阊x庿k잣v庅$鈏괎炔k쬪O_": [ + "잩AzZGz3v愠ꉈⵎ?㊱}S尳௏p\r2>췝IP䘈M)w|\u000eE", + -9222726055990423201, + null, + [ + false, + {"´킮'뮤쯽Wx讐V,6ᩪ1紲aႈ\u205czD": [ + -930994432421097536, + 3157232031581030121, + "l貚PY䃛5@䭄귻m㎮琸f": 1.0318894506812084E-19, + "࢜⩢Ш䧔1肽씮+༎ᣰ闺馺窃䕨8Mƶq腽xc(៯夐J5굄䕁Qj_훨/~価.䢵慯틠퇱豠㼇Qﵘ$DuSp(8Uญ<\/ಟ룴𥳐ݩ$": 8350772684161555590, + "ㆎQ䄾\u001bpᩭ${[諟^^骴᤮b^ㅥI┧T㉇⾞\"绦r䰂f矩'-7䡭桥Dz兔V9谶居㺍ᔊ䩯덲.\u001eL0ὅㅷ釣": [{ + "<쯬J卷^숞u࠯䌗艞R9닪g㐾볎a䂈歖意:%鐔|ﵤ|y}>;2,覂⶚啵tb*仛8乒㓶B࿠㯉戩oX 貘5V嗆렽낁߼4h䧛ꍺM空\\b꿋貼": 8478577078537189402, + "VD*|吝z~h譺aᯒ": { + "YI췢K<\/濳xNne玗rJo쾘3핰鴊\"↱AR:ࢷ\"9?\"臁說)?誚ꊏe)_D翾W?&F6J@뺾ꍰNZ醊Z쾈വH嶿?炫㷱鬰M겈᭨b,⻁鈵P䕡䀠८ⱄ홎鄣": { + "@?k2鶖㋮\"Oರ K㨇廪儲\u0017䍾J?);\b*묀㗠섳햭1MC V": null, + "UIICP!BUA`ᢈ㋸~袩㗪⾒=fB﮴l1ꡛ죘R辂여ҳ7쮡<䩲`熕8頁": 4481809488267626463, + "Y?+8먙ᚔ鋳蜩럶1㥔y璜౩`": [ + null, + 1.2850335807501874E-19, + "~V2", + 2035406654801997866, + { + "<숻1>\"": -8062468865199390827, + "M㿣E]}qwG莎Gn᝶(ꔙ\\D⬲iꇲs寢t駇S뀡ꢜ": false, + "pꝤ㎏9W%>M;-U璏f(^j1?&RB隧 忓b똊E": "#G?C8.躬ꥯ'?냪#< 渟&헿란zpo왓Kj}鷧XﻘMツb䕖;㪻", + "vE풤幉xz뱕쫥Ug㦲aH} ᣟp:鬼YᰟH3镔ᴚ斦\\鏑r*2橱G⼔F/.j": true, + "RK좬뎂a홠f*f㱉ᮍ⦋潙㨋Gu곌SGI3I뿐\\F',)t`荁蘯囯ﮉ裲뇟쥼_ገ驪▵撏ᕤV": 1.52738225997956557E18, + "^k굲䪿꠹B逤%F㱢漥O披M㽯镞竇霒i꼂焅륓\u00059=皫之눃\u2047娤閍銤唫ၕb<\/w踲䔼u솆맚,䝒ᝳ'/it": "B餹饴is権ꖪ怯ꦂẉဎt\"!凢谵⧿0\\<=(uL䷍刨쑪>俆揓Cy襸Q힆䆭涷<\/ᐱ0ɧ䗾䚹\\ኜ?ꄢᇘ`䴢{囇}᠈䴥X4퓪檄]ꥷ/3謒ሴn+g騍X", + "GgG꽬[(嫓몍6\u0004궍宩㙻/>\u0011^辍dT腪hxǑ%ꊇk,8(W⧂結P鬜O": [{ + "M㴾c>\\ᓲ\u0019V{>ꤩ혙넪㭪躂TS-痴໸闓⍵/徯O.M㏥ʷD囎⧔쁳휤T??鉬뇙=#ꢫ숣BX䭼<\/d똬졬g榿)eꨋﯪ좇첻\u001a\u0011\";~쓆BH4坋攊7힪", + "iT:L闞椕윚*滛gI≀Wਟඊ'ꢆ縺뱹鮚Nꩁ᧬蕼21줧\\䋯``⍐\\㏱鳨": 1927052677739832894, + "쮁缦腃g]礿Y㬙 fヺSɪ꾾N㞈": [ + null, + null, + { + "!t,灝Y 1䗉罵?c饃호䉂Cᐭ쒘z(즽sZG㬣sഖE4뢜㓕䏞丮Qp簍6EZឪ겛fx'ꩱQ0罣i{k锩*㤴㯞r迎jTⲤ渔m炅肳": [ + -3.3325685522591933E18, + [{"㓁5]A䢕1룥BC?Ꙍ`r룔Ⳛ䙡u伲+\u0001്o": [ + null, + 4975309147809803991, + null, + null, + {"T팘8Dﯲ稟MM☻㧚䥧/8ﻥ⥯aXLaH\"顾S☟耲ît7fS෉놁뮔/ꕼ䓈쁺4\\霶䠴ᩢ<\/t4?죵>uD5➶༆쉌럮⢀秙䘥\u20972ETR3濡恆vB? ~鸆\u0005": { + "`閖m璝㥉b뜴?Wf;?DV콜\u2020퍉౓擝宏ZMj3mJ먡-傷뱙yח㸷꥿ ໘u=M읝!5吭L4v\\?ǎ7C홫": null, + "|": false, + "~Ztᛋ䚘\\擭㗝傪W陖+㗶qᵿ蘥ᙄp%䫎)}=⠔6ᮢS湟-螾-mXH?cp": 448751162044282216, + "\u209fad놹j檋䇌ᶾ梕㉝bוּ": {"?苴ꩠD䋓帘5騱qﱖPF?☸珗顒yU ᡫcb䫎 S@㥚gꮒ쎘泴멖\\:I鮱TZ듒ᶨQ3+f7캙\"?\f풾\\o杞紟﻽M.⏎靑OP": [ + -2.6990368911551596E18, + [{"䒖@<᰿<\/⽬tTr腞&G%᳊秩蜰擻f㎳?S㵧\r*k뎾-乢겹隷j軛겷0룁鮁": {")DO0腦:춍逿:1㥨่!蛍樋2": [{ + ",ꌣf侴笾m๫ꆽ?1?U?\u0011ꌈꂇ": { + "x捗甠nVq䅦w`CD⦂惺嘴0I#vỵ} \\귂S끴D얾?Ԓj溯\"v餄a": { + "@翙c⢃趚痋i\u0015OQ⍝lq돆Y0pࢥ3쉨䜩^<8g懥0w)]䊑n洺o5쭝QL댊랖L镈Qnt⪟㒅십q헎鳒⮤眉ᔹ梠@O縠u泌ㄘb榚癸XޔFtj;iC": false, + "I&뱋゘|蓔䔕측瓯%6ᗻHW\\N1貇#?僐ᗜgh᭪o'䗈꽹Rc욏/蔳迄༝!0邔䨷푪8疩)[쭶緄㇈୧ፐ": { + "B+:ꉰ`s쾭)빼C羍A䫊pMgjdx䐝Hf9᥸W0!C樃'蘿f䫤סи\u0017Jve? 覝f둀⬣퓉Whk\"஼=չﳐ皆笁BIW虨쫓F廰饞": -642906201042308791, + "sb,XcZ<\/m㉹ ;䑷@c䵀s奤⬷7`ꘖ蕘戚?Feb#輜}p4nH⬮eKL트}": [ + "RK鳗z=袤Pf|[,u욺", + "Ẏᏻ罯뉋⺖锅젯㷻{H䰞쬙-쩓D]~\u0013O㳢gb@揶蔉|kᦂ❗!\u001ebM褐sca쨜襒y⺉룓", + null, + null, + true, + -1.650777344339075E-19, + false, + "☑lꄆs힨꤇]'uTന⌳농].1⋔괁沰\"IWഩ\u0019氜8쟇䔻;3衲恋,窌z펏喁횗?4?C넁问?ᥙ橭{稻Ⴗ_썔", + "n?]讇빽嗁}1孅9#ꭨ靶v\u0014喈)vw祔}룼쮿I", + -2.7033457331882025E18, + { + ";⚃^㱋x:饬ኡj'꧵T☽O㔬RO婎?향ᒭ搩$渣y4i;(Q>꿘e8q": "j~錘}0g;L萺*;ᕭꄮ0l潛烢5H▄쳂ꏒוֹꙶT犘≫x閦웧v", + "~揯\u2018c4職렁E~ᑅቚꈂ?nq뎤.:慹`F햘+%鉎O瀜쟏敛菮⍌浢<\/㮺紿P鳆ࠉ8I-o?#jﮨ7v3Dt赻J9": null, + "ࣝW䌈0ꍎqC逖,횅c၃swj;jJS櫍5槗OaB>D踾Y": {"㒰䵝F%?59.㍈cᕨ흕틎ḏ㋩B=9IېⓌ{:9.yw}呰ㆮ肒᎒tI㾴62\"ዃ抡C﹬B<\/촋jo朣", + [ + -7675533242647793366, + {"ᙧ呃:[㒺쳀쌡쏂H稈㢤\u001dᶗGG-{GHྻຊꡃ哸䵬;$?&d\\⥬こN圴됤挨-'ꕮ$PU%?冕눖i魁q騎Q": [ + false, + [[ + 7929823049157504248, + [[ + true, + "Z菙\u0017'eꕤ᱕l,0\\X\u001c[=雿8蠬L<\/낲긯W99g톉4ퟋb㝺\u0007劁'!麕Q궈oW:@X၎z蘻m絙璩귓죉+3柚怫tS捇蒣䝠-擶D[0=퉿8)q0ٟ", + "唉\nFA椭穒巯\\䥴䅺鿤S#b迅獘 ﶗ꬘\\?q1qN犠pX꜅^䤊⛤㢌[⬛휖岺q唻ⳡ틍\"㙙Eh@oA賑㗠y必Nꊑᗘ", + -2154220236962890773, + -3.2442003245397908E18, + "Wᄿ筠:瘫퀩?o貸q⊻(᎞KWf宛尨h^残3[U(='橄", + -7857990034281549164, + 1.44283696979059942E18, + null, + {"ꫯAw跭喀 ?_9\"Aty背F=9缉ྦྷ@;?^鞀w:uN㘢Rỏ": [ + 7.393662029337442E15, + 3564680942654233068, + [ + false, + -5253931502642112194, + "煉\\辎ೆ罍5⒭1䪁䃑s䎢:[e5}峳ﴱn騎3?腳Hyꏃ膼N潭錖,Yᝋ˜YAၓ㬠bG렣䰣:", + true, + null, + { + "⒛'P&%죮|:⫶춞": -3818336746965687085, + "钖m<\/0ݎMtF2Pk=瓰୮洽겎.": [[ + -8757574841556350607, + -3045234949333270161, + null, + { + "Ꮬr輳>⫇9hU##w@귪A\\C 鋺㘓ꖐ梒뒬묹㹻+郸嬏윤'+g<\/碴,}ꙫ>손;情d齆J䬁ຩ撛챝탹/R澡7剌tꤼ?ặ!`⏲睤\u00002똥଴⟏": null, + "\u20f2ܹe\\tAꥍư\\x当뿖렉禛;G檳ﯪS૰3~㘠#[J<}{奲 5箉⨔{놁<\/釿抋,嚠/曳m&WaOvT赋皺璑텁": [[ + false, + null, + true, + -5.7131445659795661E18, + "萭m䓪D5|3婁ఞ>蠇晼6nﴺPp禽羱DS<睓닫屚삏姿", + true, + [ + -8759747687917306831, + { + ">ⓛ\t,odKr{䘠?b퓸C嶈=DyEᙬ@ᴔ쨺芛髿UT퓻春<\/yꏸ>豚W釺N뜨^?꽴﨟5殺ᗃ翐%>퍂ဿ䄸沂Ea;A_\u0005閹殀W+窊?Ꭼd\u0013P汴G5썓揘": 4.342729067882445E-18, + "Q^즾眆@AN\u0011Kb榰냎Y#䝀ꀒᳺ'q暇睵s\"!3#I⊆畼寤@HxJ9": false, + "⿾D[)袨㇩i]웪䀤ᛰMvR<蟏㣨": {"v퇓L㪱ꖣ豛톤\\곱#kDTN": [{ + "(쾴䡣,寴ph(C\"㳶w\"憳2s馆E!n!&柄<\/0Pꈗſ?㿳Qd鵔": {"娇堰孹L錮h嵅⛤躏顒?CglN束+쨣ﺜ\\MrH": {"獞䎇둃ቲ弭팭^ꄞ踦涟XK錆쳞ឌ`;੶S炥騞ଋ褂B៎{ڒ䭷ᶼ靜pI荗虶K$": [{"◖S~躘蒉꫿輜譝Q㽙闐@ᢗ¥E榁iء5┄^B[絮跉ᰥ遙PWi3wㄾⵀDJ9!w㞣ᄎ{듒ꓓb6\\篴??c⼰鶹⟧\\鮇ꮇ": [[ + 654120831325413520, + -1.9562073916357608E-19, + { + "DC(昐衵ἡ긙갵姭|֛[t": 7.6979110359897907E18, + "J␅))嫼❳9Xfd飉j7猬ᩉ+⤻眗벎E鰉Zᄊ63zၝ69}ZᶐL崭ᦥ⡦靚⋛ꎨ~i㨃咊ꧭo䰠阀3C(": -3.5844809362512589E17, + "p꣑팱쒬ꎑ뛡Ꙩ挴恍胔&7ᔈ묒4Hd硶훐㎖zꢼ豍㿢aሃ=<\/湉鵲EӅ%$F!퍶棌孼{O駍਺geu+": ")\u001b잓kŀX쩫A밁®ڣ癦狢)扔弒p}k縕ꩋ,䃉tࣼi", + "ァF肿輸<솄G-䢹䛸ꊏl`Tqꕗ蒞a氷⸅ᴉ蠰]S/{J왲m5{9.uέ~㕚㣹u>x8U讁B덺襪盎QhVS맅킃i识{벂磄Iහ䙅xZy/抍૭Z鲁-霳V据挦ℒ": null, + "㯛|Nꐸb7ⵐb?拠O\u0014ކ?-(EꞨ4ꕷᄤYᯕOW瞺~螸\"욿ќe㺰\"'㌢ƐW\u0004瞕>0?V鷵엳": true, + "뤥G\\迋䠿[庩'꼡\u001aiᩮV쯁ᳪ䦪Ô;倱ନ뛁誈": null, + "쥹䄆䚟Q榁䎐᢭<\/2㕣p}HW蟔|䃏꿈ꚉ锳2Pb7㙑Tⅹᵅ": { + "Y?֭$>#cVBꩨ:>eL蒁務": { + "86柡0po 䏚&-捑Ћ祌<\/휃-G*㶢הּ쩍s㶟餇c걺yu꽎還5*턧簕Og婥SꝐ": null, + "a+葞h٥ࠆ裈嗫ﵢ5輙퀟ᛜ,QDﹼ⟶Y騠锪E_|x죗j侵;m蜫轘趥?븅w5+mi콛L": { + ";⯭ﱢ!买F⽍柤鶂n䵣V㫚墱2렾ELEl⣆": [ + true, + -3.6479311868339015E-18, + -7270785619461995400, + 3.334081886177621E18, + 2.581457786298155E18, + -6.605252412954115E-20, + -3.9232347037744167E-20, + { + "B6㊕.k1": null, + "ZAꄮJ鮷ᳱo갘硥鈠䠒츼": { + "ᕅ}럡}.@y陪鶁r業'援퀉x䉴ﵴl퍘):씭脴ᥞhiꃰblﲂ䡲엕8߇M㶭0燋標挝-?PCwe⾕J碻Ᾱ䬈䈥뷰憵賣뵓痬+": {"a췩v礗X⋈耓ፊf罅靮!㔽YYᣓw澍33⎔芲F|\"䜏T↮輦挑6ᓘL侘?ᅥ]덆1R௯✎餘6ꏽ<\/௨\\?q喷ꁫj~@ulq": {"嗫欆뾔Xꆹ4H㌋F嵧]ࠎ]㠖1ꞤT<$m뫏O i댳0䲝i": {"?෩?\u20cd슮|ꯆjs{?d7?eNs⢚嫥氂䡮쎱:鑵롟2hJꎒﯭ鱢3춲亄:뼣v䊭諱Yj択cVmR䩃㘬T\"N홝*ै%x^F\\_s9보zz4淗?q": [ + null, + "?", + 2941869570821073737, + "{5{殇0䝾g6밖퍋臩綹R$䖭j紋釰7sXI繳漪행y", + false, + "aH磂?뛡#惇d婅?Fe,쐘+늵䍘\"3r瘆唊勐j⳧࠴ꇓ<\/唕윈x⬌讣䋵%拗ᛆⰿ妴᝔M2㳗必꧂淲?ゥ젯檢<8끒MidX䏒3᳻Q▮佐UT|⤪봦靏⊏", + [[{ + "颉(&뜸귙{y^\"P퟉춝Ჟ䮭D顡9=?}Y誱<$b뱣RvO8cH煉@tk~4ǂ⤧⩝屋SS;J{vV#剤餓ᯅc?#a6D,s": [ + -7.8781018564821536E16, + true, + [ + -2.28770899315832371E18, + false, + -1.0863912140143876E-20, + -6282721572097446995, + 6767121921199223078, + -2545487755405567831, + false, + null, + -9065970397975641765, + [ + -5.928721243413937E-20, + {"6촊\u001a홯kB0w撨燠룉{绎6⳹!턍贑y▾鱧ժ[;7ᨷ∀*땒䪮1x霆Hᩭ☔\"r䝐7毟ᝰr惃3ꉭE+>僒澐": [ + "Ta쎩aƝt쵯ⰪVb", + [ + -5222472249213580702, + null, + -2851641861541559595, + null, + 4808804630502809099, + 5657671602244269874, + "5犲﨣4mᥣ?yf젫꾯|䋬잁$`Iⳉﴷ扳兝,'c", + false, + [ + null, + { + "DyUIN쎾M仼惀⮥裎岶泭lh扠\u001e礼.tEC癯튻@_Qd4c5S熯A<\/\6U윲蹴Q=%푫汹\\\u20614b[௒C⒥Xe⊇囙b,服3ss땊뢍i~逇PA쇸1": -2.63273619193485312E17, + "Mq꺋貘k휕=nK硍뫞輩>㾆~἞ࡹ긐榵l⋙Hw뮢帋M엳뢯v⅃^": 1877913476688465125, + "ᶴ뻗`~筗免⚽টW˃⽝b犳䓺Iz篤p;乨A\u20ef쩏?疊m㝀컩뫡b탔鄃ᾈV(遢珳=뎲ିeF仢䆡谨8t0醄7㭧瘵⻰컆r厡궥d)a阄፷Ed&c﯄伮1p": null, + "⯁w4曢\"(欷輡": "\"M᭫]䣒頳B\\燧ࠃN㡇j姈g⊸⺌忉ꡥF矉স%^", + "㣡Oᄦ昵⫮Y祎S쐐級㭻撥>{I$": -378474210562741663, + "䛒掷留Q%쓗1*1J*끓헩ᦢ﫫哉쩧EↅIcꅡ\\?ⴊl귛顮4": false, + "寔愆샠5]䗄IH贈=d﯊/偶?ॊn%晥D視N򗘈'᫂⚦|X쵩넽z질tskxDQ莮Aoﱻ뛓": true, + "钣xp?&\u001e侉/y䴼~?U篔蘚缣/I畚?Q绊": -3034854258736382234, + "꺲໣眀)⿷J暘pИfAV삕쳭Nꯗ4々'唄ⶑ伻㷯騑倭D*Ok꧁3b␽_<\/챣Xm톰ၕ䆄`*fl㭀暮滠毡?": [ + "D男p`V뙸擨忝븪9c麺`淂⢦Yw⡢+kzܖ\fY1䬡H歁)벾Z♤溊-혰셢?1<-\u0005;搢Tᐁle\\ᛵߓﭩ榩訝-xJ;巡8깊蠝ﻓU$K": { + "Vꕡ諅搓W=斸s︪vﲜ츧$)iꡟ싉e寳?ጭムVથ嵬i楝Fg<\/Z|៪ꩆ-5'@ꃱ80!燱R쇤t糳]罛逇dṌ֣XHiͦ{": true, + "Ya矲C멗Q9膲墅携휻c\\딶G甔<\/.齵휴": -1.1456247877031811E-19, + "z#.OO￝J": -8263224695871959017, + "崍_3夼ᮟ1F븍뽯ᦓ鴭V豈Ь": [{ + "N蒬74": null, + "yuB?厅vK笗!ᔸcXQ旦컶P-녫mᄉ麟_": "1R@ 톘xa_|﩯遘s槞d!d껀筤⬫薐焵먑D{\\6k共倌☀G~AS_D\"딟쬚뮥馲렓쓠攥WTMܭ8nX㩴䕅檹E\u0007ﭨN 2 ℆涐ꥏ꠵3▙玽|됨_\u2048", + "恐A C䧩G": {":M큣5e들\\ꍀ恼ᔄ靸|I﨏$)n": { + "|U䬫㟯SKV6ꛤ㗮\bn봻䲄fXT:㾯쳤'笓0b/ೢC쳖?2浓uO.䰴": "ཐ꼋e?``,ᚇ慐^8ꜙNM䂱\u0001IᖙꝧM'vKdꌊH牮r\\O@䊷ᓵ쀆(fy聻i툺\"?<\/峧ࣞ⓺ᤤ쵒߯ꎺ騬?)刦\u2072l慪y꺜ﲖTj+u", + "뽫hh䈵w>1ⲏ쐭V[ⅎ\\헑벑F_㖝⠗㫇h恽;῝汰ᱼ瀖J옆9RR셏vsZ柺鶶툤r뢱橾/ꉇ囦FGm\"謗ꉦ⨶쒿⥡%]鵩#ᖣ_蹎 u5|祥?O", + null, + 2.0150326776036215E-19, + null, + true, + false, + true, + {"\fa᭶P捤WWc᠟f뚉ᬏ퓗ⳀW睹5:HXH=q7x찙X$)모r뚥ᆟ!Jﳸf": [ + -2995806398034583407, + [ + 6441377066589744683, + "Mﶒ醹i)Gἦ廃s6몞 KJ౹礎VZ螺费힀\u0000冺업{谥'꡾뱻:.ꘘ굄奉攼Di᷑K鶲y繈욊阓v㻘}枭캗e矮1c?휐\"4\u0005厑莔뀾墓낝⽴洗ṹ䇃糞@b1\u0016즽Y轹", + { + "1⽕⌰鉟픏M㤭n⧴ỼD#%鐘⊯쿼稁븣몐紧ᅇ㓕ᛖcw嬀~ഌ㖓(0r⧦Q䑕髍ര铂㓻R儮\"@ꇱm❈௿᦯頌8}㿹犴?xn잆꥽R": 2.07321075750427366E18, + "˳b18㗈䃟柵Z曆VTAu7+㛂cb0﯑Wp執<\/臋뭡뚋刼틮荋벲TLP预庰܈G\\O@VD'鱃#乖끺*鑪ꬳ?Mޞdﭹ{␇圯쇜㼞顄︖Y홡g": [{ + "0a,FZ": true, + "2z̬蝣ꧦ驸\u0006L↛Ḣ4๚뿀'?lcwᄧ㐮!蓚䃦-|7.飑挴.樵*+1ﮊ\u0010ꛌ%貨啺/JdM:똍!FBe?鰴㨗0O财I藻ʔWA᫓G쳛u`<\/I": [{ + "$τ5V鴐a뾆両環iZp頻යn븃v": -4869131188151215571, + "*즢[⦃b礞R◚nΰꕢH=귰燙[yc誘g䆌?ଜ臛": { + "洤湌鲒)⟻\\䥳va}PeAMnN[": "㐳ɪ/(軆lZR,Cp殍ȮN啷\"3B婴?i=r$펽ᤐ쀸", + "阄R4㒿㯔ڀ69ZᲦ2癁핌噗P崜#\\-쭍袛&鐑/$4童V꩑_ZHA澢fZ3": {"x;P{긳:G閉:9?活H": [ + "繺漮6?z犞焃슳\">ỏ[Ⳛ䌜녏䂹>聵⼶煜Y桥[泥뚩MvK$4jtロ", + "E#갶霠좭㦻ୗ먵F+䪀o蝒ba쮎4X㣵 h", + -335836610224228782, + null, + null, + [ + "r1᫩0>danjY짿bs{", + [ + -9.594464059325631E-23, + 1.0456894622831624E-20, + null, + 5.803973284253454E-20, + -8141787905188892123, + true, + -4735305442504973382, + 9.513150514479281E-20, + "7넳$螔忷㶪}䪪l짴\u0007鹁P鰚HF銏ZJﳴ/⍎1ᷓ忉睇ᜋ쓈x뵠m䷐窥Ꮤ^\u0019ᶌ偭#ヂt☆၃pᎍ臶䟱5$䰵&๵分숝]䝈뉍♂坎\u0011<>", + "C蒑貑藁lﰰ}X喇몛;t밿O7/᯹f\u0015kI嘦<ዴ㟮ᗎZ`GWퟩ瑹࡮ᅴB꿊칈??R校s脚", + { + "9珵戬+AU^洘拻ቒy柭床'粙XG鞕᠜繀伪%]hC,$輙?Ut乖Qm떚W8઼}~q⠪rU䤶CQ痗ig@#≲t샌f㈥酧l;y闥ZH斦e⸬]j⸗?ঢ拻퀆滌": null, + "畯}㧢J罚帐VX㨑>1ꢶkT⿄蘥㝑o|<嗸層沈挄GEOM@-䞚䧰$만峬輏䠱V✩5宸-揂D'㗪yP掶7b⠟J㕻SfP?d}v㼂Ꮕ'猘": { + "陓y잀v>╪": null, + "鬿L+7:됑Y=焠U;킻䯌잫!韎ஔ\f": { + "駫WmGጶ": { + "\\~m6狩K": -2586304199791962143, + "ႜࠀ%͑l⿅D.瑢Dk%0紪dḨTI픸%뗜☓s榗኉\"?V籄7w髄♲쟗翛歂E䤓皹t ?)ᄟ鬲鐜6C": { + "_췤a圷1\u000eB-XOy缿請∎$`쳌eZ~杁튻/蜞`塣৙\"⪰\"沒l}蕌\\롃荫氌.望wZ|o!)Hn獝qg}": null, + "kOSܧ䖨钨:಼鉝ꭝO醧S`십`ꓭ쭁ﯢN&Et㺪馻㍢ⅳ㢺崡ຊ蜚锫\\%ahx켨|ż劻ꎄ㢄쐟A躊᰹p譞綨Ir쿯\u0016ﵚOd럂*僨郀N*b㕷63z": { + ":L5r+T㡲": [{ + "VK泓돲ᮙRy㓤➙Ⱗ38oi}LJቨ7Ó㹡৘*q)1豢⛃e᫛뙪壥镇枝7G藯g㨛oI䄽 孂L缊ꋕ'EN`": -2148138481412096818, + "`⛝ᘑ$(खꊲ⤖ᄁꤒ䦦3=)]Y㢌跨NĴ驳줟秠++d孳>8ᎊ떩EꡣSv룃 쯫أ?#E|᭙㎐?zv:5祉^⋑V": [ + -1.4691944435285607E-19, + 3.4128661569395795E17, + "㐃촗^G9佭龶n募8R厞eEw⺡_ㆱ%⼨D뉄퉠2ꩵᛅⳍ搿L팹Lවn=\"慉념ᛮy>!`g!풲晴[/;?[v겁軇}⤳⤁핏∌T㽲R홓遉㓥", + "愰_⮹T䓒妒閤둥?0aB@㈧g焻-#~跬x<\/舁P݄ꐡ=\\׳P\u0015jᳪᢁq;㯏l%᭗;砢觨▝,謁ꍰGy?躤O黩퍋Y㒝a擯\n7覌똟_䔡]fJ晋IAS", + 4367930106786121250, + -4.9421193149720582E17, + null, + { + ";ᄌ똾柉곟ⰺKpፇ䱻ฺ䖝{o~h!eꁿ઻욄ښ\u0002y?xUd\u207c悜ꌭ": [ + 1.6010824122815255E-19, + [ + "宨︩9앉檥pr쇷?WxLb", + "氇9】J玚\u000f옛呲~ 輠1D嬛,*mW3?n휂糊γ虻*ᴫ꾠?q凐趗Ko↦GT铮", + "㶢ថmO㍔k'诔栀Z蛟}GZ钹D", + false, + -6.366995517736813E-20, + -4894479530745302899, + null, + "V%᫡II璅䅛䓎풹ﱢ/pU9se되뛞x梔~C)䨧䩻蜺(g㘚R?/Ự[忓C뾠ࢤc왈邠买?嫥挤풜隊枕", + ",v碍喔㌲쟚蔚톬៓ꭶ", + 3.9625444752577524E-19, + null, + [ + "kO8란뿒䱕馔b臻⍟隨\"㜮鲣Yq5m퐔K#ꢘug㼈ᝦ=P^6탲@䧔%$CqSw铜랊0&m⟭<\/a逎ym\u0013vᯗ": true, + "洫`|XN뤮\u0018詞=紩鴘_sX)㯅鿻Ố싹": 7.168252736947373E-20, + "ꛊ饤ﴏ袁(逊+~⽫얢鈮艬O힉7D筗S곯w操I斞᠈븘蓷x": [[[[ + -7.3136069426336952E18, + -2.13572396712722688E18, + { + "硢3㇩R:o칢行E<=\u0018ၬYuH!\u00044U%卝炼2>\u001eSi$⓷ꒈ'렢gᙫ番ꯒ㛹럥嶀澈v;葷鄕x蓎\\惩+稘UEᖸﳊ㊈壋N嫿⏾挎,袯苷ኢ\\x|3c": 7540762493381776411, + "?!*^ᢏ窯?\u0001ڔꙃw虜돳FgJ?&⨫*uo籤:?}ꃹ=ٴ惨瓜Z媊@ત戹㔏똩Ԛ耦Wt轁\\枒^\\ꩵ}}}ꀣD\\]6M_⌫)H豣:36섘㑜": { + ";홗ᰰU஋㙛`D왔ཿЃS회爁\u001b-㢈`봆?盂㛣듿ᦾ蒽_AD~EEຆ㊋(eNwk=Rɠ峭q\"5Ἠ婾^>'ls\n8QAK)- Q䲌mo펹L_칍樖庫9꩝쪹ᘹ䑖瀍aK ?*趤f뭓廝p=磕", + "哑z懅ᤏ-ꍹux쀭", + [ + true, + 3998739591332339511, + "ጻ㙙?᳸aK<\/囩U`B3袗ﱱ?\"/k鏔䍧2l@쿎VZ쨎/6ꃭ脥|B?31+on颼-ꮧ,O嫚m ࡭`KH葦:粘i]aSU쓙$쐂f+詛頖b", + [{"^<9<箝&絡;%i﫡2攑紴\\켉h쓙-柂䚝ven\u20f7浯-Ꮏ\r^훁䓚헬\u000e?\\ㅡֺJ떷VOt": [{ + "-௄卶k㘆혐஽y⎱㢬sS઄+^瞥h;ᾷj;抭\u0003밫f<\/5Ⱗ裏_朻%*[-撵䷮彈-芈": { + "㩩p3篊G|宮hz䑊o곥j^Co0": [ + 653239109285256503, + {"궲?|\":N1ۿ氃NZ#깩:쇡o8킗ࡊ[\"됸Po핇1(6鰏$膓}⽐*)渽J'DN<썙긘毦끲Ys칖": { + "2Pr?Xjㆠ?搮/?㓦柖馃5뚣Nᦼ|铢r衴㩖\"甝湗ܝ憍": "\"뾯i띇筝牻$珲/4ka $匝휴译zbAᩁꇸ瑅&뵲衯ꎀᆿ7@ꈋ'ᶨH@ᠴl+", + "7뢽뚐v?4^ꊥ_⪛.>pởr渲<\/⢕疻c\"g䇘vU剺dஔ鮥꒚(dv祴X⼹\\a8y5坆": true, + "o뼄B욞羁hr﷔폘뒚⿛U5pꪴfg!6\\\"爑쏍䢱W<ﶕ\\텣珇oI/BK뺡'谑♟[Ut븷亮g(\"t⡎有?ꬊ躺翁艩nl F⤿蠜": 1695826030502619742, + "ۊ깖>ࡹ햹^ⵕ쌾BnN〳2C䌕tʬ]찠?ݾ2饺蹳ぶꌭ訍\"◹ᬁD鯎4e滨T輀ﵣ੃3\u20f3킙D瘮g\\擦+泙ၧ 鬹ﯨַ肋7놷郟lP冝{ߒhড়r5,꓋": null, + "ΉN$y{}2\\N﹯ⱙK'8ɜͣwt,.钟廣䎘ꆚk媄_": null, + "䎥eᾆᝦ읉,Jުn岪㥐s搖謽䚔5t㯏㰳㱊ZhD䃭f絕s鋡篟a`Q鬃┦鸳n_靂(E4迠_觅뷝_宪D(NL疶hL追V熑%]v肫=惂!㇫5⬒\u001f喺4랪옑": { + "2a輍85먙R㮧㚪Sm}E2yꆣꫨrRym㐱膶ᔨ\\t綾A☰.焄뙗9<쫷챻䒵셴᭛䮜.<\/慌꽒9叻Ok䰊Z㥪幸k": [ + null, + true, + {"쌞쐍": { + "▟GL K2i뛱iQ\"̠.옛1X$}涺]靎懠ڦ늷?tf灟ݞゟ{": 1.227740268699265E-19, + "꒶]퓚%ฬK❅": [{ + "(ෛ@Ǯっ䧼䵤[aテൖvEnAdU렖뗈@볓yꈪ,mԴ|꟢캁(而첸죕CX4Y믅": "2⯩㳿ꢚ훀~迯?᪑\\啚;4X\u20c2襏B箹)俣eỻw䇄", + "75༂f詳䅫ꐧ鏿 }3\u20b5'∓䝱虀f菼Iq鈆﨤g퍩)BFa왢d0뮪痮M鋡nw∵謊;ꝧf美箈ḋ*\u001c`퇚퐋䳫$!V#N㹲抗ⱉ珎(V嵟鬒_b㳅\u0019": null, + "e_m@(i㜀3ꦗ䕯䭰Oc+-련0뭦⢹苿蟰ꂏSV䰭勢덥.ྈ爑Vd,ᕥ=퀍)vz뱊ꈊB_6듯\"?{㒲&㵞뵫疝돡믈%Qw限,?\r枮\"? N~癃ruࡗdn&": null, + "㉹&'Pfs䑜공j<\/?|8oc᧨L7\\pXᭁ 9᪘": -2.423073789014103E18, + "䝄瑄䢸穊f盈᥸,B뾧푗횵B1쟢f\u001f凄": "魖⚝2儉j꼂긾껢嗎0ࢇ纬xI4](੓`蕞;픬\fC\"斒\")2櫷I﹥迧", + "ퟯ詔x悝령+T?Bg⥄섅kOeQ큼㻴*{E靼6氿L缋\u001c둌๶-㥂2==-츫I즃㠐Lg踞ꙂEG貨鞠\"\u0014d'.缗gI-lIb䋱ᎂDy缦?": null, + "紝M㦁犿w浴詟棓쵫G:䜁?V2ힽ7N*n&㖊Nd-'ຊ?-樹DIv⊜)g䑜9뉂ㄹ푍阉~ꅐ쵃#R^\u000bB䌎䦾]p.䀳": [{"ϒ爛\"ꄱ︗竒G䃓-ま帳あ.j)qgu扐徣ਁZ鼗A9A鸦甈!k蔁喙:3T%&㠘+,䷞|챽v䚞문H<\/醯r셓㶾\\a볜卺zE䝷_죤ဵ뿰᎟CB": [ + 6233512720017661219, + null, + -1638543730522713294, + false, + -8901187771615024724, + [ + 3891351109509829590, + true, + false, + -1.03836679125188032E18, + { + "j랎:g曞ѕᘼ}链N", + -1.1103819473845426E-19, + true, + [ + true, + null, + -7.9091791735309888E17, + true, + {"}蔰鋈+ꐨ啵0?g*사%`J?*": [{ + "\"2wG?yn,癷BK\\龞䑞x?蠢": -3.7220345009853505E-19, + ";饹়❀)皋`噿焒j(3⿏w>偍5X薙婏聿3aFÆÝ": "2,ꓴg?_섦_>Y쪥션钺;=趘F~?D㨫\bX?㹤+>/믟kᠪ멅쬂Uzỵ]$珧`m雁瑊ඖ鯬cꙉ梢f묛bB", + "♽n$YjKiXX*GO贩鏃豮祴遞K醞眡}ꗨv嵎꼷0୸+M菋eH徸J꣆:⼐悥B켽迚㯃b諂\u000bjꠜ碱逮m8": [ + "푷᣺ﻯd8ﱖ嬇ភH鹎⡱᱅0g:果6$GQ췎{vᷧYy-脕x偹砡館⮸C蓼ꏚ=軄H犠G谖ES詤Z蠂3l봟hᅭ7䦹1GPQG癸숟~[#駥8zQ뛣J소obg,", + null, + 1513751096373485652, + null, + -6.851466660824754E-19, + {"䩂-⴮2ٰK솖풄꾚ႻP앳1H鷛wmR䗂皎칄?醜<\/&ࠧ㬍X濬䵈K`vJ륒Q/IC묛!;$vϑ": { + "@-ꚗxྐྵ@m瘬\u0010U絨ﮌ驐\\켑寛넆T=tQ㭤L연@脸삯e-:⩼u㎳VQ㋱襗ຓ<Ⅶ䌸cML3+\u001e_C)r\\9+Jn\\Pﺔ8蠱檾萅Pq鐳话T䄐I": -1.80683891195530061E18, + "ᷭዻU~ཷsgSJ`᪅'%㖔n5픆桪砳峣3獮枾䌷⊰呀": { + "Ş੉䓰邟自~X耤pl7间懑徛s첦5ਕXexh⬖鎥᐀nNr(J컗|ૃF\"Q겮葲놔엞^겄+㈆话〾희紐G'E?飕1f❼텬悚泬먐U睬훶Qs": false, + "(\u20dag8큽튣>^Y{뤋.袊䂓;_g]S\u202a꽬L;^'#땏bႌ?C緡<䝲䲝断ꏏ6\u001asD7IK5Wxo8\u0006p弊⼂ꯍ扵\u0003`뵂픋%ꄰ⫙됶l囏尛+䗅E쟇\\": [ + true, + { + "\n鱿aK㝡␒㼙2촹f;`쾏qIࡔG}㝷䐍瓰w늮*粅9뒪ㄊCj倡翑閳R渚MiUO~仨䜶RꙀA僈㉋⦋n{㖥0딿벑逦⥻0h薓쯴Ꝼ": [ + 5188716534221998369, + 2579413015347802508, + 9.010794400256652E-21, + -6.5327297761238093E17, + 1.11635352494065523E18, + -6656281618760253655, + { + "": ")?", + "TWKLꑙ裑꺔UE俸塑炌Ũ᜕-o\"徚#": {"M/癟6!oI51ni퐚=댡>xꍨ\u0004 ?": { + "皭": {"⢫䋖>u%w잼<䕏꘍P䋵$魋拝U䮎緧皇Y훂&|羋ꋕ잿cJ䨈跓齳5\u001a삱籷I꿾뤔S8㌷繖_Yឯ䲱B턼O歵F\\l醴o_欬6籏=D": [ + false, + true, + {"Mt|ꏞD|F궣MQ뵕T,띺k+?㍵i": [ + 7828094884540988137, + false, + { + "!༦鯠,&aﳑ>[euJꏽ綷搐B.h": -7648546591767075632, + "-n켧嘰{7挐毄Y,>❏螵煫乌pv醑Q嶚!|⌝責0왾덢ꏅ蛨S\\)竰'舓Q}A釡5#v": 3344849660672723988, + "8閪麁V=鈢1녈幬6棉⪮둌\u207d᚛驉ꛃ'r䆉惏ै|bἧﺢᒙ<=穊强s혧eꮿ慩⌡ \\槳W븧J檀C,ᘉ의0俯퀉M;筷ࣴ瓿{늊埂鄧_4揸Nn阼Jੵ˥(社": true, + "o뼀vw)4A뢵(a䵢)p姃뛸\u000fK#KiQp\u0005ꅍ芅쏅": null, + "砥$ꥸ┇耽u斮Gc{z빔깎밇\\숰\u001e괷各㶇쵿_ᴄ+h穢p촀Ნ䃬z䝁酳ӂ31xꔄ1_砚W렘G#2葊P ": [ + -3709692921720865059, + null, + [ + 6669892810652602379, + -135535375466621127, + "뎴iO}Z? 馢녱稹ᄾ䐩rSt帤넆&7i騏멗畖9誧鄜'w{Ͻ^2窭외b㑎粖i矪ꦨ탪跣)KEㆹ\u0015V8[W?⽉>'kc$䨘ᮛ뉻٬M5", + 1.10439588726055846E18, + false, + -4349729830749729097, + null, + [ + false, + "_蠢㠝^䟪/D녒㡋ỎC䒈판\u0006એq@O펢%;鹐쏌o戥~A[ꡉ濽ỳ&虃᩾荣唙藍茨Ig楡꒻M窓冉?", + true, + 2.17220752996421728E17, + -5079714907315156164, + -9.960375974658589E-20, + "ᾎ戞༒", + true, + false, + [[ + "ⶉᖌX⧕홇)g엃⹪x뚐癟\u0002", + -5185853871623955469, + { + "L㜤9ợㇶK鐰⋓V뽋˖!斫as|9"፬䆪?7胜&n薑~": -2.11545634977136992E17, + "O8뀩D}캖q萂6༣㏗䈓煮吽ਆᎼDᣘ폛;": false, + "YTᡅ^L㗎cbY$pᣞ縿#fh!ꘂb삵玊颟샞ဢ$䁗鼒몁~rkH^:닮먖츸륈⪺쒉砉?㙓扫㆕꣒`R䢱B酂?C뇞<5Iޚ讳騕S瞦z": null, + "\\RB?`mG댵鉡幐物䵎有5*e骄T㌓ᛪ琾駒Ku\u001a[柆jUq8⋈5鿋츿myﻗ?雍ux঴?": 5828963951918205428, + "n0晅:黯 xu씪^퓞cB㎊ᬍ⺘٤փ~B岚3㥕擄vᲂ~F?C䶖@$m~忔S왖㲚?챴⊟W#벌{'㰝I䝠縁s樘\\X뢻9핡I6菍ㄛ8쯶]wॽ0L\"q": null, + "x增줖j⦦t䏢᎙㛿Yf鼘~꫓恄4惊\u209c": "oOhbᤃ᛽z&Bi犑\\3B㩬劇䄑oŁ쨅孥멁ຖacA㖫借㞝vg싰샂㐜#譞⢤@k]鋰嘘䜾L熶塥_<\/⍾屈ﮊ_mY菹t뙺}Ox=w鮮4S1ꐩמּ'巑", + "㗓蟵ꂾe蠅匳(JP䗏෸\u0089耀왲": [{ + "ᤃ㵥韎뤽\r?挥O쯡⇔㞚3伖\u0005P⋪\"D궣QLn(⚘罩䩢Ŏv䤘尗뼤됛O淽鋋闚r崩a{4箙{煷m6〈": { + "l곺1L": { + "T'ਤ?砅|੬Km]䄩\"(࿶<\/6U爢䫈倔郴l2㴱^줣k'L浖L鰄Rp今鎗⒗C얨M훁㡧ΘX粜뫈N꤇輊㌻켑#㮮샶-䍗룲蠝癜㱐V>=\\I尬癤t=": 7648082845323511446, + "鋞EP:<\/_`ၧe混ㇹBd⯢㮂驋\\q碽饩跓྿ᴜ+j箿렏㗑yK毢宸p謹h䦹乕U媣\\炤": [[ + "3", + [ + true, + 3.4058271399411134E-20, + true, + "揀+憱f逮@먻BpW曉\u001a㣐⎊$n劈D枤㡞좾\u001aᛁ苔౩闝1B䷒Ṋ݋➐ꀞꐃ磍$t੤_:蘺⮼(#N", + 697483894874368636, + [ + "vᘯ锴)0訶}䳅⩚0O壱韈ߜ\u0018*U鍾䏖=䧉뽑单휻ID쿇嘗?ꌸῬ07", + -5.4858784319382006E18, + 7.5467775182251151E18, + -8911128589670029195, + -7531052386005780140, + null, + [ + null, + true, + [[{ + "1欯twG<\/Q:0怯押殃탷聫사<ỗꕧ蚨䡁nDꌕ\u001c녬~蓩鲃g儊>ꏡl㻿/⑷*챳6㻜W毤緛ﹺᨪ4\u0013뺚J髬e3쳸䘦伧?恪&{L掾p+꬜M䏊d娘6": { + "2p첼양棜h䜢﮶aQ*c扦v︥뮓kC寵횂S銩&ǝ{O*य़iH`U큅ࡓr䩕5ꄸ?`\\᧫?ᮼ?t〟崾훈k薐ì/iy꤃뵰z1<\/AQ#뿩8jJ1z@u䕥": 1.82135747285215155E18, + "ZdN &=d년ᅆ'쑏ⅉ:烋5&៏ᄂ汎来L㯄固{钧u\\㊏튚e摑&t嗄ꖄUb❌?m䴘熚9EW": [{ + "ଛ{i*a(": -8.0314147546006822E17, + "⫾ꃆY\u000e+W`௸ \"M뒶+\\뷐lKE}(NT킶Yj選篒쁶'jNQ硾(똡\\\"逌ⴍy? IRꜘ὞鄬﨧:M\\f⠋Cꚜ쫊ᚴNV^D䕗ㅖἔIao꿬C⍏8": [ + 287156137829026547, + { + "H丞N逕⯲": {"": { + "7-;枮阕梒9ᑄZ": [[[[ + null, + { + "": [[[[ + -7.365909561486078E-19, + 2948694324944243408, + null, + [ + true, + "荒\"并孷䂡쵼9o䀘F\u0002龬7⮹Wz%厖/*? a*R枈㌦됾g뒠䤈q딄㺿$쮸tᶎ릑弣^鏎<\/Y鷇驜L鿽<\/춋9Mᲆឨ^<\/庲3'l낢", + "c鮦\u001b두\\~?眾ಢu݆綑෪蘛轋◜gȃ<\/ⴃcpkDt誩܅\"Y", + [[ + null, + null, + [ + 3113744396744005402, + true, + "v(y", + { + "AQ幆h쾜O+꺷铀ꛉ練A蚗⼺螔j㌍3꽂楎䥯뎸먩?": null, + "蠗渗iz鱖w]擪E": 1.2927828494783804E-17, + "튷|䀭n*曎b✿~杤U]Gz鄭kW|㴚#㟗ഠ8u擨": [[ + true, + null, + null, + {"⾪壯톽g7?㥜ώQꑐ㦀恃㧽伓\\*᧰閖樧뢇赸N휶䎈pI氇镊maᬠ탷#X?A+kНM ༑᩟؝?5꧎鰜ṚY즫궔 =ঈ;ﳈ?*s|켦蜌wM笙莔": [ + null, + -3808207793125626469, + [ + -469910450345251234, + 7852761921290328872, + -2.7979740127017492E18, + 1.4458504352519893E-20, + true, + "㽙깹?먏䆢:䴎ۻg殠JBTU⇞}ꄹꗣi#I뵣鉍r혯~脀쏃#釯:场:䔁>䰮o'㼽HZ擓௧nd", + [ + 974441101787238751, + null, + -2.1647718292441327E-19, + 1.03602824249831488E18, + [ + null, + 1.0311977941822604E-17, + false, + true, + { + "": -3.7019778830816707E18, + "E峾恆茍6xLIm縂0n2视֯J-ᤜz+ᨣ跐mYD豍繹⹺䊓몓ﴀE(@詮(!Y膽#᎙2䟓섣A䈀㟎,囪QbK插wcG湎ꤧtG엝x⥏俎j'A一ᯥ뛙6ㅑ鬀": 8999803005418087004, + "よ殳\\zD⧅%Y泥簳Uꈩ*wRL{3#3FYHା[d岀䉯T稉駅䞘礄P:闈W怏ElB㤍喬赔bG䠼U଄Nw鰯闀楈ePsDꥷ꭬⊊": [ + 6.77723657904486E-20, + null, + [ + "ཚ_뷎꾑蹝q'㾱ꂓ钚蘞慵렜떆`ⴹ⎼櫯]J?[t9Ⓢ !컶躔I᮸uz>3a㠕i,錃L$氰텰@7녫W㸮?羧W뇧ꃞ,N鋮숪2ɼ콏┍䁲6", + "&y?뢶=킕올Za惻HZk>c\u20b58i?ꦶcfBv잉ET9j䡡", + "im珊Ճb칧校\\뼾쯀", + 9.555715121193197E-20, + true, + { + "<㫚v6腓㨭e1㕔&&V∌ᗈT奄5Lጥ>탤?튣瑦㳆ꉰ!(ᙪ㿬擇_n쌯IMΉ㕨␰櫈ᱷ5풔蟹&L.첽e鰷쯃劼﫭b#ﭶ퓀7뷄Wr㢈๧Tʴશ㶑澕鍍%": -1810142373373748101, + "fg晌o?߲ꗄ;>C>?=鑰監侯Kt굅": true, + "䫡蓺ꑷ]C蒹㦘\"1ః@呫\u0014NL䏾eg呮፳,r$裢k>/\\?ㄤᇰﻛ쉕1஥'Ċ\" \\_?쨔\"ʾr: 9S䘏禺ᪧꄂ㲄", + [[{ + "*硙^+E쌺I1䀖ju?:⦈Ꞓl๴竣迃xKC/饉:\fl\"XTFᄄ蟭,芢<\/骡軺띜hꏘ\u001f銿<棔햳▨(궆*=乥b8\\媦䷀뫝}닶ꇭ(Kej䤑M": [{ + "1Ꮼ?>옿I╅C<ގ?ꊌ冉SV5A㢊㶆z-๎玶绢2F뵨@㉌뀌o嶔f9-庒茪珓뷳4": null, + ";lᰳ": "CbB+肻a䄷苝*/볳+/4fq=㰁h6瘉샴4铢Y骐.⌖@哼猎㦞+'gꋸ㒕ߤ㞑(䶒跲ti⑴a硂#No볔", + "t?/jE幸YHT셵⩎K!Eq糦ꗣv刴w\"l$ο:=6:移": { + "z]鑪醊嫗J-Xm銌翁絨c里됏炙Ep㣋鏣똼嚌䀓GP﹖cmf4鹭T䅿꣭姧␸wy6ꦶ;S&(}ᎧKxᾂQ|t뻳k\"d6\"|Ml췆hwLt꼼4$&8Պ褵婶鯀9": {"嵃닢ᒯ'd᧫䳳#NXe3-붋鸿ଢ떓%dK\u0013䲎ꖍYV.裸R⍉rR3蟛\\:젯:南ĺLʆ넕>|텩鴷矔ꋅⒹ{t孶㓑4_": [ + true, + null, + [ + false, + "l怨콈lᏒ", + { + "0w䲏嬧-:`䉅쉇漧\\܂yㄨb%㽄j7ᦶ涶<": 3.7899452730383747E-19, + "ꯛTẀq纤q嶏V⿣?\"g}ი艹(쥯B T騠I=仵및X": {"KX6颠+&ᅃ^f畒y[": { + "H?뱜^?꤂-⦲1a㋞&ꍃ精Ii᤾챪咽쬘唂쫷<땡劈훫놡o㥂\\ KⴙD秼F氮[{'좴:례晰Iq+I쭥_T綺砸GO煝䟪ᚪ`↹l羉q쐼D꽁ᜅ훦: vUV": true, + "u^yﳍ0㱓#[y뜌앸ꊬL㷩?蕶蘾⻍KӼ": -7931695755102841701, + "䤬轉車>\u001c鴵惋\"$쯃྆⇻n뽀G氠S坪]ಲꨍ捇Qxኻ椕駔\\9ࣼ﫻읜磡煮뺪ᶚ볝l㕆t+sζ": [[[ + true, + false, + [ + null, + 3363739578828074923, + true, + { + "\"鸣詩 볰㑵gL㯦῅춝旫}ED辗ﮈI쀤-ꧤ|㠦Z\"娑ᕸ4爏騍㣐\"]쳝Af]茛⬻싦o蚁k䢯䩐菽3廇喑ޅ": 4.5017999150704666E17, + "TYႇ7ʠ值4챳唤~Zo&ݛ": false, + "`塄J袛㭆끺㳀N㺣`꽐嶥KﯝSVᶔ∲퀠獾N딂X\"ᤏhNﬨvI": {"\u20bb㭘I䖵䰼?sw䂷쇪](泒f\"~;꼪Fԝsᝦ": {"p,'ꉂ軿=A蚶?bƉ㏵䅰諬'LYKL6B깯⋩겦뎙(ᜭ\u0006噣d꾆㗼Z;䄝䚔cd<情@䞂3苼㸲U{)<6&ꩻ钛\u001au〷N숨囖愙j=BXW욕^x芜堏Ῑ爂뛷꒻t✘Q\b": [[ + "籛&ଃ䩹.ꃩ㦔\\C颫#暪&!勹ꇶ놽攺J堬镙~軌C'꾖䣹㮅岃ᙴ鵣", + 4.317829988264744E15, + 6.013585322002147E-20, + false, + true, + null, + null, + -3.084633632357326E-20, + false, + null, + { + "\"짫愔昻 X\"藣j\"\"먁ཅѻ㘤㬯0晲DU꟒㸃d벀윒l䦾c੻*3": null, + "谈Wm陧阦咟ฯ歖擓N喴㋐銭rCCnVࢥ^♼Ⅾ젲씗刊S༝+_t赔\\b䚍뉨ꬫ6펛cL䊘᜼<\/澤pF懽&H": [ + null, + { + "W\"HDUuΌ퀟M'P4࿰H똆ⰱﮯ<\/凐蘲\"C鴫ﭒж}ꭩ쥾t5yd诪ﮡ퍉ⴰ@?氐醳rj4I6Qt": 6.9090159359219891E17, + "絛ﳛ⺂": {"諰P㗮聦`ZQ?ꫦh*റcb⧱}埌茥h{棩렛툽o3钛5鮁l7Q榛6_g)ὄ\u0013kj뤬^爖eO4Ⱈ槞鉨ͺ订%qX0T썗嫷$?\\\"봅늆'%": [ + -2.348150870600346E-19, + [[ + true, + -6619392047819511778, + false, + [[ + -1.2929189982356161E-20, + 1.7417192219309838E-19, + {"?嵲2࿐2\u0001啑㷳c縯": [ + null, + [ + false, + true, + 2578060295690793218, + { + "?\"殃呎#㑑F": true, + "}F炊_殛oU헢兔Ꝉ,赭9703.B数gTz3⏬": { + "5&t3,햓Mݸᵣ㴵;꣫䩍↳#@뫷䠅+W-ࣇzᓃ鿕ಔ梭?T䮑ꥬ旴]u뫵막bB讍:왳둛lEh=숾鱠p咐$짏#?g⹷ᗊv㷵.斈u頻\u0018-G.": "뽙m-ouࣤ஫牷\"`Ksꕞ筼3HlȨvC堈\"I]㖡玎r먞#'W賜鴇k'c룼髋䆿飉㗆xg巤9;芔cጐ/ax䊨♢큓r吓㸫೼䢗da᩾\"]屣`", + ":M딪<䢥喠\u0013㖅x9蕐㑂XO]f*Q呰瞊吭VP@9,㨣 D\\穎vˤƩs㜂-曱唅L걬/롬j㈹EB8g<\/섩o渀\"u0y&룣": ">氍緩L/䕑돯Ꟙ蕞^aB뒣+0jK⪄瑨痜LXK^힦1qK{淚t츔X:Vm{2r獁B뾄H첚7氥?쉟䨗ꠂv팳圎踁齀\\", + "D彤5㢷Gꪻ[lㄆ@὜⓰絳[ଃ獽쮹☒[*0ꑚ㜳": 9022717159376231865, + "ҖaV銣tW+$魿\u20c3亜~뫡ᙰ禿쨽㏡fṼzE/h": "5臐㋇Ჯ쮺? 昨탰Wム밎#'\"崲钅U?幫뺀⍾@4kh>騧\\0ҾEV=爐͌U捀%ꉼ 㮋<{j]{R>:gԩL\u001c瀈锌ﯲﳡꚒ'⫿E4暍㌗뵉X\"H᝜", + "ᱚגּ;s醒}犍SἿ㦣&{T$jkB\\\tḮ앾䤹o<避(tW": "vb⯽䴪䮢@|)", + "⥒퐁껉%惀뗌+녣迺顀q條g⚯i⤭룐M琹j̈́⽜A": -8385214638503106917, + "逨ꊶZ<\/W⫟솪㎮ᘇb?ꠔi\"H㧺x෷韒Xꫨฟ|]窽\u001a熑}Agn?Mᶖa9韲4$3Ỵ^=쏍煤ፐ돷2䣃%鷠/eQ9頸쥎", + 2398360204813891033, + false, + 3.2658897259932633E-19, + null, + "?ꚃ8Nn㞷幵d䲳䱲뀙ꪛQ瑓鎴]䩋-鰾捡䳡??掊", + false, + -1309779089385483661, + "ᦲxu_/yecR.6芏.ᜇ過 ~", + -5658779764160586501, + "쒌:曠=l썜䢜wk#s蕚\"互㮉m䉤~0듐䋙#G;h숄옥顇෤勹(C7㢅雚㐯L⠅VV簅<", + null, + -4.664877097240962E18, + -4.1931322262828017E18, + { + ",": { + "v㮟麑䄠뤵g{M띮.\u001bzt뢜뵡0Ǥ龍떟Ᾰ怷ϓRT@Lꀌ樂U㏠⾕e扉|bJg(뵒㠶唺~ꂿ(땉x⻫싉쁊;%0鎻V(o\f,N鏊%nk郼螺": -1.73631993428376141E18, + "쟧摑繮Q@Rᕾ㭚㾣4隅待㓎3蒟": [ + 4971487283312058201, + 8973067552274458613, + { + "`a揙ᣗ\u0015iBo¸": 4.3236479112537999E18, + "HW&퉡ぁ圍Y?瑡Qy훍q!帰敏s舠㫸zꚗaS歲v`G株巷Jp6킼 (귶鍔⾏⡈>M汐㞍ቴ꙲dv@i㳓ᇆ?黍": [ + null, + 4997607199327183467, + "E㻎蠫ᐾ高䙟蘬洼旾﫠텛㇛?'M$㣒蔸=A_亀绉앭rN帮", + null, + [{ + "Eᑞ)8餧A5u&㗾q?": [ + -1.969987519306507E-19, + null, + [ + 3.42437673373841E-20, + true, + "e걷M墁\"割P␛퍧厀R䱜3ﻴO퓫r﹉⹊", + [ + -8164221302779285367, + [ + true, + null, + "爘y^-?蘞Ⲽꪓa␅ꍨ}I", + 1.4645984996724427E-19, + [{ + "tY좗⧑mrzﺝ㿥ⴖ᥷j諅\u0000q賋譁Ꞅ⮱S\nࡣB/큃굪3Zɑ复o<\/;롋": null, + "彟h浠_|V4䦭Dᙣ♞u쿻=삮㍦\u001e哀鬌": [{"6횣楠,qʎꗇ鎆빙]㱭R굋鈌%栲j分僅ペ䇰w폦p蛃N溈ꡐꏀ?@(GI뉬$ﮄ9誁ꓚ2e甸ڋ[䁺,\u0011\u001cࢃ=\\+衪䷨ᯕ鬸K": [[ + "ㅩ拏鈩勥\u000etgWVXs陂規p狵w퓼{뮵_i\u0002ퟑႢ⬐d6鋫F~챿搟\u0096䚼1ۼ칥0꣯儏=鋷牋ⅈꍞ龐", + -7283717290969427831, + true, + [ + 4911644391234541055, + { + "I鈒첽P릜朸W徨觘-Hᎄ퐟⓺>8kr1{겵䍃〛ᬡ̨O귑o䝕'쿡鉕p5": "fv粖RN瞖蛐a?q꤄\u001d⸥}'ꣴ犿ꦼ?뤋?鵆쥴덋䡫s矷̄?ඣ/;괱絢oWfV<\/\u202cC,㖦0䑾%n賹g&T;|lj_欂N4w", + "짨䠗;䌕u i+r๏0": [{"9䥁\\఩8\"馇z䇔<\/ႡY3e狚쐡\"ุ6ﰆZ遖c\"Ll:ꮾ疣<\/᭙O◌납୕湞9⡳Und㫜\u0018^4pj1;䧐儂䗷ୗ>@e톬": { + "a⑂F鋻Q螰'<퇽Q贝瀧{ᘪ,cP&~䮃Z?gI彃": [ + -1.69158726118025933E18, + [ + "궂z簽㔛㮨瘥⤜䛖Gℤ逆Y⪾j08Sn昞ꘔ캻禀鴚P謦b{ꓮmN靐Mᥙ5\"睏2냑I\u0011.L&=?6ᄠ뻷X鸌t刑\"#z)o꫚n쳟줋", + null, + 7517598198523963704, + "ኑQp襟`uᩄr方]*F48ꔵn俺ሙ9뇒", + null, + null, + 6645782462773449868, + 1219168146640438184, + null, + { + ")ယ넌竀Sd䰾zq⫣⏌ʥ\u0010ΐ' |磪&p牢蔑mV蘸૰짬꺵;K": [ + -7.539062290108008E-20, + [ + true, + false, + null, + true, + 6574577753576444630, + [[ + 1.2760162530699766E-19, + [ + null, + [ + "顊\\憎zXB,", + [{ + "㇆{CVC9-MN㜋ઘR눽#{h@ퟨ!鼚׼XOvXS\u0017ᝣ=cS+梽៲綆16s덽휐y屬?ᇳG2ᴭ\u00054쫖y룇nKcW̭炦s/鰘ᬽ?J|퓀髣n勌\u0010홠P>j": false, + "箴": [ + false, + "鍞j\"ꮾ*엇칬瘫xṬ⭽쩁䃳\"-⋵?ᦽ댎Ĝ": true, + "Pg帯佃籛n㔠⭹࠳뷏≻࿟3㞱!-쒾!}쭪䃕!籿n涻J5ਲ਼yvy;Rኂ%ᔡጀ裃;M⣼)쵂쑈": 1.80447711803435366E18, + "ꈑC⡂ᑆ㤉壂뎃Xub<\/쀆༈憓ق쨐ק\\": [ + 7706977185172797197, + {"": {"K╥踮砆NWࡆFy韣7ä밥{|紒︧䃀榫rᩛꦡTSy잺iH8}ퟴ,M?Ʂ勺ᴹ@T@~꾂=I㙕뾰_涀쑜嫴曣8IY?ҿo줫fऒ}\\S\"ᦨ뵼#nDX": { + "♘k6?଱癫d68?㽚乳䬳-V顷\u0005蝕?\u0018䞊V{邾zじl]雏k臤~ൖH뒐iꢥ]g?.G碄懺䔛pR$䅒X觨l봜A刊8R梒',}u邩퉕?;91Ea䈈믁G⊶芔h袪&廣㺄j;㡏綽\u001bN頸쳘橆": -2272208444812560733, + "拑Wﵚj鵼駳Oࣿ)#㾅顂N傓纝y僱栜'Bꐍ-!KF*ꭇK¦?䈴^:啤wG逭w᧯": "xᣱmYe1ۏ@霄F$ě꧘푫O䤕퀐Pq52憬ꀜ兴㑗ᡚ?L鷝ퟐ뭐zJꑙ}╆ᅨJB]\"袌㺲u8䯆f", + "꿽၅㔂긱Ǧ?SI": -1669030251960539193, + "쇝ɨ`!葎>瞺瘡驷錶❤ﻮ酜=": -6961311505642101651, + "?f7♄꫄Jᡔ훮e읇퍾፣䭴KhखT;Qty}O\\|뫁IῒNe(5惁ꥶㆷY9ﮡ\\ oy⭖-䆩婁m#x봉>Y鈕E疣s驇↙ᙰm<": {"퉻:dꂁ&efᅫ쫢[\"돈늖꺙|Ô剐1͖-K:ʚ᭕/;쏖㷛]I痐职4gZ4⍜kเꛘZ⥺\\Bʫᇩ鄨魢弞&幟ᓮ2̊盜", + -9006004849098116748, + -3118404930403695681, + { + "_彃Y艘-\"Xx㤩㳷瑃?%2䐡鵛o귵옔夘v*탋职&㳈챗|O钧": [ + false, + "daꧺdᗹ羞쯧H㍤鄳頳<型孒ン냆㹀f4㹰\u000f|C*ሟ鰠(O<ꨭ峹ipຠ*y೧4VQ蔔hV淬{?ᵌEfrI_", + "j;ꗣ밷邍副]ᗓ", + -4299029053086432759, + -5610837526958786727, + [ + null, + [ + -1.3958390678662759E-19, + { + "lh좈T_믝Y\"伨\u001cꔌG爔겕ꫳ晚踍⿻읐T䯎]~e#฽燇\"5hٔ嶰`泯r;ᗜ쮪Q):/t筑,榄&5懶뎫狝(": [{ + "2ፁⓛ]r3C攟וּ9賵s⛔6'ஂ|\"ⵈ鶆䐹禝3\"痰ࢤ霏䵩옆䌀?栕r7O簂Isd?K᫜`^讶}z8?z얰T:X倫⨎ꑹ": -6731128077618251511, + "|︦僰~m漿햭\\Y1'Vvخ굇ቍ챢c趖": [null] + }], + "虌魿閆5⛔煊뎰㞤ᗴꥰF䮥蘦䂪樳-K᝷-(^\u20dd_": 2.11318679791770592E17 + } + ] + ] + ]}, + "묗E䀳㧯᳀逞GMc\b墹㓄끖Ơ&U??펌鑍 媋k))ᄊ": null, + "묥7콽벼諌J_DɯﮪM殴䣏,煚ྼ`Y:씧<\/⩫%yf䦀!1Ჶk춎Q米W∠WC跉鬽*ᛱi㴕L꘻ꀏ쓪\"_g鿄'#t⽙?,Wg㥖|D鑆e⥏쪸僬h鯔咼ඡ;4TK聎졠嫞" + } + ] + ] + } + ] + ] + ]}} + } + ]} + }, + "뿋뀾淣截䔲踀&XJ펖꙯^Xb訅ꫥgᬐ>棟S\"혧騾밫겁7-": "擹8C憎W\"쵮yR뢩浗絆䠣簿9䏈引Wcy䤶孖ꯥ;퐌]輩䍐3@{叝 뽸0ᡈ쵡Ⲇ\u001dL匁꧐2F~ݕ㪂@W^靽L襒ᦘ~沦zZ棸!꒲栬R" + } + ] + ], + "Z:덃൛5Iz찇䅄駠㭧蓡K1": "e8᧤좱U%?ⵇ䯿鿝\u0013縮R∱骒EO\u000fg?幤@֗퉙vU`", + "䐃쪈埽້=Ij,쭗쓇చ": false + }]}} + ] + } + ]} + } + ] + ] + ], + "咰긖VM]᝼6䓑쇎琺etDҌ?㞏ꩄ퇫밉gj8蠃\"⩐5䛹1ࣚ㵪": "ക蹊?⎲⧘⾚̀I#\"䈈⦞돷`wo窭戕෱휾䃼)앷嵃꾞稧,Ⴆ윧9S?೗EMk3Მ3+e{⹔Te驨7䵒?타Ulg悳o43" + } + ], + "zQᤚ纂땺6#ٽ﹧v￿#ࠫ휊冟蹧텈ꃊʆ?&a䥯De潝|쿓pt瓞㭻啹^盚2Ꝋf醪,얏T窧\\Di䕎谄nn父ꋊE": -2914269627845628872, + "䉩跐|㨻ᷢ㝉B{蓧瞸`I!℄욃힕#ೲᙾ竛ᔺCjk췒늕貭词\u0017署?W딚%(pꍁ⤼띳^=on뺲l䆼bzrﳨ[&j狸䠠=ᜑꦦ\u2061յnj=牲攑)M\\龏": false, + "뎕y絬᫡⥮Ϙᯑ㌔/NF*˓.,QEzvK!Iwz?|쥾\"ꩻL꼗Bꔧ賴緜s뉣隤茛>ロ?(?^`>冺飒=噸泥⺭Ᲊ婓鎔븜z^坷裮êⓅ໗jM7ﶕ找\\O": 1.376745434746303E-19 + }, + "䐛r滖w㏤,|Nዜ": false + } + ]], + "@꿙?薕尬 gd晆(띄5躕ﻫS蔺4)떒錸瓍?~": 1665108992286702624, + "w믍nᏠ=`঺ᅥC>'從됐槷䤝眷螄㎻揰扰XᅧC贽uჍ낟jKD03T!lDV쀉Ӊy뢖,袛!终캨G?鉮Q)⑗1쾅庅O4ꁉH7?d\u0010蠈줘월ސ粯Q!낇껉6텝|{": null, + "~˷jg쿤촖쉯y": -5.5527605669177098E18, + "펅Wᶺzꐆと푭e?4j仪열[D<鈑皶婆䵽ehS?袪;HꍨM뗎ば[(嗏M3q퍟g4y╸鰧茀[Bi盤~﫝唎鋆彺⦊q?B4쉓癚O洙킋툈䶯_?ퟲ": null + } + ] + ]] + ]], + "꟱Ԕ㍤7曁聯ಃ錐V䷰?v㪃૦~K\"$%请|ꇹn\"k䫛㏨鲨\u2023䄢\u0004[︊VJ?䶟ាꮈ䗱=깘U빩": -4863152493797013264 + } + ]}]} + ] + }}} + ], + "쏷쐲۹퉃~aE唙a챑,9㮹gLHd'䔏|킗㍞䎥&KZYT맵7䥺Nⱳ同莞鿧w\\༌疣n/+ꎥU\"封랾○ퟙAJᭌ?9䛝$?驔9讐짘魡T֯c藳`虉C읇쐦T" + } + ], + "谶개gTR￐>ၵ͚dt晑䉇陏滺}9㉸P漄": -3350307268584339381 + }] + ] + ] + ]] + ] + ], + "0y꟭馋X뱔瑇:䌚￐廿jg-懲鸭䷭垤㒬茭u賚찶ಽ+\\mT땱\u20821殑㐄J쩩䭛ꬿNS潔*d\\X,壠뒦e殟%LxG9:摸": 3737064585881894882, + "풵O^-⧧ⅶvѪ8廸鉵㈉ר↝Q㿴뺟EႳvNM:磇>w/៻唎뷭୥!냹D䯙i뵱貁C#⼉NH6`柴ʗ#\\!2䂗Ⱨf?諳.P덈-返I꘶6?8ꐘ": -8934657287877777844, + "溎-蘍寃i诖ര\"汵\"\ftl,?d⼡쾪⺋h匱[,෩I8MҧF{k瓿PA'橸ꩯ綷퉲翓": null + } + ] + ], + "ោ係؁<元": 1.7926963090826924E-18 + }}] + } + ] + ]]}] + }] + ] + ] + ] + ], + "ጩV<\"ڸsOᤘ": 2.0527167903723048E-19 + }] + ]} + ] + ]], + "∳㙰3젴p᧗䱙?`yZA8Ez0,^ᙛ4_0븢\u001ft:~䎼s.bb룦明yNP8弆C偯;⪾짍'蕴뮛": -6976654157771105701, + "큵ꦀ\\㇑:nv+뒤燻䀪ﴣ﷍9ᚈ኷K㚊誦撪䚛,ꮪxሲ쳊\u0005HSf?asg昱dqꬌVꙇ㼺'k*'㈈": -5.937042203633044E-20 + } + ] + }], + "?}\u20e0],s嶳菋@#2u쒴sQS䩗=ꥮ;烌,|ꘔ䘆": "ᅩ영N璠kZ먕眻?2ቲ芋眑D륟渂⸑ﴃIRE]啗`K'" + }}, + "쨀jmV賂ﰊ姐䂦玞㬙ᏪM᪟Վ씜~`uOn*ॠ8\u000ef6??\\@/?9見d筜ﳋB|S䝬葫㽁o": true + }, + "즛ꄤ酳艚␂㺘봿㎨iG৕ࡿ?1\"䘓您\u001fSኝ⺿溏zៀ뻤B\u0019?윐a䳵᭱䉺膷d:<\/": 3935553551038864272 + } + ] + ]} + ]] + ]] + ]} + } + ] + } + ]]}}, + "᥺3h↛!ꋰy\"攜(ெl䪕oUkc1A㘞ᡲ촾ᣫ<\/䒌E㛝潨i{v?W౾H\\RჅpz蝬R脾;v:碽✘↯삞鷱o㸧瑠jcmK7㶧뾥찲n": true, + "ⶸ?x䊺⬝-䰅≁!e쩆2ꎿ准G踌XXᩯ1߁}0?.헀Z馟;稄\baDꟹ{-寪⚈ꉷ鮸_L7ƽᾚ<\u001bጨA䧆송뇵⨔\\礍뗔d设룱㶉cq{HyぱR㥽吢ſtp": -7985372423148569301, + "緫#콮IB6<\/=5Eh礹\t8럭@饹韠r㰛斣$甝LV췐a갵'请o0g:^": "䔨(.", + "띳℡圤pン௄ĝ倧訜B쁟G䙔\"Sb⓮;$$▏S1J뢙SF|赡g*\"Vu䲌y": "䪈&틐),\\kT鬜1풥;뷴'Zေ䩹@J鞽NぼM?坥eWb6榀ƩZڮ淽⺞삳煳xჿ絯8eⶍ羷V}ჿ쎱䄫R뱃9Z>'\u20f1ⓕ䏜齮" + } + ] + ]]] + }} + } + ] + ]}, + "펮b.h粔폯2npX詫g錰鷇㇒<쐙S値bBi@?镬矉`剔}c2壧ଭfhY깨R()痩⺃a\\⍔?M&ﯟ<劜꺄멊ᄟA\"_=": null + }, + "~潹Rqn榢㆓aR鬨侅?䜑亡V_翅㭔(䓷w劸ၳDp䀅<\/ﰎ鶊m䵱팱긽ꆘ긓准D3掱;o:_ќ)껚콥8곤d矦8nP倥ꃸI": null, + "뾎/Q㣩㫸벯➡㠦◕挮a鶧⋓偼\u00001뱓fm覞n?㛅\"": 2.8515592202045408E17 + }], + ",": -5426918750465854828, + "2櫫@0柡g䢻/gꆑ6演&D稒肩Y?艘/놘p{f투`飷ᒉ챻돎<늛䘍ﴡ줰쫄": false, + "8(鸑嵀⵹ퟡ<9㣎Tߗ┘d슒ل蘯&㠦뮮eࠍk砝g 엻": false, + "d-\u208b?0ﳮ嵙'(J`蔿d^踅⤔榥\\J⵲v7": 6.8002426206715341E17, + "ཎ耰큓ꐕ㱷\u0013y=詽I\"盈xm{0쾽倻䉚ષso#鰑/8㸴짯%ꀄ떸b츟*\\鲷礬ZQ兩?np㋄椂榨kc᡹醅3": false, + "싊j20": false + }]] + ]], + "俛\u0017n緽Tu뫉蜍鼟烬.ꭠIⰓ\"Ἀ᜾uC쎆J@古%ꛍm뻨ᾀ画蛐휃T:錖㑸ዚ9죡$": true + } + ] + ], + "㍵⇘ꦖ辈s}㱮慀밒s`\"㞟j:`i픻Z섫^諎0Ok{켿歁෣胰a2﨤[탳뚬쎼嫭뉮m": 409440660915023105, + "w墄#*ᢄ峠밮jLa`ㆪ꺊漓Lで끎!Agk'ꁛ뢃㯐岬D#㒦": false, + "ଦPGI䕺L몥罭ꃑ궩﮶#⮈ᢓӢ䚬p7웼臧%~S菠␌힀6&t䳙y㪘냏\\*;鉏ᅧ鿵'嗕pa\"oL쇿꬈Cg": "㶽1灸D⟸䴅ᆤ뉎﷛渤csx 䝔цꬃ锚捬?ຽ+x~꘩uI࡞\u0007栲5呚ẓem?袝\")=㥴䨃pac!/揎Y", + "ᷱo\\||뎂몷r篙|#X䦜I#딌媸픕叞RD斳X4t⯩夬=[뭲r=绥jh뷱츝⪘%]⚋܈㖴スH텹m(WO曝劉0~K3c柢Ր㏉着逳~": false, + "煽_qb[첑\\륌wE❽ZtCNﭝ+餌ᕜOꛭ": "{ﳾ쉌&s惧ᭁⵆ3䢫;䨞팑꒪흘褀࢖Q䠿V5뭀䎂澻%받u5텸oA⮥U㎦;B䳌wz䕙$ឿ\\௅婺돵⪾퐆\\`Kyौꋟ._\u0006L챯l뇠Hi䧈偒5", + "艊佁ࣃ롇䱠爬!*;⨣捎慓q靓|儑ᨋL+迥=6㒺딉6弄3辅J-㕎뛄듘SG㆛(\noAzQꝱ䰩X*ぢO퀌%펠낌mo틮a^<\/F&_눊ᾉ㨦ы4\"8H": 2974648459619059400, + "鬙@뎣䫳ၮ끡?){y?5K;TA*k溱䫜J汃ꂯ싔썍\u001dA}룖(<\/^,": false, + "몏@QꋦFꊩᒐ뎶lXl垨4^郣|ꮇ;䝴ᝓ}쵲z珖": null + } + ]]]], + ":_=닧弗D䙋暨鏛. 㱻붘䂍J儒&ZK/녩䪜r囁⽯D喠죥7⹌䪥c\u001a\u2076￞妈朹oLk菮F౟覛쐧㮏7T;}蛙2{9\"崓bB<\/⡷룀;즮鿹)丒툃୤뷠5W⊢嶜(fb뭳갣": "E{响1WM" + }}, + "䘨tjJ驳豨?y輊M*᳑梵瞻઻ofQG瑮e": 2.222802939724948E-19, + "䮴=❑➶T෋w䞜\"垦ꃼUt\u001dx;B$뵣䙶E↌艣ᡥ!᧟;䱀[䔯k쬃`੍8饙른熏'2_'袻tGf蒭J땟as꯳╖&啒zWࡇᒫYSᏬ\u0014ℑ첥鈤|cG~Pᓮ\">\"": "ႆl\f7V儊㦬nHꄬꨧC{쐢~C⮃⛓嶦vꄎ1w鰠嘩뿠魄&\"_qMⵖ釔녮ꝇ 㝚{糍J哋 cv?-jkﻯྌ鹑L舟r", + "龧葆yB✱H盋夔ﶉ?n*0(": "ꧣኆ㢓氥qZZ酒ຜ)鮢樛)X䣆gTSґG텞k.J圬疝롫쯭z L:\\ྤ@w炋塜쿖ᾳy뢀䶃뱝N䥨㚔勇겁#p", + "도畎Q娡\"@S/뼋:䵏!P衅촚fVHQs✜ᐫi㻑殡B䜇%믚k*U#濨낄~": "ꍟዕ쳸ꍈ敋&l妏\u0005憡멗瘌uPgᅪm<\/To쯬锩h뒓k" + } + ] + }], + "墥홞r绚<\/⸹ⰃB}<躅\\Y;๑@䔸>韫䜲뱀X뗩鿥쩗SI%ﴞ㳕䛇?<\/\u00018x\\&侂9鋙a[LR㋭W胕)⡿8㞙0JF,}?허d1cDMᐃ␛鄝ⱕ%X)!XQ": "ⳍꗳ=橇a;3t⦾꼑仈ူaᚯ⯋ꕃAs鴷N⍕_䎃ꙎAz\u0016䯷\\<࿫>8q{}キ?ᣰ}'0ᴕ펓B┦lF#趤厃T?㕊#撹圂䆲" + }, + "܋닐龫論c웑": false, + "ㇿ/q\"6-co髨휝C큦#\u001b4~?3䐹E삇<<": 7.600917488140322E-20, + "䁝E6?㣖ꃁ间t祗*鑠{ḣV(浾h逇큞=W?ૉ?nꇽ8ꅉຉj으쮺@Ꚅ㰤u]Oyr": "v≁᫸_*όAඤԆl)ۓᦇQ}폠z༏q滚", + "ソ᥊/넺I": true + }]] + ] + ] + ] + ]] + }, + "䭑Ik攑\u0002QV烄:芩.麑㟴㘨≕": true, + "坄꿕C쇻풉~崍%碼\\8\"䬦꣙": null, + "欌L圬䅘Y8c(♺2?ON}o椳s宥2䉀eJ%闹r冁O^K諭%凞⺉⡻,掜?$ꥉ?略焕찳㯊艼誜4?\"﯎<゛XፈINT:詓 +": -1.0750456770694562E-19, + "獒àc뜭싼ﺳ뎤K`]p隨LtE": null, + "甙8䵊神EIꩤ鐯ᢀ,ﵮU䝑u疒ử驺䚿≚ഋ梶秓F`覤譐#짾蔀묊4<媍쬦靪_Yzgcࡶ4k紥`kc[Lﮗ簐*I瀑[⾰L殽鑥_mGȠ<\/|囹灠g桰iri": true, + "챓ꖙꟻ좝菇ou,嗠0\\jK핻뜠qwQ?ഩ㼕3Y彦b\u009bJ榶N棨f?됦鏖綃6鳵M[OE봨u햏.Ꮁ癜蟳뽲ꩌ뻾rM豈R嗀羫 uDꎚ%": null + }, + "V傜2<": 7175127699521359521 + }], + "铫aG切<\/\"ী⊆e<^g࢛)D顝nאַ饼\u008c猪繩嵿ﱚCꡬ㻊g엺A엦\u000f暿_f꿤볝㦕桦`蒦䎔j甬%岝rj 糏": "䚢偎눴Au<4箞7礦Iﱔ坠eȧ䪸u䵁p|逹$嗫쨘ꖾ﷐!胠z寓팢^㨔|u8Nሇe텔ꅦ抷]،鹎㳁#༔繁 ", + "낂乕ꃻ볨ϱ-ꇋ㖍fs⿫)zꜦ/K?솞♞ꑌ宭hJ᤭瑥Fu": false, + "쟰ぜ魛G\u0003u?`㾕ℾ㣭5螠烶這趩ꖢ:@咕ꐶx뒘느m䰨b痃렐0鳊喵熬딃$摉_~7*ⱦ녯1錾GKhJ惎秴6'H妈Tᧅ窹㺒疄矤铟wላ": null, + "쯆q4!3錕㲏ⵆ㇛꘷Z瑩뭆\\◪NH\u001d\\㽰U~㯶<\"쑣낞3ᵤ'峉eꢬ;鬹o꣒木X*長PXᘱu\"䠹n惞": null, + "ᅸ祊\"&ꥴCjࢼ﴿?䡉`U效5殼㮞V昽ꏪ#ﺸ\\&t6x꠹盥꣰a[\u001aꪍSpe鎿蠹": -1.1564713893659811E-19 + } + ]] + ] + ] + ], + "羵䥳H,6ⱎ겾|@t\"#햊1|稃 섭)띜=뻔ꡜ???櫎~*ῡ꫌/繣ﻠq": null + } + ]} + ]}, + "츤": false + }}, + "s": 3.7339341963399598E18 + } + ], + "N,I?1+㢓|ࣱ嶃쩥V2\u0012(4EE虪朶$|w颇v步": "~읢~_,Mzr㐫YB溓E淚\"ⅹ䈔ᏺ抙 b,nt5V㐒J檶ꏨ⻔?", + "Q껑ꡡ}$넎qH煔惍/ez^!ẳF댙䝌馻剁8": "梲;yt钰$i冄}AL%a j뜐奷걳뚾d꿽*ሬuDY3?뮟鼯뮟w㍪틱V", + "o{Q/K O胟㍏zUdꀐm&⨺J舕⾏魸訟㌥[T籨櫉唐킝 aṭ뱫촙莛>碶覆⧬짙쭰ׯdAiH໥벤퐥_恸[ 0e:죃TC弼荎뵁DA:w唵ꣁ": null, + "὏樎䵮軧|?౗aWH쩃1 ꅭsu": null + } + ] + }, + "勂\\&m鰈J釮=Ⲽ鳋+䂡郑": null, + "殣b綊倶5㥗惢⳷萢ᑀ䬄镧M^ﱴ3⣢翣n櫻1㨵}ኯ뗙顖Z.Q➷ꮨ뗇\u0004": "ꔙ䁼>n^[GीA䨟AM琢ᒊS쨲w?d㶣젊嘶纝麓+愣a%気ྞSc됓ᔘ:8bM7Xd8㶑臌]Ꙥ0ꐭ쒙䫣挵C薽Dfⵃ떼᷸", + "?紡.셪_෨j\u0013Ox┠$Xᶨ-ᅇo薹-}軫;y毝㪜K㣁?.EV쮱4둽⛻䤜'2盡\u001f60(|e쐰㼎ᦀ㒧-$l@ﻑ坳\u0003䭱响巗WFo5c㧆T턁Y맸♤(": -2.50917882560589088E17 + }} + ], + "侸\\릩.᳠뎠狣살cs项䭩畳H1s瀉븇19?.w骴崖㤊h痠볭㞳㞳䁮Ql怠㦵": "@䟴-=7f", + "鹟1x௢+d ;vi䭴FSDS\u0004hꎹ㚍?⒍⦏ў6u,扩@됷Su)Pag휛TᒗV痩!瞏釀ꖞ蘥&ೞ蘐ꭰꞇᝎ": "ah懱Ժ&\u20f7䵅♎඀䞧鿪굛ౕ湚粎蚵ᯋ幌YOE)५襦㊝Y*^\"R+ඈ咷蝶9ꥂ榨艦멎헦閝돶v좛咊E)K㓷ྭr", + "搆q쮦4綱켙셁.f4<\/g<籽늷?#蚴픘:fF\u00051㹉뀭.ᰖ풎f֦Hv蔎㧤.!䭽=鞽]음H:?\"-4": 8.740133984938656E-20 + }]} + } + ], + "tVKn딩꘥⊾蹓᤹{\u0003lR꼽ᄲQFᅏ傅ﱋ猢⤊ᔁ,E㓒秤nTතv`♛I\u0000]꫔ṞD\"麵c踝杰X&濿또꣹깳౥葂鿎\\aꡨ?": 3900062609292104525 + } + ], + "ਉ샒⊩Lu@S䧰^g": -1.1487677090371648E18, + "⎢k⑊꬗yᏫ7^err糎Dt\u000bJ礯확ㆍ沑サꋽe赔㝢^J\u0004笲㿋idra剰-᪉C錇/Ĝ䂾ညS지?~콮gR敉⬹'䧭": 1901472137232418266, + "灗k䶥:?촽贍쓉꓈㒸g獘[뵎\\胕?\u0014_榙p.j稶,$`糉妋0>Fᡰly㘽$?": "]ꙛO赎&#㠃돱剳\"<◆>0誉齐_|z|裵씪>ᐌ㼍\"Z[琕}O?G뚇諦cs⠜撺5cu痑U圲\u001c?鴴計l춥/╓哼䄗茏ꮅ뫈댽A돌롖뤫V窗讬sHd&\nOi;_u" + } + ], + "Uﺗ\\Y\\梷䄬~\u0002": null, + "k\"Y磓ᗔ휎@U冈<\/w컑)[": false, + "曏J蝷⌻덦\u001f㙳s꥓⍟邫P늮쥄c∬ྡྷ舆렮칤Z趣5콡넛A쳨\\뀙骫(棻.*&輛LiIfi{@EA婳KᬰTXT": -4.3088230431977587E17 + }]} + ] + ], + "곃㲧<\/dఓꂟs其ࡧ&N葶=?c㠤Ჴ'횠숄臼#\u001a~": false + } + ] + ]}] + }] + }} + ], + "2f`⽰E쵟>J笂裭!〛觬囀ۺ쟰#桊l鹛ⲋ|RA_Vx፭gE됓h﵀mfỐ|?juTU档[d⢼⺻p濚7E峿": 5613688852456817133 + }, + "濘끶g忮7㏵殬W팕Q曁 뫰)惃廊5%-蹚zYZ樭ﴷQ锘쯤崫gg": true, + "絥ᇑ⦏쒓븣爚H.㗊߄o蘵貆ꂚ(쎔O᥉ﮓ]姨Wꁓ!RMA|o퉢THx轮7M껁U즨'i뾘舯o": "跥f꜃?" + }} + ], + "鷰鹮K-9k;ﰰ?_ݦѷ-ꅣ䩨Zꥱ\"mꠟ屎/콑Y╘2&鸞脇㏢ꀇ࠺ⰼ拾喭틮L꽩bt俸墶 [l/웄\"꾦\u20d3iও-&+\u000fQ+໱뵞": -1.296494662286671E-19 + }, + "HX੹/⨇୕붷Uﮘ旧\\쾜͔3l鄈磣糂̖䟎Eᐳw橖b῀_딕hu葰窳闹вU颵|染H죶.fP䗮:j䫢\\b뎖i燕ꜚG⮠W-≚뉗l趕": "ଊ칭Oa᡺$IV㷧L\u0019脴셀붿餲햪$迳向쐯켂PqfT\" ?I屉鴼쿕@硙z^鏕㊵M}㚛T젣쓌-W⩐-g%⺵<뮱~빅╴瑿浂脬\u0005왦燲4Ⴭb|D堧 <\/oEQh", + "䘶#㥘੐캔f巋ἡAJ䢚쭈ࣨ뫒*mᇊK,ࣺAꑱ\u000bR<\/A\"1a6鵌㯀bh곿w(\"$ꘁ*rಐ趣.d࿩k/抶면䒎9W⊃9": "漩b挋Sw藎\u0000", + "畀e㨼mK꙼HglKb,\"'䤜": null + }]}] + ] + ] + }] + ]} + ] + ]} + ], + "歙>駿ꣂ숰Q`J΋方樛(d鱾뼣(뫖턭\u20f9lচ9歌8o]8윶l얶?镖G摄탗6폋폵+g:䱫홊<멀뀿/س|ꭺs걐跶稚W々c㫣⎖": "㣮蔊깚Cꓔ舊|XRf遻㆚︆'쾉췝\\&言", + "殭\"cށɨꝙ䞘:嬮e潽Y펪㳅/\"O@ࠗ겴]췖YǞ(t>R\"N?梳LD恭=n氯T豰2R諸#N}*灧4}㶊G䍣b얚": null, + "襞<\/啧 B|싞W瓇)6簭鼡艆lN쩝`|펭佡\\間邝[z릶&쭟愱ꅅ\\T᰽1鯯偐栈4̸s윜R7⒝/똽?치X": "⏊躖Cﱰ2Qẫ脐&இ?%냝悊", + ",鰧偵셣싹xᎹ힨᯳EṬH㹖9": -4604276727380542356 + } + } + ]]]], + "웺㚑xs}q䭵䪠馯8?LB犯zK'os䚛HZ\"L?셎s^㿧㴘Cv2": null + }] + ] + ] + ], + "Kd2Kv+|z": 7367845130646124107, + "ᦂⶨ?ᝢ 祂些ഷ牢㋇操\"腭䙾㖪\\(y4cE뽺ㆷ쫺ᔖ%zfۻ$ў1柦,㶢9r漢": -3.133230960444846E-20, + "琘M焀q%㢟f鸯O⣏蓑맕鯊$O噷|)z褫^㢦⠮ꚯ꫞`毕1qꢚ{ĭ䎀বώT\"뱘3G൴?^^of": null + } + ], + "a8V᯺?:ﺃ/8ꉿBq|9啓댚;*i2": null, + "cpT瀇H珰Ừpೃi鎪Rr␣숬-鹸ҩ䠚z脚цGoN8入y%趌I┽2ឪЀiJNcN)槣/▟6S숆牟\"箑X僛G殱娇葱T%杻:J諹昰qV쨰": 8331037591040855245 + }], + "G5ᩜ䄗巢껳": true + } + }, + "Ồ巢ゕ@_譙A`碫鄐㡥砄㠓(^K": "?܃B혢▦@犑ὺD~T⧁|醁;o=J牌9냚⢽㨘{4觍蚔9#$∺\u0016p囅\\3Xk阖⪚\"UzA穕롬✎➁㭒춺C㣌ဉ\"2瓑员ᅽꝶ뫍}꽚ꞇ鶂舟彺]ꍽJC蝧銉", + "␆Ě膝\"b-퉐ACR言J謈53~V튥x䜢?ꃽɄY뮩ꚜ": "K/↾e萃}]Bs⾿q룅鷦-膋?m+死^魊镲6", + "粡霦c枋AHퟁo礼Ke?qWcA趸㡔ꂏ?\u000e춂8iতᦜ婪\u0015㢼nﵿꍻ!ᐴ関\u001d5j㨻gfῩUK5Ju丝tかTI'?㓏t>⼟o a>i}ᰗ;뤕ܝ": false, + "ꄮ匴껢ꂰ涽+䜨B蛹H䛓-k蕞fu7kL谖,'涃V~챳逋穞cT\"vQ쓕ObaCRQ㓡Ⲯ?轭⫦輢墳?vA餽=h䮇킵n폲퉅喙?\"'1疬V嬗Qd灗'Lự": "6v!s믁㭟㣯獃!磸餠ቂh0C뿯봗F鷭gꖶ~コkK<ᦈTt\\跓w㭣횋钘ᆹ듡䑚W䟾X'ꅔ4FL勉Vܴ邨y)2'〚쭉⽵-鞣E,Q.?块", + "?(˧쩯@崟吋歄K": null + }, + "Gc럃녧>?2DYI鴿\\륨)澔0ᔬlx'觔7젘⤡縷螩%Sv׫묈/]↱&S h\u0006歋ᑛxi̘}ひY蔯_醨鯘煑橾8?䵎쨋z儬ꁏ*@츾:": null + } + } + } + ] + ] + ]} + }, + "HO츧G": 3.694949578823609E17, + "QC\u0012(翻曇Tf㷟bGBJ옉53\\嚇ᛎD/\u001b夾၉4\"핀@祎)쫆yD\"i먎Vn㿿V1W᨝䶀": -6150931500380982286, + "Z㓮P翸鍱鉼K䋞꘺튿⭁Y": -7704503411315138850, + "]모开ꬖP븣c霤<[3aΠ\"黁䖖䰑뮋ꤦ秽∼㑷冹T+YUt\"싳F↭䖏&鋌": -2.7231911483181824E18, + "tꎖ": -4.9517948741799555E-19, + "䋘즊.⬅IꬃۣQ챢ꄑ黐|f?C⾺|兕읯sC鬸섾整腨솷V": "旆柩l쪦sᖸMy㦅울썉瘗㎜檵9ꍂ駓ૉᚿ/u3씅徐拉[Z䞸ࡗ1ꆱ&Q풘?ǂ8\u0011BCDY2볨;鸏": null, + "幫 n煥s쁇펇 왊-$C\"衝:\u0014㣯舼.3뙗Yl⋇\"K迎멎[꽵s}9鉳UK8쐥\"掄㹖h㙈!얄સ?Ꜳ봺R伕UTD媚I䜘W鏨蔮": -4.150842714188901E-17, + "ﺯ^㄄\b죵@fྉkf颡팋Ꞧ{/Pm0V둳⻿/落韒ꊔᚬ@5螺G\\咸a谆⊪ቧ慷绖?财(鷇u錝F=r၍橢ឳn:^iᴵtD볠覅N赴": null + }] + }] + } + ] + ]} + ]}, + "謯?w厓奰T李헗聝ឍ貖o⪇弒L!캶$ᆅ": -4299324168507841322, + "뺊奉_垐浸延몏孄Z舰2i$q붿좾껇d▵餏\"v暜Ҭ섁m￴g>": -1.60911932510533427E18 + } + ] + } + ] + ]], + "퉝꺔㠦楶Pꅱ": 7517896876489142899, + "": false + } + ]}, + "是u&I狻餼|谖j\"7c됮sסּ-踳鉷`䣷쉄_A艣鳞凃*m⯾☦椿q㎭N溔铉tlㆈ^": 1.93547720203604352E18, + "kⲨ\\%vr#\u000bⒺY\\t<\/3﬌R訤='﹠8蝤Ꞵ렴曔r": false + } + ]}, + "阨{c?C\u001d~K?鎌Ԭ8烫#뙣P초遗t㭱E­돒䆺}甗[R*1!\\~h㕅᰺@<9JꏏષI䳖栭6綘걹ᅩM\"▯是∔v鬽顭⋊譬": "운ﶁK敂(欖C취پ℄爦賾" + } + }} + }], + "鷨赼鸙+\\䭣t圙ڹx᜾ČN<\/踘\"S_맶a鷺漇T彚⎲i㈥LT-xA캔$\u001cUH=a0츺l릦": "溣㣂0濕=鉵氬駘>Pꌢpb솇쬤h힊줎獪㪬CrQ矠a&脍꼬爼M茴/΅\u0017弝轼y#Ꞡc6둴=?R崏뷠麖w?" + }, + "閕ᘜ]CT)䵞l9z'xZF{:ؐI/躅匽졁:䟇AGF૸\u001cퟗ9)駬慟ꡒꆒRS״툋A<>\u0010\"ꂔ炃7g덚E৏bꅰ輤]o㱏_뷕ܘ暂\"u": "芢+U^+㢩^鱆8*1鈶鮀\u0002뺰9⬳ꪮlL䃣괟,G8\u20a8DF㉪錖0ㄤ瓶8Nଷd?眡GLc陓\\_죌V쁰ल二?c띦捱 \u0019JC\u0011b⤉zẒT볕\"绣蘨뚋cꡉkI\u001e鳴", + "ꃣI'{6u^㡃#཰Kq4逹y൒䧠䵮!㱙/n??{L풓ZET㙠퍿X2᩟綳跠葿㚙w཮x캽扳B唕S|尾}촕%N?o䪨": null, + "ⰴFjෟ셈[\u0018辷px?椯\\1<ﲻ栘ᣁ봢憠뉴p": -5263694954586507640 + } + ] + ]] + ]} + ]}] + ] + ], + "?#癘82禩鋆ꊝty?&": -1.9419029518535086E-19 + } + ] + ] + ]} + ] + ] + ], + "훊榲.|῕戄&.㚏Zꛦ2\"䢥ሆ⤢fV_摕婔?≍Fji冀탆꜕i㏬_ẑKᅢ꫄蔻XWc|饡Siẘ^㲦?羡2ぴ1縁ᙅ?쐉Ou": false + }]] + ]}}}, + "慂뗄卓蓔ᐓ匐嚖/颹蘯/翻ㆼL?뇊,텵<\\獷ごCボ": null + }, + "p溉ᑟi짣z:䒤棇r^٫%G9缑r砌롧.물农g?0׼ሩ4ƸO㣥㯄쩞ጩ": null, + "껎繥YxK\"F젷쨹뤤1wq轫o?鱑뜀瘊?뎃h灑\\ꛣ}K峐^ኖ⤐林ꉓhy": null + } + ], + "᱀n肓ㄛ\"堻2>m殮'1橌%Ꞵ군=Ӳ鯨9耛<\/n據0u彘8㬇៩f᏿诙]嚊": "䋯쪦S럶匏ㅛ#)O`ሀX_鐪渲⛀㨻宅闩➈ꢙஶDR⪍" + }, + "tA썓龇 ⋥bj왎录r땽✒롰;羋^\\?툳*┎?썀ma䵳넅U䳆૘〹䆀LQ0\b疀U~u$M}(鵸g⳾i抦뛹?䤈땚검.鹆?ꩡtⶥGĒ;!ቹHS峻B츪켏f5≺": 2366175040075384032, + "전pJjleb]ួ": -7.5418493141528422E18, + "n.鎖ጲ\n?,$䪘": true + }, + "欈Ar㉣螵᪚茩?O)": null + }, + "쫸M#x}D秱欐K=侫们丐.KꕾxẠ\u001e㿯䣛F܍캗qq8꟞ṢFD훎⵳簕꭛^鳜\u205c٫~⑟~冫ऊ2쫰<\/戲윱o<\"": true + }, + "㷝聥/T뱂\u0010锕|内䞇x侁≦㭖:M?iM᣿IJe煜dG࣯尃⚩gPt*辂.{磼럾䝪@a\\袛?}ᓺB珼": true + } + } + ]]}]}}, + "tn\"6ꫤ샾䄄;銞^%VBPwu묪`Y僑N.↺Ws?3C⤻9唩S䠮ᐴm;sᇷ냞඘B/;툥B?lB∤)G+O9m裢0kC햪䪤": -4.5941249382502277E18, + "ᚔt'\\愫?鵀@\\びꂕP큠<<]煹G-b!S?\nꖽ鼫,ݛ&頺y踦?E揆릱H}햧캡b@手.p탻>췽㣬ꒅ`qe佭P>ᓂ&?u}毚ᜉ蟶頳졪ᎏzl2wO": -2.53561440423275936E17 + }]} + } + ] + ]], + "潈촒⿂叡": 5495738871964062986 + } + ]] + } + ] + ]} + ]] + ]] + ]} + ] + ]}, + "ႁq킍蓅R`謈蟐ᦏ儂槐僻ﹶ9婌櫞釈~\"%匹躾ɢ뤥>࢟瀴愅?殕节/냔O✬H鲽엢?ᮈੁ⋧d␽㫐zCe*": 2.15062231586689536E17, + "㶵Ui曚珰鋪ᾼ臧P{䍏䷪쨑̟A뼿T渠誈䏚D1!잶<\/㡍7?)2l≣穷᛾稝{:;㡹nemיּ訊`G": null, + "䀕\"飕辭p圁f#뫆䶷뛮;⛴ᩍ3灚덏ᰝ쎓⦷詵%᜖Մfs⇫(\u001e~P|ﭗCⲾផv湟W첋(텪બT<บSꏉ੗⋲X婵i ӵ⇮?L䬇|ꈏ?졸": 1.548341247351782E-19 + } + ] + }, + "t;:N\u0015q鐦Rt缆{ꮐC?஛㷱敪\\+鲊㉫㓪몗릙竏(氵kYS": "XᰂT?൮ô", + "碕飦幑|+ 㚦鏶`镥ꁩ B<\/加륙": -4314053432419755959, + "秌孳(p!G?V傫%8ሽ8w;5鲗㦙LI檸\u2098": "zG N볞䆭鎍흘\\ONK3횙<\/樚立圌Q튅k쩎Ff쁋aׂJK銆ઘ즐狩6༥✙䩜篥CzP(聻駇HHퟲ讃%,ά{렍p而刲vy䦅ክ^톺M楒鍢㹳]Mdg2>䤉洞", + "踛M젧>忔芿㌜Zk": 2215369545966507819, + "씐A`$槭頰퍻^U覒\bG毲aᣴU;8!팲f꜇E⸃_卵{嫏羃X쀳C7뗮m(嚼u N܁谟D劯9]#": true, + "ﻩ!뵸-筚P᭛}ἰ履lPh?౮ⶹꆛ穉뎃g萑㑓溢CX뾇G㖬A錟]RKaꄘ]Yo+@䘁's섎襠$^홰}F": null + }, + "粘ꪒ4HXᕘ蹵.$區\r\u001d묁77pPc^y笲Q<\/ꖶ 訍䃍ᨕG?*": 1.73773035935040224E17 + }, + "婅拳?bkU;#D矠❴vVN쩆t㜷A풃갮娪a%鮏絪3dAv룒#tm쑬⌛qYwc4|L8KZ;xU⓭㳔밆拓EZ7襨eD|隰ऌ䧼u9Ԣ+]贴P荿": 2.9628516456987075E18 + }]}}] + ]} + }} + ]}] + ], + "|g翉F*湹̶\u0005⏐1脉̀eI쩓ᖂ㫱0碞l䴨ꑅ㵽7AtἈ턧yq䳥塑:z:遀ᄐX눔擉)`N3昛oQ셖y-ڨ⾶恢ꈵq^<\/": null, + "菹\\랓G^璬x৴뭸ゆUS겧﮷Bꮤ ┉銜᯻0%N7}~f洋坄Xꔼ<\/4妟Vꄟ9:౟곡t킅冩䧉笭裟炂4봋ⱳ叺怊t+怯涗\"0㖈Hq": false, + "졬믟'ﺇফ圪쓬멤m邸QLব䗁愍4jvs翙 ྍ꧀艳H-|": null, + "컮襱⣱뗠 R毪/鹙꾀%헳8&": -5770986448525107020 + } + ], + "B䔚bꐻ뙏姓展槰T-똌鷺tc灿᫽^㓟䏀o3o$꘭趙萬I顩)뇭Ἑ䓝\f@{ᣨ`x3蔛": null + } + ] + ] + }], + "⦖扚vWꃱ꥙㾠壢輓{-⎳鹷贏璿䜑bG倛⋐磎c皇皩7a~ﳫU╣Q࠭ꎉS摅姽OW.홌ೞ.": null, + "蚪eVlH献r}ᮏ믠ﰩꔄ@瑄ⲱ": null, + "퀭$JWoꩢg역쁍䖔㑺h&ୢtXX愰㱇?㾫I_6 OaB瑈q裿": null, + "꽦ﲼLyr纛Zdu珍B絟쬴糔?㕂짹䏵e": "ḱ\u2009cX9멀i䶛簆㳀k" + } + ]]]], + "(_ꏮg່澮?ᩑyM<艷\u001aꪽ\\庼뙭Z맷㰩Vm\\lY筺]3㋲2㌩㄀Eਟ䝵⨄쐨ᔟgङHn鐖⤇놋瓇Q탚單oY\"♆臾jHᶈ征ቄ??uㇰA?#1侓": null + }, + "觓^~ሢ&iI띆g륎ḱ캀.ᓡꀮ胙鈉": 1.0664523593012836E-19, + "y詭Gbᔶऽs댁U:杜⤎ϲ쁗⮼D醄诿q뙰I#즧v蔎xHᵿt᡽[**?崮耖p缫쿃L菝,봬ꤦC쯵#=X1瞻@OZc鱗CQTx": null + } + ] + }}], + "剘紁\u0004\\Xn⊠6,တױ;嵣崇}讃iႽ)d1\\䔓": null + }, + "脨z\"{X,1u찜<'k&@?1}Yn$\u0015Rd輲ーa쮂굄+B$l": true, + "諳>*쭮괐䵟Ґ+<箁}빀䅱⡔檏臒hIH脟ꩪC핝ଗP좕\"0i<\/C褻D۞恗+^5?'ꂱ䚫^7}㡠cq6\\쨪ꔞꥢ?纖䫀氮蒫侲빦敶q{A煲G": -6880961710038544266 + }}] + }, + "5s⨲JvಽῶꭂᄢI.a৊": null, + "?1q꽏쿻ꛋDR%U娝>DgN乭G": -1.2105047302732358E-19 + } + ] + ]}, + "qZz`撋뙹둣j碇쁏\\ꆥ\u0018@藴疰Wz)O{F䶛l᷂绘訥$]뮍夻䢋䩇萿獰樧猵⣭j萶q)$꬚⵷0馢W:Ⱍ!Qoe": -1666634370862219540, + "t": "=wp|~碎Q鬳Ӎ\\l-<\/^ﳊhn퐖}䍔t碵ḛ혷?靻䊗", + "邙쇡㯇%#=,E4勃驆V繚q[Y댻XV㡸[逹ᰏ葢B@u=JS5?bLRn얮㍉⏅ﰳ?a6[&큟!藈": 1.2722786745736667E-19 + }, + "X블땨4{ph鵋ꉯ웸 5p簂䦭s_E徔濧d稝~No穔噕뽲)뉈c5M윅>⚋[岦䲟懷恁?鎐꓆ฬ爋獠䜔s{\u001bm鐚儸煛%bﯿXT>ꗘ@8G": 1157841540507770724, + "媤娪Q杸\u0011SAyᡈ쿯": true, + "灚^ಸ%걁<\/蛯?\"祴坓\\\\'흍": -3.4614808555942579E18, + "釴U:O湛㴑䀣렑縓\ta)(j:숾却䗌gCiB뽬Oyuq輥厁/7)?今hY︺Q": null + } + ] + ]]]}] + ], + "I笔趠Ph!<ཛྷ㸞诘X$畉F\u0005笷菟.Esr릙!W☆䲖뗷莾뒭U\"䀸犜Uo3Gꯌx4r蔇᡹㧪쨢準<䂀%ࡡꟼ瑍8炝Xs0䀝销?fi쥱ꆝલBB": -8571484181158525797, + "L⦁o#J|\"⽩-㱢d㌛8d\\㶤傩儻E[Y熯)r噤὘勇 }": "e(濨쓌K䧚僒㘍蠤Vᛸ\"络QJL2,嬓왍伢㋒䴿考澰@(㏾`kX$끑эE斡,蜍&~y", + "vj.|统圪ᵮPL?2oŶ`밧\"勃+0ue%⿥绬췈체$6:qa렐Q;~晘3㙘鹑": true, + "ශؙ4獄⶿c︋i⚅:ん閝Ⳙ苆籦kw{䙞셕pC췃ꍬ␜꟯ꚓ酄b힝hwk꭭M鬋8B耳쑘WQ\\偙ac'唀x᪌\u2048*h짎#ፇ鮠뾏ឿ뀌": false, + "⎀jꄒ牺3Ⓝ컴~?親ꕽぼܓ喏瘘!@<튋㐌꿱⩦{a?Yv%⪧笯Uܱ栅E搚i뚬:ꄃx7䙳ꦋ&䓹vq☶I䁘ᾘ涜\\썉뺌Lr%Bc㍜3?ꝭ砿裞]": null, + "⭤뙓z(㡂%亳K䌽꫿AԾ岺㦦㼴輞낚Vꦴw냟鬓㹈뽈+o3譻K1잞": 2091209026076965894, + "ㇲ\t⋇轑ꠤ룫X긒\"zoY읇희wj梐쐑l侸`e%s": -9.9240075473576563E17, + "啸ꮑ㉰!ᚓ}銏": -4.0694813896301194E18, + ">]囋੽EK뇜>_ꀣ緳碖{쐐裔[<ನ\"䇅\"5L?#xTwv#罐\u0005래t应\\N?빗;": "v쮽瞭p뭃" + } + ]], + "斴槾?Z翁\"~慍弞ﻆ=꜡o5鐋dw\"?K蠡i샾ogDﲰ_C*⬟iㇷ4nય蟏[㟉U꽌娛苸 ঢ়操贻洞펻)쿗૊許X⨪VY츚Z䍾㶭~튃ᵦ<\/E臭tve猑x嚢": null, + "锡⛩<\/칥ꈙᬙ蝀&Ꚑ籬■865?_>L詏쿨䈌浿弥爫̫lj&zx<\/C쉾?覯n?": null, + "꾳鑤/꼩d=ᘈn挫ᑩ䰬ZC": "3錢爋6Ƹ䴗v⪿Wr益G韠[\u0010屗9쁡钁u?殢c䳀蓃樄욂NAq赟c튒瘁렶Aૡɚ捍" + } + ] + ] + ]} + ] + ] + }]]]}} + ]}], + "Ej䗳U<\/Q=灒샎䞦,堰頠@褙g_\u0003ꤾfⶽ?퇋!łB〙ד3CC䌴鈌U:뭔咎(Qો臃䡬荋BO7㢝䟸\"Yb": 2.36010731779814E-20, + "逸'0岔j\u000e눘먷翌C츊秦=ꭣ棭ှ;鳸=麱$XP⩉駚橄A\\좱⛌jqv䰞3Ь踌v㳆¹gT┌gvLB賖烡m?@E঳i": null + }, + "曺v찘ׁ?&绫O័": 9107241066550187880 + } + ] + ], + "(e屄\u0019昜훕琖b蓘ᬄ0/۲묇Z蘮ဏ⨏蛘胯뢃@㘉8ሪWᨮ⦬ᅳ䅴HI၇쨳z囕陻엣1赳o": true, + ",b刈Z,ၠ晐T솝ŕB⩆ou'퐼≃绗雗d譊": null, + "a唥KB\"ﳝ肕$u\n^⅄P䟼냉䞸⩪u윗瀱ꔨ#yşs꒬=1|ﲤ爢`t౐튼쳫_Az(Ṋ擬㦷좕耈6": 2099309172767331582, + "?㴸U<\/䢔ꯡ阽扆㐤q鐋?f㔫wM嬙-;UV죫嚔픞G&\"Cᗍ䪏풊Q": "VM7疹+陕枡툩窲}翡䖶8欞čsT뮐}璤:jﺋ鎴}HfA൝⧻Zd#Qu茅J髒皣Y-︴[?-~쉜v딏璮㹚䅊﩯<-#\u000e걀h\u0004u抱﵊㼃U<㱷⊱IC進" + }, + "숌dee節鏽邺p넱蹓+e罕U": true + } + ], + "b⧴룏??ᔠ3ぱ>%郿劃翐ꏬꠛW瞳᫏누躨狀ໄy੽\"ីuS=㨞馸k乆E": "トz݈^9R䬑<ﮛGRꨳ\u000fTT泠纷꽀MRᴱ纊:㠭볮?%N56%鈕1䗍䜁a䲗j陇=뿻偂衋࿘ᓸ?ᕵZ+<\/}H耢b䀁z^f$&㝒LkꢳI脚뙛u": 5.694374481577558E-20 + }] + } + ]], + "obj": {"key": "wrong value"}, + "퓲꽪m{㶩/뇿#⼢&᭙硞㪔E嚉c樱㬇1a綑᝖DḾ䝩": null + } +} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/webapp.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/webapp.json new file mode 100644 index 0000000000..d540b57f0d --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/webapp.json @@ -0,0 +1,88 @@ +{"web-app": { + "servlet": [ + { + "servlet-name": "cofaxCDS", + "servlet-class": "org.cofax.cds.CDSServlet", + "init-param": { + "configGlossary:installationAt": "Philadelphia, PA", + "configGlossary:adminEmail": "ksm@pobox.com", + "configGlossary:poweredBy": "Cofax", + "configGlossary:poweredByIcon": "/images/cofax.gif", + "configGlossary:staticPath": "/content/static", + "templateProcessorClass": "org.cofax.WysiwygTemplate", + "templateLoaderClass": "org.cofax.FilesTemplateLoader", + "templatePath": "templates", + "templateOverridePath": "", + "defaultListTemplate": "listTemplate.htm", + "defaultFileTemplate": "articleTemplate.htm", + "useJSP": false, + "jspListTemplate": "listTemplate.jsp", + "jspFileTemplate": "articleTemplate.jsp", + "cachePackageTagsTrack": 200, + "cachePackageTagsStore": 200, + "cachePackageTagsRefresh": 60, + "cacheTemplatesTrack": 100, + "cacheTemplatesStore": 50, + "cacheTemplatesRefresh": 15, + "cachePagesTrack": 200, + "cachePagesStore": 100, + "cachePagesRefresh": 10, + "cachePagesDirtyRead": 10, + "searchEngineListTemplate": "forSearchEnginesList.htm", + "searchEngineFileTemplate": "forSearchEngines.htm", + "searchEngineRobotsDb": "WEB-INF/robots.db", + "useDataStore": true, + "dataStoreClass": "org.cofax.SqlDataStore", + "redirectionClass": "org.cofax.SqlRedirection", + "dataStoreName": "cofax", + "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver", + "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon", + "dataStoreUser": "sa", + "dataStorePassword": "dataStoreTestQuery", + "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';", + "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log", + "dataStoreInitConns": 10, + "dataStoreMaxConns": 100, + "dataStoreConnUsageLimit": 100, + "dataStoreLogLevel": "debug", + "maxUrlLength": 500}}, + { + "servlet-name": "cofaxEmail", + "servlet-class": "org.cofax.cds.EmailServlet", + "init-param": { + "mailHost": "mail1", + "mailHostOverride": "mail2"}}, + { + "servlet-name": "cofaxAdmin", + "servlet-class": "org.cofax.cds.AdminServlet"}, + + { + "servlet-name": "fileServlet", + "servlet-class": "org.cofax.cds.FileServlet"}, + { + "servlet-name": "cofaxTools", + "servlet-class": "org.cofax.cms.CofaxToolsServlet", + "init-param": { + "templatePath": "toolstemplates/", + "log": 1, + "logLocation": "/usr/local/tomcat/logs/CofaxTools.log", + "logMaxSize": "", + "dataLog": 1, + "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log", + "dataLogMaxSize": "", + "removePageCache": "/content/admin/remove?cache=pages&id=", + "removeTemplateCache": "/content/admin/remove?cache=templates&id=", + "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder", + "lookInContext": 1, + "adminGroupID": 4, + "betaServer": true}}], + "servlet-mapping": { + "cofaxCDS": "/", + "cofaxEmail": "/cofaxutil/aemail/*", + "cofaxAdmin": "/admin/*", + "fileServlet": "/static/*", + "cofaxTools": "/tools/*"}, + + "taglib": { + "taglib-uri": "cofax.tld", + "taglib-location": "/WEB-INF/tlds/cofax.tld"}}} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/widget.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/widget.json new file mode 100644 index 0000000000..0449493a64 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/data/widget.json @@ -0,0 +1,26 @@ +{"widget": { + "debug": "on", + "window": { + "title": "Sample Konfabulator Widget", + "name": "main_window", + "width": 500, + "height": 500 + }, + "image": { + "src": "Images/Sun.png", + "name": "sun1", + "hOffset": 250, + "vOffset": 250, + "alignment": "center" + }, + "text": { + "data": "Click Here", + "size": 36, + "style": "bold", + "name": "text1", + "hOffset": 250, + "vOffset": 100, + "alignment": "center", + "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" + } +}} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/draft-04/schema b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/draft-04/schema new file mode 100644 index 0000000000..85eb502a68 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/draft-04/schema @@ -0,0 +1,150 @@ +{ + "id": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Core schema meta-schema", + "definitions": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#" } + }, + "positiveInteger": { + "type": "integer", + "minimum": 0 + }, + "positiveIntegerDefault0": { + "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ] + }, + "simpleTypes": { + "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ] + }, + "stringArray": { + "type": "array", + "items": { "type": "string" }, + "minItems": 1, + "uniqueItems": true + } + }, + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uri" + }, + "$schema": { + "type": "string", + "format": "uri" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "default": {}, + "multipleOf": { + "type": "number", + "minimum": 0, + "exclusiveMinimum": true + }, + "maximum": { + "type": "number" + }, + "exclusiveMaximum": { + "type": "boolean", + "default": false + }, + "minimum": { + "type": "number" + }, + "exclusiveMinimum": { + "type": "boolean", + "default": false + }, + "maxLength": { "$ref": "#/definitions/positiveInteger" }, + "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" }, + "pattern": { + "type": "string", + "format": "regex" + }, + "additionalItems": { + "anyOf": [ + { "type": "boolean" }, + { "$ref": "#" } + ], + "default": {} + }, + "items": { + "anyOf": [ + { "$ref": "#" }, + { "$ref": "#/definitions/schemaArray" } + ], + "default": {} + }, + "maxItems": { "$ref": "#/definitions/positiveInteger" }, + "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" }, + "uniqueItems": { + "type": "boolean", + "default": false + }, + "maxProperties": { "$ref": "#/definitions/positiveInteger" }, + "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" }, + "required": { "$ref": "#/definitions/stringArray" }, + "additionalProperties": { + "anyOf": [ + { "type": "boolean" }, + { "$ref": "#" } + ], + "default": {} + }, + "definitions": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} + }, + "properties": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} + }, + "dependencies": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { "$ref": "#" }, + { "$ref": "#/definitions/stringArray" } + ] + } + }, + "enum": { + "type": "array", + "minItems": 1, + "uniqueItems": true + }, + "type": { + "anyOf": [ + { "$ref": "#/definitions/simpleTypes" }, + { + "type": "array", + "items": { "$ref": "#/definitions/simpleTypes" }, + "minItems": 1, + "uniqueItems": true + } + ] + }, + "allOf": { "$ref": "#/definitions/schemaArray" }, + "anyOf": { "$ref": "#/definitions/schemaArray" }, + "oneOf": { "$ref": "#/definitions/schemaArray" }, + "not": { "$ref": "#" } + }, + "dependencies": { + "exclusiveMaximum": [ "maximum" ], + "exclusiveMinimum": [ "minimum" ] + }, + "default": {} +} diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf16be.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf16be.json new file mode 100644 index 0000000000..e46dbfb9dd Binary files /dev/null and b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf16be.json differ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf16bebom.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf16bebom.json new file mode 100644 index 0000000000..0a23ae205c Binary files /dev/null and b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf16bebom.json differ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf16le.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf16le.json new file mode 100644 index 0000000000..92d504530c Binary files /dev/null and b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf16le.json differ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf16lebom.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf16lebom.json new file mode 100644 index 0000000000..eaba00132c Binary files /dev/null and b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf16lebom.json differ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf32be.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf32be.json new file mode 100644 index 0000000000..9cbb522279 Binary files /dev/null and b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf32be.json differ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf32bebom.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf32bebom.json new file mode 100644 index 0000000000..bde6a99ab4 Binary files /dev/null and b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf32bebom.json differ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf32le.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf32le.json new file mode 100644 index 0000000000..b00f290a64 Binary files /dev/null and b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf32le.json differ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf32lebom.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf32lebom.json new file mode 100644 index 0000000000..d3db39bf73 Binary files /dev/null and b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf32lebom.json differ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf8.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf8.json new file mode 100644 index 0000000000..1e27ece50e --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf8.json @@ -0,0 +1,7 @@ +{ + "en":"I can eat glass and it doesn't hurt me.", + "zh-Hant":"我能吞下玻璃而不傷身體。", + "zh-Hans":"我能吞下玻璃而不伤身体。", + "ja":"私はガラスを食べられます。それは私を傷つけません。", + "ko":"나는 유리를 먹을 수 있어요. 그래도 아프지 않아요" +} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf8bom.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf8bom.json new file mode 100644 index 0000000000..07e81e1052 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/encodings/utf8bom.json @@ -0,0 +1,7 @@ +{ + "en":"I can eat glass and it doesn't hurt me.", + "zh-Hant":"我能吞下玻璃而不傷身體。", + "zh-Hans":"我能吞下玻璃而不伤身体。", + "ja":"私はガラスを食べられます。それは私を傷つけません。", + "ko":"나는 유리를 먹을 수 있어요. 그래도 아프지 않아요" +} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail1.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail1.json new file mode 100644 index 0000000000..6216b865f1 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail1.json @@ -0,0 +1 @@ +"A JSON payload should be an object or array, not a string." \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail10.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail10.json new file mode 100644 index 0000000000..5d8c0047bd --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail10.json @@ -0,0 +1 @@ +{"Extra value after close": true} "misplaced quoted value" \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail11.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail11.json new file mode 100644 index 0000000000..76eb95b458 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail11.json @@ -0,0 +1 @@ +{"Illegal expression": 1 + 2} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail12.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail12.json new file mode 100644 index 0000000000..77580a4522 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail12.json @@ -0,0 +1 @@ +{"Illegal invocation": alert()} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail13.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail13.json new file mode 100644 index 0000000000..379406b59b --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail13.json @@ -0,0 +1 @@ +{"Numbers cannot have leading zeroes": 013} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail14.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail14.json new file mode 100644 index 0000000000..0ed366b38a --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail14.json @@ -0,0 +1 @@ +{"Numbers cannot be hex": 0x14} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail15.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail15.json new file mode 100644 index 0000000000..fc8376b605 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail15.json @@ -0,0 +1 @@ +["Illegal backslash escape: \x15"] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail16.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail16.json new file mode 100644 index 0000000000..3fe21d4b53 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail16.json @@ -0,0 +1 @@ +[\naked] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail17.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail17.json new file mode 100644 index 0000000000..62b9214aed --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail17.json @@ -0,0 +1 @@ +["Illegal backslash escape: \017"] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail18.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail18.json new file mode 100644 index 0000000000..edac92716f --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail18.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail19.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail19.json new file mode 100644 index 0000000000..3b9c46fa9a --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail19.json @@ -0,0 +1 @@ +{"Missing colon" null} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail2.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail2.json new file mode 100644 index 0000000000..6b7c11e5a5 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail2.json @@ -0,0 +1 @@ +["Unclosed array" \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail20.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail20.json new file mode 100644 index 0000000000..27c1af3e72 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail20.json @@ -0,0 +1 @@ +{"Double colon":: null} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail21.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail21.json new file mode 100644 index 0000000000..62474573b2 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail21.json @@ -0,0 +1 @@ +{"Comma instead of colon", null} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail22.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail22.json new file mode 100644 index 0000000000..a7752581bc --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail22.json @@ -0,0 +1 @@ +["Colon instead of comma": false] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail23.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail23.json new file mode 100644 index 0000000000..494add1ca1 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail23.json @@ -0,0 +1 @@ +["Bad value", truth] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail24.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail24.json new file mode 100644 index 0000000000..caff239bfc --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail24.json @@ -0,0 +1 @@ +['single quote'] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail25.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail25.json new file mode 100644 index 0000000000..8b7ad23e01 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail25.json @@ -0,0 +1 @@ +[" tab character in string "] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail26.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail26.json new file mode 100644 index 0000000000..845d26a6a5 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail26.json @@ -0,0 +1 @@ +["tab\ character\ in\ string\ "] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail27.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail27.json new file mode 100644 index 0000000000..6b01a2ca4a --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail27.json @@ -0,0 +1,2 @@ +["line +break"] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail28.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail28.json new file mode 100644 index 0000000000..621a0101c6 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail28.json @@ -0,0 +1,2 @@ +["line\ +break"] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail29.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail29.json new file mode 100644 index 0000000000..47ec421bb6 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail29.json @@ -0,0 +1 @@ +[0e] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail3.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail3.json new file mode 100644 index 0000000000..168c81eb78 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail3.json @@ -0,0 +1 @@ +{unquoted_key: "keys must be quoted"} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail30.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail30.json new file mode 100644 index 0000000000..8ab0bc4b8b --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail30.json @@ -0,0 +1 @@ +[0e+] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail31.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail31.json new file mode 100644 index 0000000000..1cce602b51 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail31.json @@ -0,0 +1 @@ +[0e+-1] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail32.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail32.json new file mode 100644 index 0000000000..45cba7396f --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail32.json @@ -0,0 +1 @@ +{"Comma instead if closing brace": true, \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail33.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail33.json new file mode 100644 index 0000000000..ca5eb19dc9 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail33.json @@ -0,0 +1 @@ +["mismatch"} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail4.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail4.json new file mode 100644 index 0000000000..9de168bf34 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail4.json @@ -0,0 +1 @@ +["extra comma",] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail5.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail5.json new file mode 100644 index 0000000000..ddf3ce3d24 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail5.json @@ -0,0 +1 @@ +["double extra comma",,] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail6.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail6.json new file mode 100644 index 0000000000..ed91580e1b --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail6.json @@ -0,0 +1 @@ +[ , "<-- missing value"] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail7.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail7.json new file mode 100644 index 0000000000..8a96af3e4e --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail7.json @@ -0,0 +1 @@ +["Comma after the close"], \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail8.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail8.json new file mode 100644 index 0000000000..b28479c6ec --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail8.json @@ -0,0 +1 @@ +["Extra close"]] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail9.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail9.json new file mode 100644 index 0000000000..5815574f36 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/fail9.json @@ -0,0 +1 @@ +{"Extra comma": true,} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/pass1.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/pass1.json new file mode 100644 index 0000000000..70e2685436 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/pass1.json @@ -0,0 +1,58 @@ +[ + "JSON Test Pattern pass1", + {"object with 1 member":["array with 1 element"]}, + {}, + [], + -42, + true, + false, + null, + { + "integer": 1234567890, + "real": -9876.543210, + "e": 0.123456789e-12, + "E": 1.234567890E+34, + "": 23456789012E66, + "zero": 0, + "one": 1, + "space": " ", + "quote": "\"", + "backslash": "\\", + "controls": "\b\f\n\r\t", + "slash": "/ & \/", + "alpha": "abcdefghijklmnopqrstuvwyz", + "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", + "digit": "0123456789", + "0123456789": "digit", + "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", + "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", + "true": true, + "false": false, + "null": null, + "array":[ ], + "object":{ }, + "address": "50 St. James Street", + "url": "http://www.JSON.org/", + "comment": "// /* */": " ", + " s p a c e d " :[1,2 , 3 + +, + +4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], + "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", + "quotes": "" \u0022 %22 0x22 034 "", + "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" +: "A key can be any string" + }, + 0.5 ,98.6 +, +99.44 +, + +1066, +1e1, +0.1e1, +1e-1, +1e00,2e+00,2e-00 +,"rosebud"] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/pass2.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/pass2.json new file mode 100644 index 0000000000..d3c63c7ad8 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/pass2.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/pass3.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/pass3.json new file mode 100644 index 0000000000..4528d51f1a --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/pass3.json @@ -0,0 +1,6 @@ +{ + "JSON Test Pattern pass3": { + "The outermost value": "must be an object or array.", + "In this test": "It is an object." + } +} diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/readme.txt b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/readme.txt new file mode 100644 index 0000000000..321d89d998 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonchecker/readme.txt @@ -0,0 +1,3 @@ +Test suite from http://json.org/JSON_checker/. + +If the JSON_checker is working correctly, it must accept all of the pass*.json files and reject all of the fail*.json files. diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/.gitignore b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/.gitignore new file mode 100644 index 0000000000..1333ed77b7 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/.gitignore @@ -0,0 +1 @@ +TODO diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/.travis.yml b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/.travis.yml new file mode 100644 index 0000000000..deecd61100 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/.travis.yml @@ -0,0 +1,4 @@ +language: python +python: "2.7" +install: pip install jsonschema +script: bin/jsonschema_suite check diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/LICENSE b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/LICENSE new file mode 100644 index 0000000000..c28adbadd9 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Julian Berman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/README.md b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/README.md new file mode 100644 index 0000000000..6d9da94932 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/README.md @@ -0,0 +1,148 @@ +JSON Schema Test Suite [![Build Status](https://travis-ci.org/json-schema/JSON-Schema-Test-Suite.png?branch=develop)](https://travis-ci.org/json-schema/JSON-Schema-Test-Suite) +====================== + +This repository contains a set of JSON objects that implementors of JSON Schema +validation libraries can use to test their validators. + +It is meant to be language agnostic and should require only a JSON parser. + +The conversion of the JSON objects into tests within your test framework of +choice is still the job of the validator implementor. + +Structure of a Test +------------------- + +If you're going to use this suite, you need to know how tests are laid out. The +tests are contained in the `tests` directory at the root of this repository. + +Inside that directory is a subdirectory for each draft or version of the +schema. We'll use `draft3` as an example. + +If you look inside the draft directory, there are a number of `.json` files, +which logically group a set of test cases together. Often the grouping is by +property under test, but not always, especially within optional test files +(discussed below). + +Inside each `.json` file is a single array containing objects. It's easiest to +illustrate the structure of these with an example: + +```json + { + "description": "the description of the test case", + "schema": {"the schema that should" : "be validated against"}, + "tests": [ + { + "description": "a specific test of a valid instance", + "data": "the instance", + "valid": true + }, + { + "description": "another specific test this time, invalid", + "data": 15, + "valid": false + } + ] + } +``` + +So a description, a schema, and some tests, where tests is an array containing +one or more objects with descriptions, data, and a boolean indicating whether +they should be valid or invalid. + +Coverage +-------- + +Draft 3 and 4 should have full coverage. If you see anything missing or think +there is a useful test missing, please send a pull request or open an issue. + +Who Uses the Test Suite +----------------------- + +This suite is being used by: + +### Coffeescript ### + +* [jsck](https://github.com/pandastrike/jsck) + +### Dart ### + +* [json_schema](https://github.com/patefacio/json_schema) + +### Erlang ### + +* [jesse](https://github.com/klarna/jesse) + +### Go ### + +* [gojsonschema](https://github.com/sigu-399/gojsonschema) +* [validate-json](https://github.com/cesanta/validate-json) + +### Haskell ### + +* [aeson-schema](https://github.com/timjb/aeson-schema) +* [hjsonschema](https://github.com/seagreen/hjsonschema) + +### Java ### + +* [json-schema-validator](https://github.com/fge/json-schema-validator) + +### JavaScript ### + +* [json-schema-benchmark](https://github.com/Muscula/json-schema-benchmark) +* [direct-schema](https://github.com/IreneKnapp/direct-schema) +* [is-my-json-valid](https://github.com/mafintosh/is-my-json-valid) +* [jassi](https://github.com/iclanzan/jassi) +* [JaySchema](https://github.com/natesilva/jayschema) +* [json-schema-valid](https://github.com/ericgj/json-schema-valid) +* [Jsonary](https://github.com/jsonary-js/jsonary) +* [jsonschema](https://github.com/tdegrunt/jsonschema) +* [request-validator](https://github.com/bugventure/request-validator) +* [skeemas](https://github.com/Prestaul/skeemas) +* [tv4](https://github.com/geraintluff/tv4) +* [z-schema](https://github.com/zaggino/z-schema) +* [jsen](https://github.com/bugventure/jsen) +* [ajv](https://github.com/epoberezkin/ajv) + +### Node.js ### + +The JSON Schema Test Suite is also available as an +[npm](https://www.npmjs.com/package/json-schema-test-suite) package. +Node-specific support is maintained on the [node branch](https://github.com/json-schema/JSON-Schema-Test-Suite/tree/node). +See [NODE-README.md](https://github.com/json-schema/JSON-Schema-Test-Suite/blob/node/NODE-README.md) +for more information. + +### .NET ### + +* [Newtonsoft.Json.Schema](https://github.com/JamesNK/Newtonsoft.Json.Schema) + +### PHP ### + +* [json-schema](https://github.com/justinrainbow/json-schema) + +### Python ### + +* [jsonschema](https://github.com/Julian/jsonschema) + +### Ruby ### + +* [json-schema](https://github.com/hoxworth/json-schema) + +### Rust ### + +* [valico](https://github.com/rustless/valico) + +### Swift ### + +* [JSONSchema](https://github.com/kylef/JSONSchema.swift) + +If you use it as well, please fork and send a pull request adding yourself to +the list :). + +Contributing +------------ + +If you see something missing or incorrect, a pull request is most welcome! + +There are some sanity checks in place for testing the test suite. You can run +them with `bin/jsonschema_suite check` or `tox`. They will be run automatically by +[Travis CI](https://travis-ci.org/) as well. diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/bin/jsonschema_suite b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/bin/jsonschema_suite new file mode 100755 index 0000000000..96108c86ba --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/bin/jsonschema_suite @@ -0,0 +1,283 @@ +#! /usr/bin/env python +from __future__ import print_function +import sys +import textwrap + +try: + import argparse +except ImportError: + print(textwrap.dedent(""" + The argparse library could not be imported. jsonschema_suite requires + either Python 2.7 or for you to install argparse. You can do so by + running `pip install argparse`, `easy_install argparse` or by + downloading argparse and running `python2.6 setup.py install`. + + See https://pypi.python.org/pypi/argparse for details. + """.strip("\n"))) + sys.exit(1) + +import errno +import fnmatch +import json +import os +import random +import shutil +import unittest +import warnings + +if getattr(unittest, "skipIf", None) is None: + unittest.skipIf = lambda cond, msg : lambda fn : fn + +try: + import jsonschema +except ImportError: + jsonschema = None +else: + validators = getattr( + jsonschema.validators, "validators", jsonschema.validators + ) + + +ROOT_DIR = os.path.join( + os.path.dirname(__file__), os.pardir).rstrip("__pycache__") +SUITE_ROOT_DIR = os.path.join(ROOT_DIR, "tests") + +REMOTES = { + "integer.json": {"type": "integer"}, + "subSchemas.json": { + "integer": {"type": "integer"}, + "refToInteger": {"$ref": "#/integer"}, + }, + "folder/folderInteger.json": {"type": "integer"} +} +REMOTES_DIR = os.path.join(ROOT_DIR, "remotes") + +TESTSUITE_SCHEMA = { + "$schema": "http://json-schema.org/draft-03/schema#", + "type": "array", + "items": { + "type": "object", + "properties": { + "description": {"type": "string", "required": True}, + "schema": {"required": True}, + "tests": { + "type": "array", + "items": { + "type": "object", + "properties": { + "description": {"type": "string", "required": True}, + "data": {"required": True}, + "valid": {"type": "boolean", "required": True} + }, + "additionalProperties": False + }, + "minItems": 1 + } + }, + "additionalProperties": False, + "minItems": 1 + } +} + + +def files(paths): + for path in paths: + with open(path) as test_file: + yield json.load(test_file) + + +def groups(paths): + for test_file in files(paths): + for group in test_file: + yield group + + +def cases(paths): + for test_group in groups(paths): + for test in test_group["tests"]: + test["schema"] = test_group["schema"] + yield test + + +def collect(root_dir): + for root, dirs, files in os.walk(root_dir): + for filename in fnmatch.filter(files, "*.json"): + yield os.path.join(root, filename) + + +class SanityTests(unittest.TestCase): + @classmethod + def setUpClass(cls): + print("Looking for tests in %s" % SUITE_ROOT_DIR) + cls.test_files = list(collect(SUITE_ROOT_DIR)) + print("Found %s test files" % len(cls.test_files)) + assert cls.test_files, "Didn't find the test files!" + + def test_all_files_are_valid_json(self): + for path in self.test_files: + with open(path) as test_file: + try: + json.load(test_file) + except ValueError as error: + self.fail("%s contains invalid JSON (%s)" % (path, error)) + + def test_all_descriptions_have_reasonable_length(self): + for case in cases(self.test_files): + descript = case["description"] + self.assertLess( + len(descript), + 60, + "%r is too long! (keep it to less than 60 chars)" % (descript,) + ) + + def test_all_descriptions_are_unique(self): + for group in groups(self.test_files): + descriptions = set(test["description"] for test in group["tests"]) + self.assertEqual( + len(descriptions), + len(group["tests"]), + "%r contains a duplicate description" % (group,) + ) + + @unittest.skipIf(jsonschema is None, "Validation library not present!") + def test_all_schemas_are_valid(self): + for schema in os.listdir(SUITE_ROOT_DIR): + schema_validator = validators.get(schema) + if schema_validator is not None: + test_files = collect(os.path.join(SUITE_ROOT_DIR, schema)) + for case in cases(test_files): + try: + schema_validator.check_schema(case["schema"]) + except jsonschema.SchemaError as error: + self.fail("%s contains an invalid schema (%s)" % + (case, error)) + else: + warnings.warn("No schema validator for %s" % schema) + + @unittest.skipIf(jsonschema is None, "Validation library not present!") + def test_suites_are_valid(self): + validator = jsonschema.Draft3Validator(TESTSUITE_SCHEMA) + for tests in files(self.test_files): + try: + validator.validate(tests) + except jsonschema.ValidationError as error: + self.fail(str(error)) + + def test_remote_schemas_are_updated(self): + for url, schema in REMOTES.items(): + filepath = os.path.join(REMOTES_DIR, url) + with open(filepath) as schema_file: + self.assertEqual(json.load(schema_file), schema) + + +def main(arguments): + if arguments.command == "check": + suite = unittest.TestLoader().loadTestsFromTestCase(SanityTests) + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(not result.wasSuccessful()) + elif arguments.command == "flatten": + selected_cases = [case for case in cases(collect(arguments.version))] + + if arguments.randomize: + random.shuffle(selected_cases) + + json.dump(selected_cases, sys.stdout, indent=4, sort_keys=True) + elif arguments.command == "remotes": + json.dump(REMOTES, sys.stdout, indent=4, sort_keys=True) + elif arguments.command == "dump_remotes": + if arguments.update: + shutil.rmtree(arguments.out_dir, ignore_errors=True) + + try: + os.makedirs(arguments.out_dir) + except OSError as e: + if e.errno == errno.EEXIST: + print("%s already exists. Aborting." % arguments.out_dir) + sys.exit(1) + raise + + for url, schema in REMOTES.items(): + filepath = os.path.join(arguments.out_dir, url) + + try: + os.makedirs(os.path.dirname(filepath)) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + with open(filepath, "wb") as out_file: + json.dump(schema, out_file, indent=4, sort_keys=True) + elif arguments.command == "serve": + try: + from flask import Flask, jsonify + except ImportError: + print(textwrap.dedent(""" + The Flask library is required to serve the remote schemas. + + You can install it by running `pip install Flask`. + + Alternatively, see the `jsonschema_suite remotes` or + `jsonschema_suite dump_remotes` commands to create static files + that can be served with your own web server. + """.strip("\n"))) + sys.exit(1) + + app = Flask(__name__) + + @app.route("/") + def serve_path(path): + if path in REMOTES: + return jsonify(REMOTES[path]) + return "Document does not exist.", 404 + + app.run(port=1234) + + +parser = argparse.ArgumentParser( + description="JSON Schema Test Suite utilities", +) +subparsers = parser.add_subparsers(help="utility commands", dest="command") + +check = subparsers.add_parser("check", help="Sanity check the test suite.") + +flatten = subparsers.add_parser( + "flatten", + help="Output a flattened file containing a selected version's test cases." +) +flatten.add_argument( + "--randomize", + action="store_true", + help="Randomize the order of the outputted cases.", +) +flatten.add_argument( + "version", help="The directory containing the version to output", +) + +remotes = subparsers.add_parser( + "remotes", + help="Output the expected URLs and their associated schemas for remote " + "ref tests as a JSON object." +) + +dump_remotes = subparsers.add_parser( + "dump_remotes", help="Dump the remote ref schemas into a file tree", +) +dump_remotes.add_argument( + "--update", + action="store_true", + help="Update the remotes in an existing directory.", +) +dump_remotes.add_argument( + "--out-dir", + default=REMOTES_DIR, + type=os.path.abspath, + help="The output directory to create as the root of the file tree", +) + +serve = subparsers.add_parser( + "serve", + help="Start a webserver to serve schemas used by remote ref tests." +) + +if __name__ == "__main__": + main(parser.parse_args()) diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/remotes/folder/folderInteger.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/remotes/folder/folderInteger.json new file mode 100644 index 0000000000..dbe5c758ee --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/remotes/folder/folderInteger.json @@ -0,0 +1,3 @@ +{ + "type": "integer" +} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/remotes/integer.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/remotes/integer.json new file mode 100644 index 0000000000..dbe5c758ee --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/remotes/integer.json @@ -0,0 +1,3 @@ +{ + "type": "integer" +} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/remotes/subSchemas.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/remotes/subSchemas.json new file mode 100644 index 0000000000..8b6d8f842f --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/remotes/subSchemas.json @@ -0,0 +1,8 @@ +{ + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/integer" + } +} \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/additionalItems.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/additionalItems.json new file mode 100644 index 0000000000..6d4bff51cf --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/additionalItems.json @@ -0,0 +1,82 @@ +[ + { + "description": "additionalItems as schema", + "schema": { + "items": [], + "additionalItems": {"type": "integer"} + }, + "tests": [ + { + "description": "additional items match schema", + "data": [ 1, 2, 3, 4 ], + "valid": true + }, + { + "description": "additional items do not match schema", + "data": [ 1, 2, 3, "foo" ], + "valid": false + } + ] + }, + { + "description": "items is schema, no additionalItems", + "schema": { + "items": {}, + "additionalItems": false + }, + "tests": [ + { + "description": "all items match schema", + "data": [ 1, 2, 3, 4, 5 ], + "valid": true + } + ] + }, + { + "description": "array of items with no additionalItems", + "schema": { + "items": [{}, {}, {}], + "additionalItems": false + }, + "tests": [ + { + "description": "no additional items present", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "additional items are not permitted", + "data": [ 1, 2, 3, 4 ], + "valid": false + } + ] + }, + { + "description": "additionalItems as false without items", + "schema": {"additionalItems": false}, + "tests": [ + { + "description": + "items defaults to empty schema so everything is valid", + "data": [ 1, 2, 3, 4, 5 ], + "valid": true + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + } + ] + }, + { + "description": "additionalItems are allowed by default", + "schema": {"items": []}, + "tests": [ + { + "description": "only the first items are validated", + "data": [1, "foo", false], + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/additionalProperties.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/additionalProperties.json new file mode 100644 index 0000000000..40831f9e9a --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/additionalProperties.json @@ -0,0 +1,88 @@ +[ + { + "description": + "additionalProperties being false does not allow other properties", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "patternProperties": { "^v": {} }, + "additionalProperties": false + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": [1, 2, 3], + "valid": true + }, + { + "description": "patternProperties are not additional properties", + "data": {"foo":1, "vroom": 2}, + "valid": true + } + ] + }, + { + "description": + "additionalProperties allows a schema which should validate", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional valid property is valid", + "data": {"foo" : 1, "bar" : 2, "quux" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : 12}, + "valid": false + } + ] + }, + { + "description": + "additionalProperties can exist by itself", + "schema": { + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "an additional valid property is valid", + "data": {"foo" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1}, + "valid": false + } + ] + }, + { + "description": "additionalProperties are allowed by default", + "schema": {"properties": {"foo": {}, "bar": {}}}, + "tests": [ + { + "description": "additional properties are allowed", + "data": {"foo": 1, "bar": 2, "quux": true}, + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/default.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/default.json new file mode 100644 index 0000000000..17629779fb --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/default.json @@ -0,0 +1,49 @@ +[ + { + "description": "invalid type for default", + "schema": { + "properties": { + "foo": { + "type": "integer", + "default": [] + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"foo": 13}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + }, + { + "description": "invalid string value for default", + "schema": { + "properties": { + "bar": { + "type": "string", + "minLength": 4, + "default": "bad" + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"bar": "good"}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/dependencies.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/dependencies.json new file mode 100644 index 0000000000..2f6ae489ae --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/dependencies.json @@ -0,0 +1,108 @@ +[ + { + "description": "dependencies", + "schema": { + "dependencies": {"bar": "foo"} + }, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependant", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "with dependency", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "multiple dependencies", + "schema": { + "dependencies": {"quux": ["foo", "bar"]} + }, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependants", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "with dependencies", + "data": {"foo": 1, "bar": 2, "quux": 3}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"foo": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing other dependency", + "data": {"bar": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing both dependencies", + "data": {"quux": 1}, + "valid": false + } + ] + }, + { + "description": "multiple dependencies subschema", + "schema": { + "dependencies": { + "bar": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "integer"} + } + } + } + }, + "tests": [ + { + "description": "valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "wrong type", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "wrong type other", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + }, + { + "description": "wrong type both", + "data": {"foo": "quux", "bar": "quux"}, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/disallow.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/disallow.json new file mode 100644 index 0000000000..a5c9d90cce --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/disallow.json @@ -0,0 +1,80 @@ +[ + { + "description": "disallow", + "schema": { + "disallow": "integer" + }, + "tests": [ + { + "description": "allowed", + "data": "foo", + "valid": true + }, + { + "description": "disallowed", + "data": 1, + "valid": false + } + ] + }, + { + "description": "multiple disallow", + "schema": { + "disallow": ["integer", "boolean"] + }, + "tests": [ + { + "description": "valid", + "data": "foo", + "valid": true + }, + { + "description": "mismatch", + "data": 1, + "valid": false + }, + { + "description": "other mismatch", + "data": true, + "valid": false + } + ] + }, + { + "description": "multiple disallow subschema", + "schema": { + "disallow": + ["string", + { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + } + }] + }, + "tests": [ + { + "description": "match", + "data": 1, + "valid": true + }, + { + "description": "other match", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "mismatch", + "data": "foo", + "valid": false + }, + { + "description": "other mismatch", + "data": {"foo": "bar"}, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/divisibleBy.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/divisibleBy.json new file mode 100644 index 0000000000..ef7cc14890 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/divisibleBy.json @@ -0,0 +1,60 @@ +[ + { + "description": "by int", + "schema": {"divisibleBy": 2}, + "tests": [ + { + "description": "int by int", + "data": 10, + "valid": true + }, + { + "description": "int by int fail", + "data": 7, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "by number", + "schema": {"divisibleBy": 1.5}, + "tests": [ + { + "description": "zero is divisible by anything (except 0)", + "data": 0, + "valid": true + }, + { + "description": "4.5 is divisible by 1.5", + "data": 4.5, + "valid": true + }, + { + "description": "35 is not divisible by 1.5", + "data": 35, + "valid": false + } + ] + }, + { + "description": "by small number", + "schema": {"divisibleBy": 0.0001}, + "tests": [ + { + "description": "0.0075 is divisible by 0.0001", + "data": 0.0075, + "valid": true + }, + { + "description": "0.00751 is not divisible by 0.0001", + "data": 0.00751, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/enum.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/enum.json new file mode 100644 index 0000000000..0c83f0804d --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/enum.json @@ -0,0 +1,71 @@ +[ + { + "description": "simple enum validation", + "schema": {"enum": [1, 2, 3]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": 1, + "valid": true + }, + { + "description": "something else is invalid", + "data": 4, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum validation", + "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": [], + "valid": true + }, + { + "description": "something else is invalid", + "data": null, + "valid": false + }, + { + "description": "objects are deep compared", + "data": {"foo": false}, + "valid": false + } + ] + }, + { + "description": "enums in properties", + "schema": { + "type":"object", + "properties": { + "foo": {"enum":["foo"]}, + "bar": {"enum":["bar"], "required":true} + } + }, + "tests": [ + { + "description": "both properties are valid", + "data": {"foo":"foo", "bar":"bar"}, + "valid": true + }, + { + "description": "missing optional property is valid", + "data": {"bar":"bar"}, + "valid": true + }, + { + "description": "missing required property is invalid", + "data": {"foo":"foo"}, + "valid": false + }, + { + "description": "missing all properties is invalid", + "data": {}, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/extends.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/extends.json new file mode 100644 index 0000000000..909bce575a --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/extends.json @@ -0,0 +1,94 @@ +[ + { + "description": "extends", + "schema": { + "properties": {"bar": {"type": "integer", "required": true}}, + "extends": { + "properties": { + "foo": {"type": "string", "required": true} + } + } + }, + "tests": [ + { + "description": "extends", + "data": {"foo": "baz", "bar": 2}, + "valid": true + }, + { + "description": "mismatch extends", + "data": {"foo": "baz"}, + "valid": false + }, + { + "description": "mismatch extended", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "wrong type", + "data": {"foo": "baz", "bar": "quux"}, + "valid": false + } + ] + }, + { + "description": "multiple extends", + "schema": { + "properties": {"bar": {"type": "integer", "required": true}}, + "extends" : [ + { + "properties": { + "foo": {"type": "string", "required": true} + } + }, + { + "properties": { + "baz": {"type": "null", "required": true} + } + } + ] + }, + "tests": [ + { + "description": "valid", + "data": {"foo": "quux", "bar": 2, "baz": null}, + "valid": true + }, + { + "description": "mismatch first extends", + "data": {"bar": 2, "baz": null}, + "valid": false + }, + { + "description": "mismatch second extends", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "mismatch both", + "data": {"bar": 2}, + "valid": false + } + ] + }, + { + "description": "extends simple types", + "schema": { + "minimum": 20, + "extends": {"maximum": 30} + }, + "tests": [ + { + "description": "valid", + "data": 25, + "valid": true + }, + { + "description": "mismatch extends", + "data": 35, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/items.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/items.json new file mode 100644 index 0000000000..f5e18a1384 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/items.json @@ -0,0 +1,46 @@ +[ + { + "description": "a schema given for items", + "schema": { + "items": {"type": "integer"} + }, + "tests": [ + { + "description": "valid items", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "wrong type of items", + "data": [1, "x"], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + } + ] + }, + { + "description": "an array of schemas for items", + "schema": { + "items": [ + {"type": "integer"}, + {"type": "string"} + ] + }, + "tests": [ + { + "description": "correct types", + "data": [ 1, "foo" ], + "valid": true + }, + { + "description": "wrong types", + "data": [ "foo", 1 ], + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/maxItems.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/maxItems.json new file mode 100644 index 0000000000..3b53a6b371 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/maxItems.json @@ -0,0 +1,28 @@ +[ + { + "description": "maxItems validation", + "schema": {"maxItems": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": [1], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "too long is invalid", + "data": [1, 2, 3], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "foobar", + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/maxLength.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/maxLength.json new file mode 100644 index 0000000000..4de42bcaba --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/maxLength.json @@ -0,0 +1,33 @@ +[ + { + "description": "maxLength validation", + "schema": {"maxLength": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": "f", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too long is invalid", + "data": "foo", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 10, + "valid": true + }, + { + "description": "two supplementary Unicode code points is long enough", + "data": "\uD83D\uDCA9\uD83D\uDCA9", + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/maximum.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/maximum.json new file mode 100644 index 0000000000..86c7b89c9a --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/maximum.json @@ -0,0 +1,42 @@ +[ + { + "description": "maximum validation", + "schema": {"maximum": 3.0}, + "tests": [ + { + "description": "below the maximum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 3.5, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "exclusiveMaximum validation", + "schema": { + "maximum": 3.0, + "exclusiveMaximum": true + }, + "tests": [ + { + "description": "below the maximum is still valid", + "data": 2.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 3.0, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/minItems.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/minItems.json new file mode 100644 index 0000000000..ed5118815e --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/minItems.json @@ -0,0 +1,28 @@ +[ + { + "description": "minItems validation", + "schema": {"minItems": 1}, + "tests": [ + { + "description": "longer is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1], + "valid": true + }, + { + "description": "too short is invalid", + "data": [], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "", + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/minLength.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/minLength.json new file mode 100644 index 0000000000..3f09158dee --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/minLength.json @@ -0,0 +1,33 @@ +[ + { + "description": "minLength validation", + "schema": {"minLength": 2}, + "tests": [ + { + "description": "longer is valid", + "data": "foo", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too short is invalid", + "data": "f", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 1, + "valid": true + }, + { + "description": "one supplementary Unicode code point is not long enough", + "data": "\uD83D\uDCA9", + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/minimum.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/minimum.json new file mode 100644 index 0000000000..d5bf000bcc --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/minimum.json @@ -0,0 +1,42 @@ +[ + { + "description": "minimum validation", + "schema": {"minimum": 1.1}, + "tests": [ + { + "description": "above the minimum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "below the minimum is invalid", + "data": 0.6, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "exclusiveMinimum validation", + "schema": { + "minimum": 1.1, + "exclusiveMinimum": true + }, + "tests": [ + { + "description": "above the minimum is still valid", + "data": 1.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 1.1, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/optional/bignum.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/optional/bignum.json new file mode 100644 index 0000000000..ccc7c17fe8 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/optional/bignum.json @@ -0,0 +1,107 @@ +[ + { + "description": "integer", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "a bignum is an integer", + "data": 12345678910111213141516171819202122232425262728293031, + "valid": true + } + ] + }, + { + "description": "number", + "schema": {"type": "number"}, + "tests": [ + { + "description": "a bignum is a number", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": true + } + ] + }, + { + "description": "integer", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "a negative bignum is an integer", + "data": -12345678910111213141516171819202122232425262728293031, + "valid": true + } + ] + }, + { + "description": "number", + "schema": {"type": "number"}, + "tests": [ + { + "description": "a negative bignum is a number", + "data": -98249283749234923498293171823948729348710298301928331, + "valid": true + } + ] + }, + { + "description": "string", + "schema": {"type": "string"}, + "tests": [ + { + "description": "a bignum is not a string", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": {"maximum": 18446744073709551615}, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision", + "schema": { + "maximum": 972783798187987123879878123.18878137, + "exclusiveMaximum": true + }, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 972783798187987123879878123.188781371, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": {"minimum": -18446744073709551615}, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision on negative numbers", + "schema": { + "minimum": -972783798187987123879878123.18878137, + "exclusiveMinimum": true + }, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -972783798187987123879878123.188781371, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/optional/format.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/optional/format.json new file mode 100644 index 0000000000..3ca7319dda --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/optional/format.json @@ -0,0 +1,222 @@ +[ + { + "description": "validation of regular expressions", + "schema": {"format": "regex"}, + "tests": [ + { + "description": "a valid regular expression", + "data": "([abc])+\\s+$", + "valid": true + }, + { + "description": "a regular expression with unclosed parens is invalid", + "data": "^(abc]", + "valid": false + } + ] + }, + { + "description": "validation of date-time strings", + "schema": {"format": "date-time"}, + "tests": [ + { + "description": "a valid date-time string", + "data": "1963-06-19T08:30:06.283185Z", + "valid": true + }, + { + "description": "an invalid date-time string", + "data": "06/19/1963 08:30:06 PST", + "valid": false + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350T01:01:01", + "valid": false + } + ] + }, + { + "description": "validation of date strings", + "schema": {"format": "date"}, + "tests": [ + { + "description": "a valid date string", + "data": "1963-06-19", + "valid": true + }, + { + "description": "an invalid date string", + "data": "06/19/1963", + "valid": false + } + ] + }, + { + "description": "validation of time strings", + "schema": {"format": "time"}, + "tests": [ + { + "description": "a valid time string", + "data": "08:30:06", + "valid": true + }, + { + "description": "an invalid time string", + "data": "8:30 AM", + "valid": false + } + ] + }, + { + "description": "validation of URIs", + "schema": {"format": "uri"}, + "tests": [ + { + "description": "a valid URI", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid protocol-relative URI", + "data": "//foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "an invalid URI", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "an invalid URI though valid URI reference", + "data": "abc", + "valid": false + } + ] + }, + { + "description": "validation of e-mail addresses", + "schema": {"format": "email"}, + "tests": [ + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false + } + ] + }, + { + "description": "validation of IP addresses", + "schema": {"format": "ip-address"}, + "tests": [ + { + "description": "a valid IP address", + "data": "192.168.0.1", + "valid": true + }, + { + "description": "an IP address with too many components", + "data": "127.0.0.0.1", + "valid": false + }, + { + "description": "an IP address with out-of-range values", + "data": "256.256.256.256", + "valid": false + } + ] + }, + { + "description": "validation of IPv6 addresses", + "schema": {"format": "ipv6"}, + "tests": [ + { + "description": "a valid IPv6 address", + "data": "::1", + "valid": true + }, + { + "description": "an IPv6 address with out-of-range values", + "data": "12345::", + "valid": false + }, + { + "description": "an IPv6 address with too many components", + "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", + "valid": false + }, + { + "description": "an IPv6 address containing illegal characters", + "data": "::laptop", + "valid": false + } + ] + }, + { + "description": "validation of host names", + "schema": {"format": "host-name"}, + "tests": [ + { + "description": "a valid host name", + "data": "www.example.com", + "valid": true + }, + { + "description": "a host name starting with an illegal character", + "data": "-a-host-name-that-starts-with--", + "valid": false + }, + { + "description": "a host name containing illegal characters", + "data": "not_a_valid_host_name", + "valid": false + }, + { + "description": "a host name with a component too long", + "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", + "valid": false + } + ] + }, + { + "description": "validation of CSS colors", + "schema": {"format": "color"}, + "tests": [ + { + "description": "a valid CSS color name", + "data": "fuchsia", + "valid": true + }, + { + "description": "a valid six-digit CSS color code", + "data": "#CC8899", + "valid": true + }, + { + "description": "a valid three-digit CSS color code", + "data": "#C89", + "valid": true + }, + { + "description": "an invalid CSS color code", + "data": "#00332520", + "valid": false + }, + { + "description": "an invalid CSS color name", + "data": "puce", + "valid": false + }, + { + "description": "a CSS color name containing invalid characters", + "data": "light_grayish_red-violet", + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/optional/jsregex.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/optional/jsregex.json new file mode 100644 index 0000000000..03fe97724c --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/optional/jsregex.json @@ -0,0 +1,18 @@ +[ + { + "description": "ECMA 262 regex dialect recognition", + "schema": { "format": "regex" }, + "tests": [ + { + "description": "[^] is a valid regex", + "data": "[^]", + "valid": true + }, + { + "description": "ECMA 262 has no support for lookbehind", + "data": "(?<=foo)bar", + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/optional/zeroTerminatedFloats.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/optional/zeroTerminatedFloats.json new file mode 100644 index 0000000000..9b50ea2776 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/optional/zeroTerminatedFloats.json @@ -0,0 +1,15 @@ +[ + { + "description": "some languages do not distinguish between different types of numeric value", + "schema": { + "type": "integer" + }, + "tests": [ + { + "description": "a float is not an integer even without fractional part", + "data": 1.0, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/pattern.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/pattern.json new file mode 100644 index 0000000000..25e7299731 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/pattern.json @@ -0,0 +1,34 @@ +[ + { + "description": "pattern validation", + "schema": {"pattern": "^a*$"}, + "tests": [ + { + "description": "a matching pattern is valid", + "data": "aaa", + "valid": true + }, + { + "description": "a non-matching pattern is invalid", + "data": "abc", + "valid": false + }, + { + "description": "ignores non-strings", + "data": true, + "valid": true + } + ] + }, + { + "description": "pattern is not anchored", + "schema": {"pattern": "a+"}, + "tests": [ + { + "description": "matches a substring", + "data": "xxaayy", + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/patternProperties.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/patternProperties.json new file mode 100644 index 0000000000..18586e5dab --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/patternProperties.json @@ -0,0 +1,110 @@ +[ + { + "description": + "patternProperties validates properties matching a regex", + "schema": { + "patternProperties": { + "f.*o": {"type": "integer"} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "multiple valid matches is valid", + "data": {"foo": 1, "foooooo" : 2}, + "valid": true + }, + { + "description": "a single invalid match is invalid", + "data": {"foo": "bar", "fooooo": 2}, + "valid": false + }, + { + "description": "multiple invalid matches is invalid", + "data": {"foo": "bar", "foooooo" : "baz"}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "multiple simultaneous patternProperties are validated", + "schema": { + "patternProperties": { + "a*": {"type": "integer"}, + "aaa*": {"maximum": 20} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"a": 21}, + "valid": true + }, + { + "description": "a simultaneous match is valid", + "data": {"aaaa": 18}, + "valid": true + }, + { + "description": "multiple matches is valid", + "data": {"a": 21, "aaaa": 18}, + "valid": true + }, + { + "description": "an invalid due to one is invalid", + "data": {"a": "bar"}, + "valid": false + }, + { + "description": "an invalid due to the other is invalid", + "data": {"aaaa": 31}, + "valid": false + }, + { + "description": "an invalid due to both is invalid", + "data": {"aaa": "foo", "aaaa": 31}, + "valid": false + } + ] + }, + { + "description": "regexes are not anchored by default and are case sensitive", + "schema": { + "patternProperties": { + "[0-9]{2,}": { "type": "boolean" }, + "X_": { "type": "string" } + } + }, + "tests": [ + { + "description": "non recognized members are ignored", + "data": { "answer 1": "42" }, + "valid": true + }, + { + "description": "recognized members are accounted for", + "data": { "a31b": null }, + "valid": false + }, + { + "description": "regexes are case sensitive", + "data": { "a_x_3": 3 }, + "valid": true + }, + { + "description": "regexes are case sensitive, 2", + "data": { "a_X_3": 3 }, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/properties.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/properties.json new file mode 100644 index 0000000000..cd1644dcd9 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/properties.json @@ -0,0 +1,92 @@ +[ + { + "description": "object properties validation", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "string"} + } + }, + "tests": [ + { + "description": "both properties present and valid is valid", + "data": {"foo": 1, "bar": "baz"}, + "valid": true + }, + { + "description": "one property invalid is invalid", + "data": {"foo": 1, "bar": {}}, + "valid": false + }, + { + "description": "both properties invalid is invalid", + "data": {"foo": [], "bar": {}}, + "valid": false + }, + { + "description": "doesn't invalidate other properties", + "data": {"quux": []}, + "valid": true + }, + { + "description": "ignores non-objects", + "data": [], + "valid": true + } + ] + }, + { + "description": + "properties, patternProperties, additionalProperties interaction", + "schema": { + "properties": { + "foo": {"type": "array", "maxItems": 3}, + "bar": {"type": "array"} + }, + "patternProperties": {"f.o": {"minItems": 2}}, + "additionalProperties": {"type": "integer"} + }, + "tests": [ + { + "description": "property validates property", + "data": {"foo": [1, 2]}, + "valid": true + }, + { + "description": "property invalidates property", + "data": {"foo": [1, 2, 3, 4]}, + "valid": false + }, + { + "description": "patternProperty invalidates property", + "data": {"foo": []}, + "valid": false + }, + { + "description": "patternProperty validates nonproperty", + "data": {"fxo": [1, 2]}, + "valid": true + }, + { + "description": "patternProperty invalidates nonproperty", + "data": {"fxo": []}, + "valid": false + }, + { + "description": "additionalProperty ignores property", + "data": {"bar": []}, + "valid": true + }, + { + "description": "additionalProperty validates others", + "data": {"quux": 3}, + "valid": true + }, + { + "description": "additionalProperty invalidates others", + "data": {"quux": "foo"}, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/ref.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/ref.json new file mode 100644 index 0000000000..903ecb6bce --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/ref.json @@ -0,0 +1,159 @@ +[ + { + "description": "root pointer ref", + "schema": { + "properties": { + "foo": {"$ref": "#"} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "match", + "data": {"foo": false}, + "valid": true + }, + { + "description": "recursive match", + "data": {"foo": {"foo": false}}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": false}, + "valid": false + }, + { + "description": "recursive mismatch", + "data": {"foo": {"bar": false}}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to object", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"$ref": "#/properties/foo"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to array", + "schema": { + "items": [ + {"type": "integer"}, + {"$ref": "#/items/0"} + ] + }, + "tests": [ + { + "description": "match array", + "data": [1, 2], + "valid": true + }, + { + "description": "mismatch array", + "data": [1, "foo"], + "valid": false + } + ] + }, + { + "description": "escaped pointer ref", + "schema": { + "tilda~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"}, + "properties": { + "tilda": {"$ref": "#/tilda~0field"}, + "slash": {"$ref": "#/slash~1field"}, + "percent": {"$ref": "#/percent%25field"} + } + }, + "tests": [ + { + "description": "slash invalid", + "data": {"slash": "aoeu"}, + "valid": false + }, + { + "description": "tilda invalid", + "data": {"tilda": "aoeu"}, + "valid": false + }, + { + "description": "percent invalid", + "data": {"percent": "aoeu"}, + "valid": false + }, + { + "description": "slash valid", + "data": {"slash": 123}, + "valid": true + }, + { + "description": "tilda valid", + "data": {"tilda": 123}, + "valid": true + }, + { + "description": "percent valid", + "data": {"percent": 123}, + "valid": true + } + ] + }, + { + "description": "nested refs", + "schema": { + "definitions": { + "a": {"type": "integer"}, + "b": {"$ref": "#/definitions/a"}, + "c": {"$ref": "#/definitions/b"} + }, + "$ref": "#/definitions/c" + }, + "tests": [ + { + "description": "nested ref valid", + "data": 5, + "valid": true + }, + { + "description": "nested ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "remote ref, containing refs itself", + "schema": {"$ref": "http://json-schema.org/draft-03/schema#"}, + "tests": [ + { + "description": "remote ref valid", + "data": {"items": {"type": "integer"}}, + "valid": true + }, + { + "description": "remote ref invalid", + "data": {"items": {"type": 1}}, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/refRemote.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/refRemote.json new file mode 100644 index 0000000000..4ca804732c --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/refRemote.json @@ -0,0 +1,74 @@ +[ + { + "description": "remote ref", + "schema": {"$ref": "http://localhost:1234/integer.json"}, + "tests": [ + { + "description": "remote ref valid", + "data": 1, + "valid": true + }, + { + "description": "remote ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "fragment within remote ref", + "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, + "tests": [ + { + "description": "remote fragment valid", + "data": 1, + "valid": true + }, + { + "description": "remote fragment invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "ref within remote ref", + "schema": { + "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" + }, + "tests": [ + { + "description": "ref within ref valid", + "data": 1, + "valid": true + }, + { + "description": "ref within ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "change resolution scope", + "schema": { + "id": "http://localhost:1234/", + "items": { + "id": "folder/", + "items": {"$ref": "folderInteger.json"} + } + }, + "tests": [ + { + "description": "changed scope ref valid", + "data": [[1]], + "valid": true + }, + { + "description": "changed scope ref invalid", + "data": [["a"]], + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/required.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/required.json new file mode 100644 index 0000000000..aaaf024273 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/required.json @@ -0,0 +1,53 @@ +[ + { + "description": "required validation", + "schema": { + "properties": { + "foo": {"required" : true}, + "bar": {} + } + }, + "tests": [ + { + "description": "present required property is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "non-present required property is invalid", + "data": {"bar": 1}, + "valid": false + } + ] + }, + { + "description": "required default validation", + "schema": { + "properties": { + "foo": {} + } + }, + "tests": [ + { + "description": "not required by default", + "data": {}, + "valid": true + } + ] + }, + { + "description": "required explicitly false validation", + "schema": { + "properties": { + "foo": {"required": false} + } + }, + "tests": [ + { + "description": "not required if required is false", + "data": {}, + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/type.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/type.json new file mode 100644 index 0000000000..337da1206d --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/type.json @@ -0,0 +1,474 @@ +[ + { + "description": "integer type matches integers", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "an integer is an integer", + "data": 1, + "valid": true + }, + { + "description": "a float is not an integer", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an integer", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an integer", + "data": {}, + "valid": false + }, + { + "description": "an array is not an integer", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an integer", + "data": true, + "valid": false + }, + { + "description": "null is not an integer", + "data": null, + "valid": false + } + ] + }, + { + "description": "number type matches numbers", + "schema": {"type": "number"}, + "tests": [ + { + "description": "an integer is a number", + "data": 1, + "valid": true + }, + { + "description": "a float is a number", + "data": 1.1, + "valid": true + }, + { + "description": "a string is not a number", + "data": "foo", + "valid": false + }, + { + "description": "an object is not a number", + "data": {}, + "valid": false + }, + { + "description": "an array is not a number", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a number", + "data": true, + "valid": false + }, + { + "description": "null is not a number", + "data": null, + "valid": false + } + ] + }, + { + "description": "string type matches strings", + "schema": {"type": "string"}, + "tests": [ + { + "description": "1 is not a string", + "data": 1, + "valid": false + }, + { + "description": "a float is not a string", + "data": 1.1, + "valid": false + }, + { + "description": "a string is a string", + "data": "foo", + "valid": true + }, + { + "description": "an object is not a string", + "data": {}, + "valid": false + }, + { + "description": "an array is not a string", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a string", + "data": true, + "valid": false + }, + { + "description": "null is not a string", + "data": null, + "valid": false + } + ] + }, + { + "description": "object type matches objects", + "schema": {"type": "object"}, + "tests": [ + { + "description": "an integer is not an object", + "data": 1, + "valid": false + }, + { + "description": "a float is not an object", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an object", + "data": "foo", + "valid": false + }, + { + "description": "an object is an object", + "data": {}, + "valid": true + }, + { + "description": "an array is not an object", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an object", + "data": true, + "valid": false + }, + { + "description": "null is not an object", + "data": null, + "valid": false + } + ] + }, + { + "description": "array type matches arrays", + "schema": {"type": "array"}, + "tests": [ + { + "description": "an integer is not an array", + "data": 1, + "valid": false + }, + { + "description": "a float is not an array", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an array", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an array", + "data": {}, + "valid": false + }, + { + "description": "an array is an array", + "data": [], + "valid": true + }, + { + "description": "a boolean is not an array", + "data": true, + "valid": false + }, + { + "description": "null is not an array", + "data": null, + "valid": false + } + ] + }, + { + "description": "boolean type matches booleans", + "schema": {"type": "boolean"}, + "tests": [ + { + "description": "an integer is not a boolean", + "data": 1, + "valid": false + }, + { + "description": "a float is not a boolean", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not a boolean", + "data": "foo", + "valid": false + }, + { + "description": "an object is not a boolean", + "data": {}, + "valid": false + }, + { + "description": "an array is not a boolean", + "data": [], + "valid": false + }, + { + "description": "a boolean is a boolean", + "data": true, + "valid": true + }, + { + "description": "null is not a boolean", + "data": null, + "valid": false + } + ] + }, + { + "description": "null type matches only the null object", + "schema": {"type": "null"}, + "tests": [ + { + "description": "an integer is not null", + "data": 1, + "valid": false + }, + { + "description": "a float is not null", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not null", + "data": "foo", + "valid": false + }, + { + "description": "an object is not null", + "data": {}, + "valid": false + }, + { + "description": "an array is not null", + "data": [], + "valid": false + }, + { + "description": "a boolean is not null", + "data": true, + "valid": false + }, + { + "description": "null is null", + "data": null, + "valid": true + } + ] + }, + { + "description": "any type matches any type", + "schema": {"type": "any"}, + "tests": [ + { + "description": "any type includes integers", + "data": 1, + "valid": true + }, + { + "description": "any type includes float", + "data": 1.1, + "valid": true + }, + { + "description": "any type includes string", + "data": "foo", + "valid": true + }, + { + "description": "any type includes object", + "data": {}, + "valid": true + }, + { + "description": "any type includes array", + "data": [], + "valid": true + }, + { + "description": "any type includes boolean", + "data": true, + "valid": true + }, + { + "description": "any type includes null", + "data": null, + "valid": true + } + ] + }, + { + "description": "multiple types can be specified in an array", + "schema": {"type": ["integer", "string"]}, + "tests": [ + { + "description": "an integer is valid", + "data": 1, + "valid": true + }, + { + "description": "a string is valid", + "data": "foo", + "valid": true + }, + { + "description": "a float is invalid", + "data": 1.1, + "valid": false + }, + { + "description": "an object is invalid", + "data": {}, + "valid": false + }, + { + "description": "an array is invalid", + "data": [], + "valid": false + }, + { + "description": "a boolean is invalid", + "data": true, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + } + ] + }, + { + "description": "types can include schemas", + "schema": { + "type": [ + "array", + {"type": "object"} + ] + }, + "tests": [ + { + "description": "an integer is invalid", + "data": 1, + "valid": false + }, + { + "description": "a string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "a float is invalid", + "data": 1.1, + "valid": false + }, + { + "description": "an object is valid", + "data": {}, + "valid": true + }, + { + "description": "an array is valid", + "data": [], + "valid": true + }, + { + "description": "a boolean is invalid", + "data": true, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + } + ] + }, + { + "description": + "when types includes a schema it should fully validate the schema", + "schema": { + "type": [ + "integer", + { + "properties": { + "foo": {"type": "null"} + } + } + ] + }, + "tests": [ + { + "description": "an integer is valid", + "data": 1, + "valid": true + }, + { + "description": "an object is valid only if it is fully valid", + "data": {"foo": null}, + "valid": true + }, + { + "description": "an object is invalid otherwise", + "data": {"foo": "bar"}, + "valid": false + } + ] + }, + { + "description": "types from separate schemas are merged", + "schema": { + "type": [ + {"type": ["string"]}, + {"type": ["array", "null"]} + ] + }, + "tests": [ + { + "description": "an integer is invalid", + "data": 1, + "valid": false + }, + { + "description": "a string is valid", + "data": "foo", + "valid": true + }, + { + "description": "an array is valid", + "data": [1, 2, 3], + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/uniqueItems.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/uniqueItems.json new file mode 100644 index 0000000000..c1f4ab99c9 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft3/uniqueItems.json @@ -0,0 +1,79 @@ +[ + { + "description": "uniqueItems validation", + "schema": {"uniqueItems": true}, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is invalid", + "data": [1, 1], + "valid": false + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": false + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is invalid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": false + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is invalid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": false + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is invalid", + "data": [["foo"], ["foo"]], + "valid": false + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are invalid", + "data": [{}, [1], true, null, {}, 1], + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/additionalItems.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/additionalItems.json new file mode 100644 index 0000000000..521745c8d6 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/additionalItems.json @@ -0,0 +1,82 @@ +[ + { + "description": "additionalItems as schema", + "schema": { + "items": [{}], + "additionalItems": {"type": "integer"} + }, + "tests": [ + { + "description": "additional items match schema", + "data": [ null, 2, 3, 4 ], + "valid": true + }, + { + "description": "additional items do not match schema", + "data": [ null, 2, 3, "foo" ], + "valid": false + } + ] + }, + { + "description": "items is schema, no additionalItems", + "schema": { + "items": {}, + "additionalItems": false + }, + "tests": [ + { + "description": "all items match schema", + "data": [ 1, 2, 3, 4, 5 ], + "valid": true + } + ] + }, + { + "description": "array of items with no additionalItems", + "schema": { + "items": [{}, {}, {}], + "additionalItems": false + }, + "tests": [ + { + "description": "no additional items present", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "additional items are not permitted", + "data": [ 1, 2, 3, 4 ], + "valid": false + } + ] + }, + { + "description": "additionalItems as false without items", + "schema": {"additionalItems": false}, + "tests": [ + { + "description": + "items defaults to empty schema so everything is valid", + "data": [ 1, 2, 3, 4, 5 ], + "valid": true + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + } + ] + }, + { + "description": "additionalItems are allowed by default", + "schema": {"items": [{"type": "integer"}]}, + "tests": [ + { + "description": "only the first item is validated", + "data": [1, "foo", false], + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/additionalProperties.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/additionalProperties.json new file mode 100644 index 0000000000..40831f9e9a --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/additionalProperties.json @@ -0,0 +1,88 @@ +[ + { + "description": + "additionalProperties being false does not allow other properties", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "patternProperties": { "^v": {} }, + "additionalProperties": false + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": [1, 2, 3], + "valid": true + }, + { + "description": "patternProperties are not additional properties", + "data": {"foo":1, "vroom": 2}, + "valid": true + } + ] + }, + { + "description": + "additionalProperties allows a schema which should validate", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional valid property is valid", + "data": {"foo" : 1, "bar" : 2, "quux" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : 12}, + "valid": false + } + ] + }, + { + "description": + "additionalProperties can exist by itself", + "schema": { + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "an additional valid property is valid", + "data": {"foo" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1}, + "valid": false + } + ] + }, + { + "description": "additionalProperties are allowed by default", + "schema": {"properties": {"foo": {}, "bar": {}}}, + "tests": [ + { + "description": "additional properties are allowed", + "data": {"foo": 1, "bar": 2, "quux": true}, + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/allOf.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/allOf.json new file mode 100644 index 0000000000..bbb5f89e4b --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/allOf.json @@ -0,0 +1,112 @@ +[ + { + "description": "allOf", + "schema": { + "allOf": [ + { + "properties": { + "bar": {"type": "integer"} + }, + "required": ["bar"] + }, + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "allOf", + "data": {"foo": "baz", "bar": 2}, + "valid": true + }, + { + "description": "mismatch second", + "data": {"foo": "baz"}, + "valid": false + }, + { + "description": "mismatch first", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "wrong type", + "data": {"foo": "baz", "bar": "quux"}, + "valid": false + } + ] + }, + { + "description": "allOf with base schema", + "schema": { + "properties": {"bar": {"type": "integer"}}, + "required": ["bar"], + "allOf" : [ + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + }, + { + "properties": { + "baz": {"type": "null"} + }, + "required": ["baz"] + } + ] + }, + "tests": [ + { + "description": "valid", + "data": {"foo": "quux", "bar": 2, "baz": null}, + "valid": true + }, + { + "description": "mismatch base schema", + "data": {"foo": "quux", "baz": null}, + "valid": false + }, + { + "description": "mismatch first allOf", + "data": {"bar": 2, "baz": null}, + "valid": false + }, + { + "description": "mismatch second allOf", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "mismatch both", + "data": {"bar": 2}, + "valid": false + } + ] + }, + { + "description": "allOf simple types", + "schema": { + "allOf": [ + {"maximum": 30}, + {"minimum": 20} + ] + }, + "tests": [ + { + "description": "valid", + "data": 25, + "valid": true + }, + { + "description": "mismatch one", + "data": 35, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/anyOf.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/anyOf.json new file mode 100644 index 0000000000..a58714afd8 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/anyOf.json @@ -0,0 +1,68 @@ +[ + { + "description": "anyOf", + "schema": { + "anyOf": [ + { + "type": "integer" + }, + { + "minimum": 2 + } + ] + }, + "tests": [ + { + "description": "first anyOf valid", + "data": 1, + "valid": true + }, + { + "description": "second anyOf valid", + "data": 2.5, + "valid": true + }, + { + "description": "both anyOf valid", + "data": 3, + "valid": true + }, + { + "description": "neither anyOf valid", + "data": 1.5, + "valid": false + } + ] + }, + { + "description": "anyOf with base schema", + "schema": { + "type": "string", + "anyOf" : [ + { + "maxLength": 2 + }, + { + "minLength": 4 + } + ] + }, + "tests": [ + { + "description": "mismatch base schema", + "data": 3, + "valid": false + }, + { + "description": "one anyOf valid", + "data": "foobar", + "valid": true + }, + { + "description": "both anyOf invalid", + "data": "foo", + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/default.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/default.json new file mode 100644 index 0000000000..17629779fb --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/default.json @@ -0,0 +1,49 @@ +[ + { + "description": "invalid type for default", + "schema": { + "properties": { + "foo": { + "type": "integer", + "default": [] + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"foo": 13}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + }, + { + "description": "invalid string value for default", + "schema": { + "properties": { + "bar": { + "type": "string", + "minLength": 4, + "default": "bad" + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"bar": "good"}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/definitions.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/definitions.json new file mode 100644 index 0000000000..cf935a3215 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/definitions.json @@ -0,0 +1,32 @@ +[ + { + "description": "valid definition", + "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, + "tests": [ + { + "description": "valid definition schema", + "data": { + "definitions": { + "foo": {"type": "integer"} + } + }, + "valid": true + } + ] + }, + { + "description": "invalid definition", + "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, + "tests": [ + { + "description": "invalid definition schema", + "data": { + "definitions": { + "foo": {"type": 1} + } + }, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/dependencies.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/dependencies.json new file mode 100644 index 0000000000..7b9b16a7e1 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/dependencies.json @@ -0,0 +1,113 @@ +[ + { + "description": "dependencies", + "schema": { + "dependencies": {"bar": ["foo"]} + }, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependant", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "with dependency", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "multiple dependencies", + "schema": { + "dependencies": {"quux": ["foo", "bar"]} + }, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependants", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "with dependencies", + "data": {"foo": 1, "bar": 2, "quux": 3}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"foo": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing other dependency", + "data": {"bar": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing both dependencies", + "data": {"quux": 1}, + "valid": false + } + ] + }, + { + "description": "multiple dependencies subschema", + "schema": { + "dependencies": { + "bar": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "integer"} + } + } + } + }, + "tests": [ + { + "description": "valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "no dependency", + "data": {"foo": "quux"}, + "valid": true + }, + { + "description": "wrong type", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "wrong type other", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + }, + { + "description": "wrong type both", + "data": {"foo": "quux", "bar": "quux"}, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/enum.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/enum.json new file mode 100644 index 0000000000..f124436a7d --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/enum.json @@ -0,0 +1,72 @@ +[ + { + "description": "simple enum validation", + "schema": {"enum": [1, 2, 3]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": 1, + "valid": true + }, + { + "description": "something else is invalid", + "data": 4, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum validation", + "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": [], + "valid": true + }, + { + "description": "something else is invalid", + "data": null, + "valid": false + }, + { + "description": "objects are deep compared", + "data": {"foo": false}, + "valid": false + } + ] + }, + { + "description": "enums in properties", + "schema": { + "type":"object", + "properties": { + "foo": {"enum":["foo"]}, + "bar": {"enum":["bar"]} + }, + "required": ["bar"] + }, + "tests": [ + { + "description": "both properties are valid", + "data": {"foo":"foo", "bar":"bar"}, + "valid": true + }, + { + "description": "missing optional property is valid", + "data": {"bar":"bar"}, + "valid": true + }, + { + "description": "missing required property is invalid", + "data": {"foo":"foo"}, + "valid": false + }, + { + "description": "missing all properties is invalid", + "data": {}, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/items.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/items.json new file mode 100644 index 0000000000..f5e18a1384 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/items.json @@ -0,0 +1,46 @@ +[ + { + "description": "a schema given for items", + "schema": { + "items": {"type": "integer"} + }, + "tests": [ + { + "description": "valid items", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "wrong type of items", + "data": [1, "x"], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + } + ] + }, + { + "description": "an array of schemas for items", + "schema": { + "items": [ + {"type": "integer"}, + {"type": "string"} + ] + }, + "tests": [ + { + "description": "correct types", + "data": [ 1, "foo" ], + "valid": true + }, + { + "description": "wrong types", + "data": [ "foo", 1 ], + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/maxItems.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/maxItems.json new file mode 100644 index 0000000000..3b53a6b371 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/maxItems.json @@ -0,0 +1,28 @@ +[ + { + "description": "maxItems validation", + "schema": {"maxItems": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": [1], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "too long is invalid", + "data": [1, 2, 3], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "foobar", + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/maxLength.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/maxLength.json new file mode 100644 index 0000000000..811d35b253 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/maxLength.json @@ -0,0 +1,33 @@ +[ + { + "description": "maxLength validation", + "schema": {"maxLength": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": "f", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too long is invalid", + "data": "foo", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + }, + { + "description": "two supplementary Unicode code points is long enough", + "data": "\uD83D\uDCA9\uD83D\uDCA9", + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/maxProperties.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/maxProperties.json new file mode 100644 index 0000000000..d282446ad6 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/maxProperties.json @@ -0,0 +1,28 @@ +[ + { + "description": "maxProperties validation", + "schema": {"maxProperties": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "exact length is valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "too long is invalid", + "data": {"foo": 1, "bar": 2, "baz": 3}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "foobar", + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/maximum.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/maximum.json new file mode 100644 index 0000000000..86c7b89c9a --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/maximum.json @@ -0,0 +1,42 @@ +[ + { + "description": "maximum validation", + "schema": {"maximum": 3.0}, + "tests": [ + { + "description": "below the maximum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 3.5, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "exclusiveMaximum validation", + "schema": { + "maximum": 3.0, + "exclusiveMaximum": true + }, + "tests": [ + { + "description": "below the maximum is still valid", + "data": 2.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 3.0, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/minItems.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/minItems.json new file mode 100644 index 0000000000..ed5118815e --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/minItems.json @@ -0,0 +1,28 @@ +[ + { + "description": "minItems validation", + "schema": {"minItems": 1}, + "tests": [ + { + "description": "longer is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1], + "valid": true + }, + { + "description": "too short is invalid", + "data": [], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "", + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/minLength.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/minLength.json new file mode 100644 index 0000000000..3f09158dee --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/minLength.json @@ -0,0 +1,33 @@ +[ + { + "description": "minLength validation", + "schema": {"minLength": 2}, + "tests": [ + { + "description": "longer is valid", + "data": "foo", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too short is invalid", + "data": "f", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 1, + "valid": true + }, + { + "description": "one supplementary Unicode code point is not long enough", + "data": "\uD83D\uDCA9", + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/minProperties.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/minProperties.json new file mode 100644 index 0000000000..a72c7d293e --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/minProperties.json @@ -0,0 +1,28 @@ +[ + { + "description": "minProperties validation", + "schema": {"minProperties": 1}, + "tests": [ + { + "description": "longer is valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "exact length is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "too short is invalid", + "data": {}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "", + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/minimum.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/minimum.json new file mode 100644 index 0000000000..d5bf000bcc --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/minimum.json @@ -0,0 +1,42 @@ +[ + { + "description": "minimum validation", + "schema": {"minimum": 1.1}, + "tests": [ + { + "description": "above the minimum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "below the minimum is invalid", + "data": 0.6, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "exclusiveMinimum validation", + "schema": { + "minimum": 1.1, + "exclusiveMinimum": true + }, + "tests": [ + { + "description": "above the minimum is still valid", + "data": 1.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 1.1, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/multipleOf.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/multipleOf.json new file mode 100644 index 0000000000..ca3b761805 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/multipleOf.json @@ -0,0 +1,60 @@ +[ + { + "description": "by int", + "schema": {"multipleOf": 2}, + "tests": [ + { + "description": "int by int", + "data": 10, + "valid": true + }, + { + "description": "int by int fail", + "data": 7, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "by number", + "schema": {"multipleOf": 1.5}, + "tests": [ + { + "description": "zero is multiple of anything", + "data": 0, + "valid": true + }, + { + "description": "4.5 is multiple of 1.5", + "data": 4.5, + "valid": true + }, + { + "description": "35 is not multiple of 1.5", + "data": 35, + "valid": false + } + ] + }, + { + "description": "by small number", + "schema": {"multipleOf": 0.0001}, + "tests": [ + { + "description": "0.0075 is multiple of 0.0001", + "data": 0.0075, + "valid": true + }, + { + "description": "0.00751 is not multiple of 0.0001", + "data": 0.00751, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/not.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/not.json new file mode 100644 index 0000000000..cbb7f46bf8 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/not.json @@ -0,0 +1,96 @@ +[ + { + "description": "not", + "schema": { + "not": {"type": "integer"} + }, + "tests": [ + { + "description": "allowed", + "data": "foo", + "valid": true + }, + { + "description": "disallowed", + "data": 1, + "valid": false + } + ] + }, + { + "description": "not multiple types", + "schema": { + "not": {"type": ["integer", "boolean"]} + }, + "tests": [ + { + "description": "valid", + "data": "foo", + "valid": true + }, + { + "description": "mismatch", + "data": 1, + "valid": false + }, + { + "description": "other mismatch", + "data": true, + "valid": false + } + ] + }, + { + "description": "not more complex schema", + "schema": { + "not": { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + } + } + }, + "tests": [ + { + "description": "match", + "data": 1, + "valid": true + }, + { + "description": "other match", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "mismatch", + "data": {"foo": "bar"}, + "valid": false + } + ] + }, + { + "description": "forbidden property", + "schema": { + "properties": { + "foo": { + "not": {} + } + } + }, + "tests": [ + { + "description": "property present", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "property absent", + "data": {"bar": 1, "baz": 2}, + "valid": true + } + ] + } + +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/oneOf.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/oneOf.json new file mode 100644 index 0000000000..1eaa4e4794 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/oneOf.json @@ -0,0 +1,68 @@ +[ + { + "description": "oneOf", + "schema": { + "oneOf": [ + { + "type": "integer" + }, + { + "minimum": 2 + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": 1, + "valid": true + }, + { + "description": "second oneOf valid", + "data": 2.5, + "valid": true + }, + { + "description": "both oneOf valid", + "data": 3, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": 1.5, + "valid": false + } + ] + }, + { + "description": "oneOf with base schema", + "schema": { + "type": "string", + "oneOf" : [ + { + "minLength": 2 + }, + { + "maxLength": 4 + } + ] + }, + "tests": [ + { + "description": "mismatch base schema", + "data": 3, + "valid": false + }, + { + "description": "one oneOf valid", + "data": "foobar", + "valid": true + }, + { + "description": "both oneOf valid", + "data": "foo", + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/optional/bignum.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/optional/bignum.json new file mode 100644 index 0000000000..ccc7c17fe8 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/optional/bignum.json @@ -0,0 +1,107 @@ +[ + { + "description": "integer", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "a bignum is an integer", + "data": 12345678910111213141516171819202122232425262728293031, + "valid": true + } + ] + }, + { + "description": "number", + "schema": {"type": "number"}, + "tests": [ + { + "description": "a bignum is a number", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": true + } + ] + }, + { + "description": "integer", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "a negative bignum is an integer", + "data": -12345678910111213141516171819202122232425262728293031, + "valid": true + } + ] + }, + { + "description": "number", + "schema": {"type": "number"}, + "tests": [ + { + "description": "a negative bignum is a number", + "data": -98249283749234923498293171823948729348710298301928331, + "valid": true + } + ] + }, + { + "description": "string", + "schema": {"type": "string"}, + "tests": [ + { + "description": "a bignum is not a string", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": {"maximum": 18446744073709551615}, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision", + "schema": { + "maximum": 972783798187987123879878123.18878137, + "exclusiveMaximum": true + }, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 972783798187987123879878123.188781371, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": {"minimum": -18446744073709551615}, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision on negative numbers", + "schema": { + "minimum": -972783798187987123879878123.18878137, + "exclusiveMinimum": true + }, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -972783798187987123879878123.188781371, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/optional/format.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/optional/format.json new file mode 100644 index 0000000000..aacfd11984 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/optional/format.json @@ -0,0 +1,148 @@ +[ + { + "description": "validation of date-time strings", + "schema": {"format": "date-time"}, + "tests": [ + { + "description": "a valid date-time string", + "data": "1963-06-19T08:30:06.283185Z", + "valid": true + }, + { + "description": "an invalid date-time string", + "data": "06/19/1963 08:30:06 PST", + "valid": false + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350T01:01:01", + "valid": false + } + ] + }, + { + "description": "validation of URIs", + "schema": {"format": "uri"}, + "tests": [ + { + "description": "a valid URI", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "a valid protocol-relative URI", + "data": "//foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "an invalid URI", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "an invalid URI though valid URI reference", + "data": "abc", + "valid": false + } + ] + }, + { + "description": "validation of e-mail addresses", + "schema": {"format": "email"}, + "tests": [ + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false + } + ] + }, + { + "description": "validation of IP addresses", + "schema": {"format": "ipv4"}, + "tests": [ + { + "description": "a valid IP address", + "data": "192.168.0.1", + "valid": true + }, + { + "description": "an IP address with too many components", + "data": "127.0.0.0.1", + "valid": false + }, + { + "description": "an IP address with out-of-range values", + "data": "256.256.256.256", + "valid": false + }, + { + "description": "an IP address without 4 components", + "data": "127.0", + "valid": false + }, + { + "description": "an IP address as an integer", + "data": "0x7f000001", + "valid": false + } + ] + }, + { + "description": "validation of IPv6 addresses", + "schema": {"format": "ipv6"}, + "tests": [ + { + "description": "a valid IPv6 address", + "data": "::1", + "valid": true + }, + { + "description": "an IPv6 address with out-of-range values", + "data": "12345::", + "valid": false + }, + { + "description": "an IPv6 address with too many components", + "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", + "valid": false + }, + { + "description": "an IPv6 address containing illegal characters", + "data": "::laptop", + "valid": false + } + ] + }, + { + "description": "validation of host names", + "schema": {"format": "hostname"}, + "tests": [ + { + "description": "a valid host name", + "data": "www.example.com", + "valid": true + }, + { + "description": "a host name starting with an illegal character", + "data": "-a-host-name-that-starts-with--", + "valid": false + }, + { + "description": "a host name containing illegal characters", + "data": "not_a_valid_host_name", + "valid": false + }, + { + "description": "a host name with a component too long", + "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/optional/zeroTerminatedFloats.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/optional/zeroTerminatedFloats.json new file mode 100644 index 0000000000..9b50ea2776 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/optional/zeroTerminatedFloats.json @@ -0,0 +1,15 @@ +[ + { + "description": "some languages do not distinguish between different types of numeric value", + "schema": { + "type": "integer" + }, + "tests": [ + { + "description": "a float is not an integer even without fractional part", + "data": 1.0, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/pattern.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/pattern.json new file mode 100644 index 0000000000..25e7299731 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/pattern.json @@ -0,0 +1,34 @@ +[ + { + "description": "pattern validation", + "schema": {"pattern": "^a*$"}, + "tests": [ + { + "description": "a matching pattern is valid", + "data": "aaa", + "valid": true + }, + { + "description": "a non-matching pattern is invalid", + "data": "abc", + "valid": false + }, + { + "description": "ignores non-strings", + "data": true, + "valid": true + } + ] + }, + { + "description": "pattern is not anchored", + "schema": {"pattern": "a+"}, + "tests": [ + { + "description": "matches a substring", + "data": "xxaayy", + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/patternProperties.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/patternProperties.json new file mode 100644 index 0000000000..18586e5dab --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/patternProperties.json @@ -0,0 +1,110 @@ +[ + { + "description": + "patternProperties validates properties matching a regex", + "schema": { + "patternProperties": { + "f.*o": {"type": "integer"} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "multiple valid matches is valid", + "data": {"foo": 1, "foooooo" : 2}, + "valid": true + }, + { + "description": "a single invalid match is invalid", + "data": {"foo": "bar", "fooooo": 2}, + "valid": false + }, + { + "description": "multiple invalid matches is invalid", + "data": {"foo": "bar", "foooooo" : "baz"}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "multiple simultaneous patternProperties are validated", + "schema": { + "patternProperties": { + "a*": {"type": "integer"}, + "aaa*": {"maximum": 20} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"a": 21}, + "valid": true + }, + { + "description": "a simultaneous match is valid", + "data": {"aaaa": 18}, + "valid": true + }, + { + "description": "multiple matches is valid", + "data": {"a": 21, "aaaa": 18}, + "valid": true + }, + { + "description": "an invalid due to one is invalid", + "data": {"a": "bar"}, + "valid": false + }, + { + "description": "an invalid due to the other is invalid", + "data": {"aaaa": 31}, + "valid": false + }, + { + "description": "an invalid due to both is invalid", + "data": {"aaa": "foo", "aaaa": 31}, + "valid": false + } + ] + }, + { + "description": "regexes are not anchored by default and are case sensitive", + "schema": { + "patternProperties": { + "[0-9]{2,}": { "type": "boolean" }, + "X_": { "type": "string" } + } + }, + "tests": [ + { + "description": "non recognized members are ignored", + "data": { "answer 1": "42" }, + "valid": true + }, + { + "description": "recognized members are accounted for", + "data": { "a31b": null }, + "valid": false + }, + { + "description": "regexes are case sensitive", + "data": { "a_x_3": 3 }, + "valid": true + }, + { + "description": "regexes are case sensitive, 2", + "data": { "a_X_3": 3 }, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/properties.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/properties.json new file mode 100644 index 0000000000..cd1644dcd9 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/properties.json @@ -0,0 +1,92 @@ +[ + { + "description": "object properties validation", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "string"} + } + }, + "tests": [ + { + "description": "both properties present and valid is valid", + "data": {"foo": 1, "bar": "baz"}, + "valid": true + }, + { + "description": "one property invalid is invalid", + "data": {"foo": 1, "bar": {}}, + "valid": false + }, + { + "description": "both properties invalid is invalid", + "data": {"foo": [], "bar": {}}, + "valid": false + }, + { + "description": "doesn't invalidate other properties", + "data": {"quux": []}, + "valid": true + }, + { + "description": "ignores non-objects", + "data": [], + "valid": true + } + ] + }, + { + "description": + "properties, patternProperties, additionalProperties interaction", + "schema": { + "properties": { + "foo": {"type": "array", "maxItems": 3}, + "bar": {"type": "array"} + }, + "patternProperties": {"f.o": {"minItems": 2}}, + "additionalProperties": {"type": "integer"} + }, + "tests": [ + { + "description": "property validates property", + "data": {"foo": [1, 2]}, + "valid": true + }, + { + "description": "property invalidates property", + "data": {"foo": [1, 2, 3, 4]}, + "valid": false + }, + { + "description": "patternProperty invalidates property", + "data": {"foo": []}, + "valid": false + }, + { + "description": "patternProperty validates nonproperty", + "data": {"fxo": [1, 2]}, + "valid": true + }, + { + "description": "patternProperty invalidates nonproperty", + "data": {"fxo": []}, + "valid": false + }, + { + "description": "additionalProperty ignores property", + "data": {"bar": []}, + "valid": true + }, + { + "description": "additionalProperty validates others", + "data": {"quux": 3}, + "valid": true + }, + { + "description": "additionalProperty invalidates others", + "data": {"quux": "foo"}, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/ref.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/ref.json new file mode 100644 index 0000000000..7e80552249 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/ref.json @@ -0,0 +1,159 @@ +[ + { + "description": "root pointer ref", + "schema": { + "properties": { + "foo": {"$ref": "#"} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "match", + "data": {"foo": false}, + "valid": true + }, + { + "description": "recursive match", + "data": {"foo": {"foo": false}}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": false}, + "valid": false + }, + { + "description": "recursive mismatch", + "data": {"foo": {"bar": false}}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to object", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"$ref": "#/properties/foo"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to array", + "schema": { + "items": [ + {"type": "integer"}, + {"$ref": "#/items/0"} + ] + }, + "tests": [ + { + "description": "match array", + "data": [1, 2], + "valid": true + }, + { + "description": "mismatch array", + "data": [1, "foo"], + "valid": false + } + ] + }, + { + "description": "escaped pointer ref", + "schema": { + "tilda~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"}, + "properties": { + "tilda": {"$ref": "#/tilda~0field"}, + "slash": {"$ref": "#/slash~1field"}, + "percent": {"$ref": "#/percent%25field"} + } + }, + "tests": [ + { + "description": "slash invalid", + "data": {"slash": "aoeu"}, + "valid": false + }, + { + "description": "tilda invalid", + "data": {"tilda": "aoeu"}, + "valid": false + }, + { + "description": "percent invalid", + "data": {"percent": "aoeu"}, + "valid": false + }, + { + "description": "slash valid", + "data": {"slash": 123}, + "valid": true + }, + { + "description": "tilda valid", + "data": {"tilda": 123}, + "valid": true + }, + { + "description": "percent valid", + "data": {"percent": 123}, + "valid": true + } + ] + }, + { + "description": "nested refs", + "schema": { + "definitions": { + "a": {"type": "integer"}, + "b": {"$ref": "#/definitions/a"}, + "c": {"$ref": "#/definitions/b"} + }, + "$ref": "#/definitions/c" + }, + "tests": [ + { + "description": "nested ref valid", + "data": 5, + "valid": true + }, + { + "description": "nested ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "remote ref, containing refs itself", + "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, + "tests": [ + { + "description": "remote ref valid", + "data": {"minLength": 1}, + "valid": true + }, + { + "description": "remote ref invalid", + "data": {"minLength": -1}, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/refRemote.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/refRemote.json new file mode 100644 index 0000000000..4ca804732c --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/refRemote.json @@ -0,0 +1,74 @@ +[ + { + "description": "remote ref", + "schema": {"$ref": "http://localhost:1234/integer.json"}, + "tests": [ + { + "description": "remote ref valid", + "data": 1, + "valid": true + }, + { + "description": "remote ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "fragment within remote ref", + "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, + "tests": [ + { + "description": "remote fragment valid", + "data": 1, + "valid": true + }, + { + "description": "remote fragment invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "ref within remote ref", + "schema": { + "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" + }, + "tests": [ + { + "description": "ref within ref valid", + "data": 1, + "valid": true + }, + { + "description": "ref within ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "change resolution scope", + "schema": { + "id": "http://localhost:1234/", + "items": { + "id": "folder/", + "items": {"$ref": "folderInteger.json"} + } + }, + "tests": [ + { + "description": "changed scope ref valid", + "data": [[1]], + "valid": true + }, + { + "description": "changed scope ref invalid", + "data": [["a"]], + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/required.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/required.json new file mode 100644 index 0000000000..612f73f347 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/required.json @@ -0,0 +1,39 @@ +[ + { + "description": "required validation", + "schema": { + "properties": { + "foo": {}, + "bar": {} + }, + "required": ["foo"] + }, + "tests": [ + { + "description": "present required property is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "non-present required property is invalid", + "data": {"bar": 1}, + "valid": false + } + ] + }, + { + "description": "required default validation", + "schema": { + "properties": { + "foo": {} + } + }, + "tests": [ + { + "description": "not required by default", + "data": {}, + "valid": true + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/type.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/type.json new file mode 100644 index 0000000000..db42a44d3f --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/type.json @@ -0,0 +1,330 @@ +[ + { + "description": "integer type matches integers", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "an integer is an integer", + "data": 1, + "valid": true + }, + { + "description": "a float is not an integer", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an integer", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an integer", + "data": {}, + "valid": false + }, + { + "description": "an array is not an integer", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an integer", + "data": true, + "valid": false + }, + { + "description": "null is not an integer", + "data": null, + "valid": false + } + ] + }, + { + "description": "number type matches numbers", + "schema": {"type": "number"}, + "tests": [ + { + "description": "an integer is a number", + "data": 1, + "valid": true + }, + { + "description": "a float is a number", + "data": 1.1, + "valid": true + }, + { + "description": "a string is not a number", + "data": "foo", + "valid": false + }, + { + "description": "an object is not a number", + "data": {}, + "valid": false + }, + { + "description": "an array is not a number", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a number", + "data": true, + "valid": false + }, + { + "description": "null is not a number", + "data": null, + "valid": false + } + ] + }, + { + "description": "string type matches strings", + "schema": {"type": "string"}, + "tests": [ + { + "description": "1 is not a string", + "data": 1, + "valid": false + }, + { + "description": "a float is not a string", + "data": 1.1, + "valid": false + }, + { + "description": "a string is a string", + "data": "foo", + "valid": true + }, + { + "description": "an object is not a string", + "data": {}, + "valid": false + }, + { + "description": "an array is not a string", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a string", + "data": true, + "valid": false + }, + { + "description": "null is not a string", + "data": null, + "valid": false + } + ] + }, + { + "description": "object type matches objects", + "schema": {"type": "object"}, + "tests": [ + { + "description": "an integer is not an object", + "data": 1, + "valid": false + }, + { + "description": "a float is not an object", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an object", + "data": "foo", + "valid": false + }, + { + "description": "an object is an object", + "data": {}, + "valid": true + }, + { + "description": "an array is not an object", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an object", + "data": true, + "valid": false + }, + { + "description": "null is not an object", + "data": null, + "valid": false + } + ] + }, + { + "description": "array type matches arrays", + "schema": {"type": "array"}, + "tests": [ + { + "description": "an integer is not an array", + "data": 1, + "valid": false + }, + { + "description": "a float is not an array", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an array", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an array", + "data": {}, + "valid": false + }, + { + "description": "an array is an array", + "data": [], + "valid": true + }, + { + "description": "a boolean is not an array", + "data": true, + "valid": false + }, + { + "description": "null is not an array", + "data": null, + "valid": false + } + ] + }, + { + "description": "boolean type matches booleans", + "schema": {"type": "boolean"}, + "tests": [ + { + "description": "an integer is not a boolean", + "data": 1, + "valid": false + }, + { + "description": "a float is not a boolean", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not a boolean", + "data": "foo", + "valid": false + }, + { + "description": "an object is not a boolean", + "data": {}, + "valid": false + }, + { + "description": "an array is not a boolean", + "data": [], + "valid": false + }, + { + "description": "a boolean is a boolean", + "data": true, + "valid": true + }, + { + "description": "null is not a boolean", + "data": null, + "valid": false + } + ] + }, + { + "description": "null type matches only the null object", + "schema": {"type": "null"}, + "tests": [ + { + "description": "an integer is not null", + "data": 1, + "valid": false + }, + { + "description": "a float is not null", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not null", + "data": "foo", + "valid": false + }, + { + "description": "an object is not null", + "data": {}, + "valid": false + }, + { + "description": "an array is not null", + "data": [], + "valid": false + }, + { + "description": "a boolean is not null", + "data": true, + "valid": false + }, + { + "description": "null is null", + "data": null, + "valid": true + } + ] + }, + { + "description": "multiple types can be specified in an array", + "schema": {"type": ["integer", "string"]}, + "tests": [ + { + "description": "an integer is valid", + "data": 1, + "valid": true + }, + { + "description": "a string is valid", + "data": "foo", + "valid": true + }, + { + "description": "a float is invalid", + "data": 1.1, + "valid": false + }, + { + "description": "an object is invalid", + "data": {}, + "valid": false + }, + { + "description": "an array is invalid", + "data": [], + "valid": false + }, + { + "description": "a boolean is invalid", + "data": true, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/uniqueItems.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/uniqueItems.json new file mode 100644 index 0000000000..c1f4ab99c9 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tests/draft4/uniqueItems.json @@ -0,0 +1,79 @@ +[ + { + "description": "uniqueItems validation", + "schema": {"uniqueItems": true}, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is invalid", + "data": [1, 1], + "valid": false + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": false + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is invalid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": false + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is invalid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": false + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is invalid", + "data": [["foo"], ["foo"]], + "valid": false + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are invalid", + "data": [{}, [1], true, null, {}, 1], + "valid": false + } + ] + } +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tox.ini b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tox.ini new file mode 100644 index 0000000000..5301222a84 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/jsonschema/tox.ini @@ -0,0 +1,8 @@ +[tox] +minversion = 1.6 +envlist = py27 +skipsdist = True + +[testenv] +deps = jsonschema +commands = {envpython} bin/jsonschema_suite check diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/booleans.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/booleans.json new file mode 100755 index 0000000000..2dcbb5fe87 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/booleans.json @@ -0,0 +1,102 @@ +[ + true, + true, + false, + false, + true, + true, + true, + false, + false, + true, + false, + false, + true, + false, + false, + false, + true, + false, + false, + true, + true, + false, + true, + true, + true, + false, + false, + false, + true, + false, + true, + false, + false, + true, + true, + true, + true, + true, + true, + false, + false, + true, + false, + false, + false, + true, + true, + false, + true, + true, + false, + true, + false, + true, + true, + true, + false, + false, + false, + true, + false, + false, + false, + true, + true, + false, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + true, + false, + false, + false, + true, + false, + false, + false, + true, + true, + true, + false, + false, + true, + false +] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/floats.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/floats.json new file mode 100755 index 0000000000..12b94a11dc --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/floats.json @@ -0,0 +1,102 @@ +[ + 135.747111636, + 123.377054008, + 140.527504552, + -72.299143906, + -23.851678949, + 73.586193519, + -158.299382442, + 177.477876032, + 32.268518982, + -139.560009969, + 115.203105183, + -106.025823607, + 167.224138231, + 103.378383732, + -97.498486285, + 18.184723416, + 69.137075711, + 33.849002681, + -120.185228215, + -20.841408615, + -172.659492727, + -2.691464061, + 22.426164066, + -98.416909437, + -31.603082708, + -85.072296561, + 108.620987395, + -43.127078238, + -126.473562057, + -158.595489097, + -57.890678254, + -13.254016573, + -85.024504709, + 171.663552644, + -146.495558248, + -10.606748276, + -118.786969354, + 153.352057804, + -45.215545083, + 37.038725288, + 106.344071897, + -64.607402031, + 85.148030911, + 28.897784566, + 39.51082061, + 20.450382102, + -113.174943618, + 71.60785784, + -168.202648062, + -157.338200017, + 10.879588527, + -114.261694831, + -5.622927072, + -173.330830616, + -29.47002003, + -39.829034201, + 50.031545162, + 82.815735508, + -119.188760828, + -48.455928081, + 163.964263034, + 46.30378861, + -26.248889762, + -47.354615322, + 155.388677633, + -166.710356904, + 42.987233558, + 144.275297374, + 37.394383186, + -122.550388725, + 177.469945914, + 101.104677413, + 109.429869885, + -104.919625624, + 147.522756541, + -81.294703727, + 122.744731363, + 81.803603684, + 26.321556167, + 147.045441354, + 147.256895816, + -174.211095908, + 52.518769316, + -78.58250334, + -173.356685435, + -107.728209264, + -69.982325771, + -113.776095893, + -35.785267074, + -105.748545976, + -30.206523864, + -76.185311723, + -126.400112781, + -26.864958639, + 56.840053629, + 93.781553535, + -116.002949803, + -46.617140948, + 176.846840093, + -144.24821335 +] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/guids.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/guids.json new file mode 100755 index 0000000000..9d7f5dbc8f --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/guids.json @@ -0,0 +1,102 @@ +[ + "d35bf0d4-8d8f-4e17-a5c3-ad9bfd675266", + "db402774-eeb6-463b-9986-c458c44d8b5a", + "2a2e4101-b5f2-40b8-8750-e03f01661e60", + "76787cfa-f4eb-4d62-aaad-e1d588d00ad5", + "fd73894b-b500-4a7c-888c-06b5bd9cec65", + "cce1862a-cf31-4ef2-9e23-f1d23b4e6163", + "00a98bb0-2b6e-4368-8512-71c21aa87db7", + "ab9a8d69-cec7-4550-bd35-3ed678e22782", + "f18b48e1-5114-4fbe-9652-579e8d66950e", + "4efe3baa-7ac5-4d6a-a839-6b9cfe825764", + "b4aec119-5b0a-434c-b388-109816c482a5", + "e0ef0cbb-127a-4a28-9831-5741b4295275", + "d50286a5-cb7b-4c9e-be99-f214439bae8c", + "a981094c-f1ac-42ed-a9fa-86404c7210ff", + "2a34ee57-5815-4829-b77b-eeebaa8fe340", + "a0530d44-48f8-4eff-b9ea-8810c4308351", + "c6f91509-83e1-4ea1-9680-e667fbfd56ee", + "cab11402-dcdd-4454-b190-6da124947395", + "283d159c-2b18-4856-b4c7-5059252eaa15", + "146157c6-72a8-4051-9991-cb6ea6743d81", + "aef6f269-7306-4bd2-83f7-6d5605b5dc9a", + "37fe6027-d638-4017-80a9-e7b0567b278e", + "5003d731-33fb-4159-af61-d76348a44079", + "e0e06979-5f80-4713-9fe0-8a4d60dc89f8", + "7e85bdc3-0345-4cb6-9398-ccab06e79976", + "f2ebf5af-6568-4ffe-a46d-403863fd4b66", + "e0b5bb1c-b4dd-4535-9a9e-3c73f1167d46", + "c852d20b-6bcb-4b12-bd57-308296c64c5a", + "7ac3ae82-1818-49cd-a8a4-5ac77dfafd46", + "138004a9-76e2-4ad7-bd42-e74dabdbb803", + "ab25b5be-96be-45b0-b765-947b40ec36a6", + "08404734-fd57-499e-a4cf-71e9ec782ede", + "8dfdeb16-248b-4a21-bf89-2e22b11a4101", + "a0e44ef0-3b09-41e8-ad5d-ed8e6a1a2a67", + "a7981e49-188d-414a-9779-b1ad91e599d1", + "329186c0-bf27-4208-baf7-c0a0a5a2d5b7", + "cb5f3381-d33e-4b30-b1a9-f482623cad33", + "15031262-ca73-4e3c-bd0a-fcf89bdf0caf", + "6d7333d1-2e8c-4d78-bfde-5be47e70eb13", + "acaa160c-670a-4e8f-ac45-49416e77d5f9", + "228f87eb-cde4-4106-808b-2dbf3c7b6d2e", + "2ff830a3-5445-4d8e-b161-bddd30666697", + "f488bedd-ff6e-4108-b9a7-07f6da62f476", + "2e12b846-0a34-478e-adf7-a438493803e6", + "6686b8ef-7446-4d86-bd8c-df24119e3bfe", + "e474a5c5-5793-4d41-b4ab-5423acc56ef1", + "ac046573-e718-44dc-a0dc-9037eeaba6a9", + "6b0e9099-cf53-4d5a-8a71-977528628fcf", + "d51a3f22-0ff9-4087-ba9b-fcee2a2d8ade", + "bdc01286-3511-4d22-bfb8-76d01203d366", + "ca44eb84-17ff-4f27-8f1e-1bd25f4e8725", + "4e9a8c2f-be0b-4913-92d2-c801b9a50d04", + "7685d231-dadd-4041-9165-898397438ab7", + "86f0bf26-d66a-44d8-99f5-d6768addae3b", + "2ca1167c-72ba-45a0-aa42-faf033db0d0b", + "199a1182-ea55-49ff-ba51-71c29cdd0aac", + "be6a4dd2-c821-4aa0-8b83-d64d6644b5b2", + "4c5f4781-7f80-4daa-9c20-76b183000514", + "513b31bd-54fb-4d12-a427-42a7c13ff8e1", + "8e211bcb-d76c-4012-83ad-74dd7d23b687", + "44d5807e-0501-4f66-8779-e244d4fdca0a", + "db8cd555-0563-4b7b-b00c-eada300a7065", + "cb14d0c9-46cc-4797-bd3a-752b05629f07", + "4f68b3ef-ac9b-47a0-b6d7-57f398a5c6a5", + "77221aae-1bcf-471c-be45-7f31f733f9d6", + "42a7cac8-9e80-4c45-8c71-511d863c98ea", + "f9018d22-b82c-468c-bdb5-8864d5964801", + "75f4e9b8-62a2-4f21-ad8a-e19eff0419bc", + "9b7385c8-8653-4184-951c-b0ac1b36b42e", + "571018aa-ffbf-4b42-a16d-07b57a7f5f0e", + "35de4a2f-6bf1-45aa-b820-2a27ea833e44", + "0b8edb20-3bb4-4cb4-b089-31957466dbab", + "97da4778-9a7b-4140-a545-968148c81fb7", + "969f326c-8f2a-47c5-b41c-d9c2f06c9b9d", + "ae211037-8b53-4b17-bfc8-c06fc7774409", + "12c5c3c4-0bd5-45d3-bc1d-d04a3c65d3e6", + "ec02024f-ce43-4dd3-8169-a59f7baee043", + "5b6afe77-ce48-47ca-90a0-25cd10ca5ffd", + "2e3a61d4-6b8f-4d2f-ba86-878b4012efd8", + "19a88a67-a5d3-4647-898f-1cde07bce040", + "6db6f420-b5c8-48b9-bbb2-8864fe6fed65", + "5a45dbde-7b53-4f6b-b864-e3b63be3708a", + "c878321b-8a02-4239-9981-15760c2e7d15", + "4e36687f-8bf6-4b12-b496-3a8e382d067e", + "a59a63cd-43c0-4c6e-b208-6dbca86f8176", + "303308c4-2e4a-45b5-8bf3-3e66e9ad05a1", + "8b58fdf1-43a6-4c98-9547-6361b50791af", + "a3563591-72ed-42b5-8e41-bac1d76d70cf", + "38db8c78-3739-4f6e-8313-de4138082114", + "86615bea-7e73-4daf-95da-ae6b9eee1bbb", + "35d38e3e-076e-40dd-9aa8-05be2603bd59", + "9f84c62d-b454-4ba3-8c19-a01878985cdc", + "6721bbae-d765-4a06-8289-6fe46a1bf943", + "0837796f-d0dd-4e50-9b7c-1983e6cc7c48", + "021eb7d7-e869-49b9-80c3-9dd16ce2d981", + "819c56f8-e040-475d-aad5-c6d5e98b20aa", + "3a61ef02-735e-4229-937d-b3777a3f4e1f", + "79dfab84-12e6-4ec8-bfc8-460ae71e4eca", + "a106fabf-e149-476c-8053-b62388b6eb57", + "9a3900a5-bfb4-4de0-baa5-253a8bd0b634" +] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/integers.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/integers.json new file mode 100755 index 0000000000..5dd05e097a --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/integers.json @@ -0,0 +1,102 @@ +[ + 8125686, + 8958709, + 5976222, + 1889524, + 7968493, + 1357486, + 118415, + 7081097, + 4635968, + 7555332, + 2270233, + 3428352, + 8699968, + 2087333, + 7861337, + 7554440, + 2017031, + 7981692, + 6060687, + 1877715, + 3297474, + 8373177, + 6158629, + 7853641, + 3004441, + 9650406, + 2695251, + 1180761, + 4988426, + 6043805, + 8063373, + 6103218, + 2848339, + 8188690, + 9235573, + 5949816, + 6116081, + 6471138, + 3354531, + 4787414, + 9660600, + 942529, + 7278535, + 7967399, + 554292, + 1436493, + 267319, + 2606657, + 7900601, + 4276634, + 7996757, + 8544466, + 7266469, + 3301373, + 4005350, + 6437652, + 7717672, + 7126292, + 8588394, + 2127902, + 7410190, + 1517806, + 4583602, + 3123440, + 7747613, + 5029464, + 9834390, + 3087227, + 4913822, + 7550487, + 4518144, + 5862588, + 1778599, + 9493290, + 5588455, + 3638706, + 7394293, + 4294719, + 3837830, + 6381878, + 7175866, + 8575492, + 1415229, + 1453733, + 6972404, + 9782571, + 4234063, + 7117418, + 7293130, + 8057071, + 9345285, + 7626648, + 3358911, + 4574537, + 9371826, + 7627107, + 6154093, + 5392367, + 5398105, + 6956377 +] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/mixed.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/mixed.json new file mode 100755 index 0000000000..43e9a1d7be --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/mixed.json @@ -0,0 +1,592 @@ +[ + { + "favoriteFruit": "banana", + "greeting": "Hello, Kim! You have 10 unread messages.", + "friends": [ + { + "name": "Higgins Rodriquez", + "id": 0 + }, + { + "name": "James Floyd", + "id": 1 + }, + { + "name": "Gay Stewart", + "id": 2 + } + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "tags": [ + "pariatur", + "ad", + "eiusmod", + "sit", + "et", + "velit", + "culpa" + ], + "longitude": -57.919246, + "latitude": -36.022812, + "registered": "Friday, March 21, 2014 9:13 PM", + "about": "Laborum nulla aliquip ullamco proident excepteur est officia ipsum. Eiusmod exercitation minim ex do labore reprehenderit aliqua minim qui excepteur reprehenderit cupidatat. Sint enim exercitation duis id consequat nisi enim magna. Commodo aliqua id ipsum sit magna enim. Veniam officia in labore fugiat veniam ea laboris ex veniam duis.\r\n", + "address": "323 Pulaski Street, Ronco, North Carolina, 7701", + "phone": "+1 (919) 438-2678", + "email": "kim.griffith@cipromox.biz", + "company": "CIPROMOX", + "name": { + "last": "Griffith", + "first": "Kim" + }, + "eyeColor": "green", + "age": 26, + "picture": "http://placehold.it/32x32", + "balance": "$1,283.55", + "isActive": false, + "guid": "10ab0392-c5e2-48a3-9473-aa725bad892d", + "index": 0, + "_id": "551b91198238a0bcf9a41133" + }, + { + "favoriteFruit": "banana", + "greeting": "Hello, Skinner! You have 9 unread messages.", + "friends": [ + { + "name": "Rhonda Justice", + "id": 0 + }, + { + "name": "Audra Castaneda", + "id": 1 + }, + { + "name": "Vicky Chavez", + "id": 2 + } + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "tags": [ + "dolore", + "enim", + "sit", + "non", + "exercitation", + "fugiat", + "adipisicing" + ], + "longitude": -60.291407, + "latitude": -84.619318, + "registered": "Friday, February 7, 2014 3:17 AM", + "about": "Consectetur eiusmod laboris dolore est ullamco nulla in velit quis esse Lorem. Amet aliqua sunt aute occaecat veniam officia in duis proident aliqua cupidatat mollit. Sint eu qui anim duis ut anim duis eu cillum. Cillum nostrud adipisicing tempor Lorem commodo sit in ad qui non et irure qui. Labore eu aliquip id duis eiusmod veniam.\r\n", + "address": "347 Autumn Avenue, Fidelis, Puerto Rico, 543", + "phone": "+1 (889) 457-2319", + "email": "skinner.maddox@moltonic.co.uk", + "company": "MOLTONIC", + "name": { + "last": "Maddox", + "first": "Skinner" + }, + "eyeColor": "green", + "age": 22, + "picture": "http://placehold.it/32x32", + "balance": "$3,553.10", + "isActive": false, + "guid": "cfbc2fb6-2641-4388-b06d-ec0212cfac1e", + "index": 1, + "_id": "551b91197e0abe92d6642700" + }, + { + "favoriteFruit": "strawberry", + "greeting": "Hello, Reynolds! You have 5 unread messages.", + "friends": [ + { + "name": "Brady Valdez", + "id": 0 + }, + { + "name": "Boyer Golden", + "id": 1 + }, + { + "name": "Gladys Knapp", + "id": 2 + } + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "tags": [ + "commodo", + "eiusmod", + "cupidatat", + "et", + "occaecat", + "proident", + "Lorem" + ], + "longitude": 140.866287, + "latitude": 1.401032, + "registered": "Monday, October 20, 2014 8:01 AM", + "about": "Deserunt elit consequat ea dolor pariatur aute consectetur et nulla ipsum ad. Laboris occaecat ipsum ad duis et esse ea ut voluptate. Ex magna consequat pariatur amet. Quis excepteur non mollit dolore cillum dolor ex esse veniam esse deserunt non occaecat veniam. Sit amet proident proident amet. Nisi est id ut ut adipisicing esse fugiat non dolor aute.\r\n", + "address": "872 Montague Terrace, Haena, Montana, 3106", + "phone": "+1 (974) 410-2655", + "email": "reynolds.sanford@combot.biz", + "company": "COMBOT", + "name": { + "last": "Sanford", + "first": "Reynolds" + }, + "eyeColor": "green", + "age": 21, + "picture": "http://placehold.it/32x32", + "balance": "$3,664.47", + "isActive": true, + "guid": "f9933a9c-c41a-412f-a18d-e727c569870b", + "index": 2, + "_id": "551b91197f170b65413a06e3" + }, + { + "favoriteFruit": "banana", + "greeting": "Hello, Neva! You have 7 unread messages.", + "friends": [ + { + "name": "Clara Cotton", + "id": 0 + }, + { + "name": "Ray Gates", + "id": 1 + }, + { + "name": "Jacobs Reese", + "id": 2 + } + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "tags": [ + "magna", + "labore", + "incididunt", + "velit", + "ea", + "et", + "eiusmod" + ], + "longitude": -133.058479, + "latitude": 87.803677, + "registered": "Friday, May 9, 2014 5:41 PM", + "about": "Do duis occaecat ut officia occaecat officia nostrud reprehenderit ex excepteur aute anim in reprehenderit. Cupidatat nulla eiusmod nulla non minim veniam aute nulla deserunt adipisicing consectetur veniam. Sit consequat ex laboris aliqua labore consectetur tempor proident consequat est. Fugiat quis esse culpa aliquip. Excepteur laborum aliquip sunt eu cupidatat magna eiusmod amet nisi labore aliquip. Ut consectetur esse aliquip exercitation nulla ex occaecat elit do ex eiusmod deserunt. Ex eu voluptate minim deserunt fugiat minim est occaecat ad Lorem nisi.\r\n", + "address": "480 Eagle Street, Fostoria, Oklahoma, 2614", + "phone": "+1 (983) 439-3000", + "email": "neva.barker@pushcart.us", + "company": "PUSHCART", + "name": { + "last": "Barker", + "first": "Neva" + }, + "eyeColor": "brown", + "age": 36, + "picture": "http://placehold.it/32x32", + "balance": "$3,182.24", + "isActive": true, + "guid": "52489849-78e1-4b27-8b86-e3e5ab2b7dc8", + "index": 3, + "_id": "551b9119a13061c083c878d5" + }, + { + "favoriteFruit": "banana", + "greeting": "Hello, Rodgers! You have 6 unread messages.", + "friends": [ + { + "name": "Marguerite Conway", + "id": 0 + }, + { + "name": "Margarita Cunningham", + "id": 1 + }, + { + "name": "Carmela Gallagher", + "id": 2 + } + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "tags": [ + "ipsum", + "magna", + "amet", + "elit", + "sit", + "occaecat", + "elit" + ], + "longitude": -125.436981, + "latitude": 19.868524, + "registered": "Tuesday, July 8, 2014 8:09 PM", + "about": "In cillum esse tempor do magna id ad excepteur ex nostrud mollit deserunt aliqua. Minim aliqua commodo commodo consectetur exercitation nulla nisi dolore aliqua in. Incididunt deserunt mollit nostrud excepteur. Ipsum fugiat anim deserunt Lorem aliquip nisi consequat eu minim in ex duis.\r\n", + "address": "989 Varanda Place, Duryea, Palau, 3972", + "phone": "+1 (968) 578-2974", + "email": "rodgers.conner@frenex.net", + "company": "FRENEX", + "name": { + "last": "Conner", + "first": "Rodgers" + }, + "eyeColor": "blue", + "age": 23, + "picture": "http://placehold.it/32x32", + "balance": "$1,665.17", + "isActive": true, + "guid": "ed3b2374-5afe-4fca-9325-8a7bbc9f81a0", + "index": 4, + "_id": "551b91197bcedb1b56a241ce" + }, + { + "favoriteFruit": "strawberry", + "greeting": "Hello, Mari! You have 10 unread messages.", + "friends": [ + { + "name": "Irwin Boyd", + "id": 0 + }, + { + "name": "Dejesus Flores", + "id": 1 + }, + { + "name": "Lane Mcmahon", + "id": 2 + } + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "tags": [ + "esse", + "aliquip", + "excepteur", + "dolor", + "ex", + "commodo", + "anim" + ], + "longitude": -17.038176, + "latitude": 17.154663, + "registered": "Sunday, April 6, 2014 4:46 AM", + "about": "Excepteur veniam occaecat sint nulla magna in in officia elit. Eiusmod qui dolor fugiat tempor in minim esse officia minim consequat. Lorem ullamco labore proident ipsum id pariatur fugiat consectetur anim cupidatat qui proident non ipsum.\r\n", + "address": "563 Hendrickson Street, Westwood, South Dakota, 4959", + "phone": "+1 (980) 434-3976", + "email": "mari.fleming@beadzza.org", + "company": "BEADZZA", + "name": { + "last": "Fleming", + "first": "Mari" + }, + "eyeColor": "blue", + "age": 21, + "picture": "http://placehold.it/32x32", + "balance": "$1,948.04", + "isActive": true, + "guid": "6bd02166-3b1f-4ed8-84c9-ed96cbf12abc", + "index": 5, + "_id": "551b9119b359ff6d24846f77" + }, + { + "favoriteFruit": "strawberry", + "greeting": "Hello, Maxine! You have 7 unread messages.", + "friends": [ + { + "name": "Sullivan Stark", + "id": 0 + }, + { + "name": "Underwood Mclaughlin", + "id": 1 + }, + { + "name": "Kristy Carlson", + "id": 2 + } + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "tags": [ + "commodo", + "ipsum", + "quis", + "non", + "est", + "mollit", + "exercitation" + ], + "longitude": -105.40635, + "latitude": 37.197993, + "registered": "Tuesday, January 20, 2015 12:30 AM", + "about": "Proident ullamco Lorem est consequat consectetur non eiusmod esse nostrud pariatur eiusmod enim exercitation eiusmod. Consequat duis elit elit minim ullamco et dolor eu minim do tempor esse consequat excepteur. Mollit dolor do voluptate nostrud quis anim cillum velit tempor eiusmod adipisicing tempor do culpa. Eu magna dolor sit amet nisi do laborum dolore nisi. Deserunt ipsum et deserunt non nisi.\r\n", + "address": "252 Boulevard Court, Brenton, Tennessee, 9444", + "phone": "+1 (950) 466-3377", + "email": "maxine.moreno@zentia.tv", + "company": "ZENTIA", + "name": { + "last": "Moreno", + "first": "Maxine" + }, + "eyeColor": "brown", + "age": 24, + "picture": "http://placehold.it/32x32", + "balance": "$1,200.24", + "isActive": false, + "guid": "ce307a37-ca1f-43f5-b637-dca2605712be", + "index": 6, + "_id": "551b91195a6164b2e35f6dc8" + }, + { + "favoriteFruit": "strawberry", + "greeting": "Hello, Helga! You have 5 unread messages.", + "friends": [ + { + "name": "Alicia Vance", + "id": 0 + }, + { + "name": "Vinson Phelps", + "id": 1 + }, + { + "name": "Francisca Kelley", + "id": 2 + } + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "tags": [ + "nostrud", + "eiusmod", + "dolore", + "officia", + "sint", + "non", + "qui" + ], + "longitude": -7.275151, + "latitude": 75.54202, + "registered": "Wednesday, October 1, 2014 6:35 PM", + "about": "Quis duis ullamco velit qui. Consectetur non adipisicing id magna anim. Deserunt est officia qui esse. Et do pariatur incididunt anim ad mollit non. Et eiusmod sunt fugiat elit mollit ad excepteur anim nisi laboris eiusmod aliquip aliquip.\r\n", + "address": "981 Bush Street, Beaulieu, Vermont, 3775", + "phone": "+1 (956) 506-3807", + "email": "helga.burch@synkgen.name", + "company": "SYNKGEN", + "name": { + "last": "Burch", + "first": "Helga" + }, + "eyeColor": "blue", + "age": 22, + "picture": "http://placehold.it/32x32", + "balance": "$3,827.89", + "isActive": false, + "guid": "ff5dfea0-1052-4ef2-8b66-4dc1aad0a4fb", + "index": 7, + "_id": "551b911946be8358ae40e90e" + }, + { + "favoriteFruit": "banana", + "greeting": "Hello, Shaw! You have 5 unread messages.", + "friends": [ + { + "name": "Christian Cardenas", + "id": 0 + }, + { + "name": "Cohen Pennington", + "id": 1 + }, + { + "name": "Mary Lindsay", + "id": 2 + } + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "tags": [ + "occaecat", + "ut", + "occaecat", + "magna", + "exercitation", + "incididunt", + "irure" + ], + "longitude": -89.102972, + "latitude": 89.489596, + "registered": "Thursday, August 21, 2014 5:00 PM", + "about": "Amet cupidatat quis velit aute Lorem consequat pariatur mollit deserunt et sint culpa excepteur duis. Enim proident duis qui ex tempor sunt nostrud occaecat. Officia sit veniam mollit eiusmod minim do aute eiusmod fugiat qui anim adipisicing in laboris. Do tempor reprehenderit sunt laborum esse irure dolor ad consectetur aute sit id ipsum. Commodo et voluptate anim consequat do. Minim laborum ad veniam ad minim incididunt excepteur excepteur aliqua.\r\n", + "address": "237 Pierrepont Street, Herbster, New York, 3490", + "phone": "+1 (976) 455-2880", + "email": "shaw.zamora@shadease.me", + "company": "SHADEASE", + "name": { + "last": "Zamora", + "first": "Shaw" + }, + "eyeColor": "blue", + "age": 38, + "picture": "http://placehold.it/32x32", + "balance": "$3,440.82", + "isActive": false, + "guid": "ac5fdb0e-e1fb-427e-881d-da461be0d1ca", + "index": 8, + "_id": "551b9119af0077bc28a2de25" + }, + { + "favoriteFruit": "apple", + "greeting": "Hello, Melissa! You have 5 unread messages.", + "friends": [ + { + "name": "Marion Villarreal", + "id": 0 + }, + { + "name": "Kate Rose", + "id": 1 + }, + { + "name": "Hines Simon", + "id": 2 + } + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "tags": [ + "amet", + "veniam", + "mollit", + "ad", + "cupidatat", + "deserunt", + "Lorem" + ], + "longitude": -52.735052, + "latitude": 16.258838, + "registered": "Wednesday, April 16, 2014 7:56 PM", + "about": "Aute ut culpa eiusmod tempor duis dolor tempor incididunt. Nisi non proident excepteur eiusmod incididunt nisi minim irure sit. In veniam commodo deserunt proident reprehenderit et consectetur ullamco quis nulla cupidatat.\r\n", + "address": "642 Halsey Street, Blandburg, Kansas, 6761", + "phone": "+1 (941) 539-3851", + "email": "melissa.vaughn@memora.io", + "company": "MEMORA", + "name": { + "last": "Vaughn", + "first": "Melissa" + }, + "eyeColor": "brown", + "age": 24, + "picture": "http://placehold.it/32x32", + "balance": "$2,399.44", + "isActive": true, + "guid": "1769f022-a7f1-4a69-bf4c-f5a5ebeab2d1", + "index": 9, + "_id": "551b9119b607c09c7ffc3b8a" + } +] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/nulls.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/nulls.json new file mode 100755 index 0000000000..7a636ec87c --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/nulls.json @@ -0,0 +1,102 @@ +[ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null +] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/paragraphs.json b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/paragraphs.json new file mode 100755 index 0000000000..8ab3e1c561 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/paragraphs.json @@ -0,0 +1,102 @@ +[ + "Commodo ullamco cupidatat nisi sit proident ex. Cillum pariatur occaecat in officia do commodo nisi cillum tempor minim. Ad dolor ut et aliquip fugiat eu officia cupidatat occaecat consectetur eiusmod veniam enim officia.\r\n", + "Adipisicing cillum laborum nisi irure. Cillum dolor proident duis nulla qui mollit dolore reprehenderit mollit. Irure nulla dolor ipsum irure nulla quis laboris do.\r\n", + "Est adipisicing consectetur incididunt in. Occaecat ea magna ex consequat irure sit laborum cillum officia magna sunt do exercitation aliquip. Laboris id aute in dolore reprehenderit voluptate non deserunt laborum.\r\n", + "Consectetur eu aute est est occaecat adipisicing sint enim dolor eu. Tempor amet id non mollit eu consectetur cillum duis. Eu labore velit nulla ipsum commodo consequat aliquip. Cupidatat commodo dolore mollit enim sit excepteur nisi duis laboris deserunt esse.\r\n", + "Incididunt ullamco est fugiat enim fugiat. Do sit mollit anim ad excepteur eu laboris exercitation officia labore nulla ut. Voluptate non voluptate cillum sit et voluptate anim duis velit consequat aliquip dolor. Elit et et esse laboris consectetur officia eiusmod aliquip nisi est. Qui labore dolore ad dolor.\r\n", + "Anim adipisicing est irure proident sit officia ullamco voluptate sunt consectetur duis mollit excepteur veniam. Nostrud ut duis aute exercitation officia et quis elit commodo elit tempor aute aliquip enim. Est officia non cillum consequat voluptate ipsum sit voluptate nulla id.\r\n", + "Ipsum enim consectetur aliquip nulla commodo ut ex aliqua elit duis do. Officia et sunt aliqua dolor minim voluptate veniam esse elit enim. Adipisicing reprehenderit duis ex magna non in fugiat sunt ipsum nostrud fugiat aliquip. Labore voluptate id officia voluptate eu. Magna do nostrud excepteur sunt aliqua adipisicing qui.\r\n", + "Est occaecat non non cupidatat laborum qui. Veniam sit est voluptate labore sit irure consectetur fugiat. Anim enim enim fugiat exercitation anim ad proident esse in aliqua. Laboris ut aute culpa ullamco.\r\n", + "Sit et aliquip cupidatat deserunt eiusmod sint aliquip occaecat nostrud aliqua elit commodo ut magna. Amet sit est deserunt id duis in officia pariatur cupidatat ex. Mollit duis est consequat nulla aute velit ipsum sit consectetur pariatur ut non ex ipsum. Tempor esse velit pariatur reprehenderit et nostrud commodo laborum mollit labore.\r\n", + "Aliquip irure quis esse aliquip. Ex non deserunt culpa aliqua ad anim occaecat ad. Lorem consectetur mollit eu consectetur est non nisi non ipsum. Qui veniam ullamco officia est ut excepteur. Nulla elit dolore cupidatat aliqua enim Lorem elit consequat eiusmod non aliqua eu in. Pariatur in culpa labore sint ipsum consectetur occaecat ad ex ipsum laboris aliquip officia. Non officia eiusmod nisi officia id id laboris deserunt sunt enim magna mollit sit.\r\n", + "Mollit velit laboris laborum nulla aliquip consequat Lorem non incididunt irure. Eu voluptate sint do consectetur tempor sit Lorem in. Laborum eiusmod nisi Lorem ipsum dolore do aute laborum occaecat aute sunt. Sit laborum in ea do ipsum officia irure cillum irure nisi laboris. Ad anim deserunt excepteur ea veniam eiusmod culpa velit veniam. Commodo incididunt ea Lorem eu enim esse nisi incididunt mollit.\r\n", + "Velit proident sunt aute dolore reprehenderit culpa. Pariatur reprehenderit commodo ad ea voluptate anim nulla ipsum eu irure fugiat aliqua et. Adipisicing incididunt anim excepteur voluptate minim qui culpa. Sunt veniam enim reprehenderit magna magna. Sit ad amet deserunt ut aute dolore ad minim.\r\n", + "Esse ullamco sunt mollit mollit. Eu enim dolore laboris cupidatat. Cupidatat adipisicing non aute exercitation fugiat. Non ut cillum labore fugiat aliquip ex duis quis consectetur ut nisi Lorem amet qui. Proident veniam amet qui reprehenderit duis qui. Nisi culpa sit occaecat ullamco occaecat laborum fugiat ut. Non duis deserunt culpa duis.\r\n", + "Id ipsum eiusmod laboris non est ipsum deserunt labore duis reprehenderit deserunt. Sint tempor fugiat eiusmod nostrud in ut laborum esse in nostrud sit deserunt nostrud reprehenderit. Cupidatat aliqua qui anim consequat eu quis consequat consequat elit ipsum pariatur. Cupidatat in dolore velit quis. Exercitation cillum ullamco ex consectetur commodo tempor incididunt exercitation labore ad dolore. Minim incididunt consequat adipisicing esse eu eu voluptate.\r\n", + "Anim sint eiusmod nisi anim do deserunt voluptate ut cillum eiusmod esse ex reprehenderit laborum. Dolore nulla excepteur duis excepteur. Magna nisi nostrud duis non commodo velit esse ipsum Lorem incididunt. Nulla enim consequat ad aliqua. Incididunt irure culpa nostrud ea aute ex sit non ad esse.\r\n", + "Ullamco nostrud cupidatat adipisicing anim fugiat mollit eu. Et ut eu in nulla consequat. Sunt do pariatur culpa non est.\r\n", + "Pariatur incididunt reprehenderit non qui excepteur cillum exercitation nisi occaecat ad. Lorem aliquip laborum commodo reprehenderit sint. Laboris qui ut veniam magna quis et et ullamco voluptate. Tempor reprehenderit deserunt consequat nisi. Esse duis sint in tempor. Amet aute cupidatat in sint et.\r\n", + "Est officia nisi dolore consequat irure et excepteur. Sit qui elit tempor magna qui cillum anim amet proident exercitation proident. Eu cupidatat laborum consectetur duis ullamco irure nulla. Adipisicing culpa non reprehenderit anim aute.\r\n", + "Eu est laborum culpa velit dolore non sunt. Tempor magna veniam ea sit non qui Lorem qui exercitation aliqua aliqua et excepteur eiusmod. Culpa aute anim proident culpa adipisicing duis tempor elit aliquip elit nulla laboris esse dolore. Sit adipisicing non dolor eiusmod occaecat cupidatat.\r\n", + "Culpa velit eu esse sunt. Laborum irure aliqua reprehenderit velit ipsum fugiat officia dolor ut aute officia deserunt. Ipsum sit quis fugiat nostrud aliqua cupidatat ex pariatur et. Cillum proident est irure nisi dolor aliqua deserunt esse occaecat velit dolor.\r\n", + "Exercitation nulla officia sit eiusmod cillum eu incididunt officia exercitation qui Lorem deserunt. Voluptate Lorem minim commodo laborum esse in duis excepteur do duis aliquip nisi voluptate consectetur. Amet tempor officia enim ex esse minim reprehenderit.\r\n", + "Laboris sint deserunt ad aute incididunt. Anim officia sunt elit qui laborum labore commodo irure non. Mollit adipisicing ullamco do aute nulla eu laborum et quis sint aute adipisicing amet. Aliqua officia irure nostrud duis ex.\r\n", + "Eiusmod ipsum aliqua reprehenderit esse est non aute id veniam eiusmod. Elit consequat ad sit tempor elit eu incididunt quis irure ad. Eu incididunt veniam consequat Lorem nostrud cillum officia ea consequat ad cillum. Non nisi irure cupidatat incididunt pariatur incididunt. Duis velit officia ad cillum qui. Aliquip consequat sint aute nisi cillum. Officia commodo nisi incididunt laborum nisi voluptate aliquip Lorem cupidatat anim consequat sit laboris.\r\n", + "Veniam cupidatat et incididunt mollit do ex voluptate veniam nostrud labore esse. Eiusmod irure sint fugiat esse. Aute irure consectetur ut mollit nulla sint esse. Lorem ut quis ex proident nostrud mollit nostrud ea duis duis in magna anim consectetur.\r\n", + "Irure culpa esse qui do dolor fugiat veniam ad. Elit commodo aute elit magna incididunt tempor pariatur velit irure pariatur cillum et ea ad. Ad consequat ea et ad minim ut sunt qui commodo voluptate. Laboris est aliquip anim reprehenderit eu officia et exercitation. Occaecat laboris cupidatat Lorem ullamco in nostrud commodo ipsum in quis esse ex.\r\n", + "Incididunt officia quis voluptate eiusmod esse nisi ipsum quis commodo. Eiusmod dolore tempor occaecat sit exercitation aliqua minim consequat minim mollit qui ad nisi. Aute quis irure adipisicing veniam nisi nisi velit deserunt incididunt anim nostrud.\r\n", + "Voluptate exercitation exercitation id minim excepteur excepteur mollit. Fugiat aute proident nulla ullamco ea. Nisi ea culpa duis dolore veniam anim tempor officia in dolore exercitation exercitation. Dolore quis cillum adipisicing sunt do nulla esse proident ad sint.\r\n", + "Laborum ut mollit sint commodo nulla laborum deserunt Lorem magna commodo mollit tempor deserunt ut. Qui aliquip commodo ea id. Consectetur dolor fugiat dolor excepteur eiusmod. Eu excepteur ex aute ex ex elit ex esse officia cillum exercitation. Duis ut labore ea nostrud excepteur. Reprehenderit labore aute sunt nisi quis Lorem officia. Ad aliquip cupidatat voluptate exercitation voluptate ad irure magna quis.\r\n", + "Tempor velit veniam sit labore elit minim do elit cillum eiusmod sunt excepteur nisi. Aliquip est deserunt excepteur duis fugiat incididunt veniam fugiat. Pariatur sit irure labore et minim non. Cillum quis aute anim sint laboris laboris ullamco exercitation nostrud. Nulla pariatur id laborum minim nisi est adipisicing irure.\r\n", + "Irure exercitation laboris nostrud in do consectetur ad. Magna aliqua Lorem culpa exercitation sint do culpa incididunt mollit eu exercitation. Elit tempor Lorem dolore enim deserunt. Anim et ullamco sint ullamco mollit cillum officia et. Proident incididunt laboris aliquip laborum sint veniam deserunt eu consequat deserunt voluptate laboris. Anim Lorem non laborum exercitation voluptate. Cupidatat reprehenderit culpa Lorem fugiat enim minim consectetur tempor quis ad reprehenderit laboris irure.\r\n", + "Deserunt elit mollit nostrud occaecat labore reprehenderit laboris ex. Esse reprehenderit adipisicing cillum minim in esse aliquip excepteur ex et nisi cillum quis. Cillum labore ut ex sunt. Occaecat proident et mollit magna consequat irure esse. Dolor do enim esse nisi ad.\r\n", + "Pariatur est anim cillum minim elit magna adipisicing quis tempor proident nisi laboris incididunt cupidatat. Nulla est adipisicing sit adipisicing id nostrud amet qui consequat eiusmod tempor voluptate ad. Adipisicing non magna sit occaecat magna mollit ad ex nulla velit ea pariatur. Irure labore ad ea exercitation ex cillum.\r\n", + "Lorem fugiat eu eu cillum nulla tempor sint. Lorem id officia nulla velit labore ut duis ad tempor non. Excepteur quis aute adipisicing nisi nisi consectetur aliquip enim Lorem id ullamco cillum sint voluptate. Qui aliquip incididunt tempor aliqua voluptate labore reprehenderit. Veniam eiusmod elit occaecat voluptate tempor culpa consectetur ea ut exercitation eiusmod exercitation qui.\r\n", + "Aliqua esse pariatur nulla veniam velit ea. Aliquip consectetur tempor ex magna sit aliquip exercitation veniam. Dolor ullamco minim commodo pariatur. Et amet reprehenderit dolore proident elit tempor eiusmod eu incididunt enim ullamco. Adipisicing id officia incididunt esse dolor sunt cupidatat do deserunt mollit do non. Magna ut officia fugiat adipisicing quis ea cillum laborum dolore ad nostrud magna minim est. Dolor voluptate officia proident enim ea deserunt eu voluptate dolore proident laborum officia ea.\r\n", + "Culpa aute consequat esse fugiat cupidatat minim voluptate voluptate eiusmod irure anim elit. Do eiusmod culpa laboris consequat incididunt minim nostrud eiusmod commodo velit ea ullamco proident. Culpa pariatur magna ut mollit nisi. Ea officia do magna deserunt minim nisi tempor ea deserunt veniam cillum exercitation esse.\r\n", + "Anim ullamco nostrud commodo Lorem. Do sunt laborum exercitation proident proident magna. Lorem officia laborum laborum dolor sunt duis commodo Lorem. Officia aute adipisicing ea cupidatat ea dolore. Aliquip adipisicing pariatur consectetur aliqua sit amet officia reprehenderit laborum culpa. Occaecat Lorem eu nisi do Lorem occaecat enim eiusmod laboris id quis. Ad mollit adipisicing sunt adipisicing esse.\r\n", + "Laborum quis sit adipisicing cupidatat. Veniam Lorem eiusmod esse esse sint nisi labore elit et. Deserunt aliqua mollit ut commodo aliqua non incididunt ipsum reprehenderit consectetur. Eiusmod nulla minim laboris Lorem ea Lorem aute tempor pariatur in sit. Incididunt culpa ut do irure amet irure cupidatat est anim anim culpa occaecat. Est velit consectetur eiusmod veniam reprehenderit officia sunt occaecat eiusmod ut sunt occaecat amet.\r\n", + "Elit minim aute fugiat nulla ex quis. Labore fugiat sint nostrud amet quis culpa excepteur in. Consectetur exercitation cupidatat laborum sit. Aute nisi eu aliqua est deserunt eiusmod commodo dolor id. Mollit laborum esse sint ipsum voluptate reprehenderit velit et. Veniam aliquip enim in veniam Lorem voluptate quis deserunt consequat qui commodo ut excepteur aute.\r\n", + "Dolore deserunt veniam aute nisi labore sunt et voluptate irure nisi anim ea. Magna nisi quis anim mollit nisi est dolor do ex aliquip elit aliquip ipsum minim. Dolore est officia nostrud eiusmod ex laborum ea amet est. Officia culpa non est et tempor consectetur exercitation tempor eiusmod enim. Ea tempor laboris qui amet ex nisi culpa dolore consectetur incididunt sunt sunt. Lorem aliquip incididunt magna do et ullamco ex elit aliqua eiusmod qui. Commodo amet dolor sint incididunt ex veniam non Lorem fugiat.\r\n", + "Officia culpa enim voluptate dolore commodo. Minim commodo aliqua minim ex sint excepteur cupidatat adipisicing eu irure. Anim magna deserunt anim Lorem non.\r\n", + "Cupidatat aliquip nulla excepteur sunt cupidatat cupidatat laborum cupidatat exercitation. Laboris minim ex cupidatat culpa elit. Amet enim reprehenderit aliqua laborum est tempor exercitation cupidatat ex dolore do. Do incididunt labore fugiat commodo consectetur nisi incididunt irure sit culpa sit. Elit aute occaecat qui excepteur velit proident cillum qui aliqua ex do ex. Dolore irure ex excepteur veniam id proident mollit Lorem.\r\n", + "Ad commodo cillum duis deserunt elit officia consectetur veniam eiusmod. Reprehenderit et veniam ad commodo reprehenderit magna elit laboris sunt non quis. Adipisicing dolor aute proident ea magna sunt et proident in consectetur.\r\n", + "Veniam exercitation esse esse veniam est nisi. Minim velit incididunt sint aute dolor anim. Fugiat cupidatat id ad nisi in voluptate dolor culpa eiusmod magna eiusmod amet id. Duis aliquip labore et ex amet amet aliquip laborum eiusmod ipsum. Quis qui ut duis duis. Minim in voluptate reprehenderit aliqua.\r\n", + "Elit ut pariatur dolor veniam ipsum consequat. Voluptate Lorem mollit et esse dolore mollit Lorem ad. Elit nostrud eu Lorem labore mollit minim cupidatat officia quis minim dolore incididunt. In cillum aute cillum ut.\r\n", + "Commodo laborum deserunt ut cupidatat pariatur ullamco in esse anim exercitation cillum duis. Consectetur incididunt sit esse Lorem in aute. Eiusmod mollit Lorem consequat minim reprehenderit laborum enim excepteur irure nisi elit. Laborum esse proident aute aute proident adipisicing laborum. Pariatur tempor duis incididunt qui velit pariatur ut officia ea mollit labore dolore. Cillum pariatur minim ullamco sunt incididunt culpa id ullamco exercitation consectetur. Ea exercitation consequat reprehenderit ut ullamco velit eu ad velit magna excepteur eiusmod.\r\n", + "Eu deserunt magna laboris laborum laborum in consequat dolore. Officia proident consectetur proident do occaecat minim pariatur officia ipsum sit non velit officia cillum. Laborum excepteur labore eu minim eiusmod. Sit anim dolore cillum ad do minim culpa sit est ad.\r\n", + "Cupidatat dolor nostrud Lorem sint consequat quis. Quis labore sint incididunt officia tempor. Fugiat nostrud in elit reprehenderit dolor. Nisi sit enim officia minim est adipisicing nulla aute labore nulla nostrud cupidatat est. Deserunt dolore qui irure Lorem esse voluptate velit qui nostrud.\r\n", + "Fugiat Lorem amet nulla nisi qui amet laboris enim cillum. Dolore occaecat exercitation id labore velit do commodo ut cupidatat laborum velit fugiat mollit. Ut et aliqua pariatur occaecat. Lorem occaecat dolore quis esse enim cupidatat exercitation ut tempor sit laboris fugiat adipisicing. Est tempor ex irure consectetur ipsum magna labore. Lorem non quis qui minim nisi magna amet aliquip ex cillum fugiat tempor.\r\n", + "Aliquip eiusmod laborum ipsum deserunt velit esse do magna excepteur consectetur exercitation sit. Minim ullamco reprehenderit commodo nostrud exercitation id irure ex qui ullamco sit esse laboris. Nulla cillum non minim qui cillum nisi aute proident. Dolor anim culpa elit quis excepteur aliqua eiusmod. Elit ea est excepteur consectetur sunt eiusmod enim id commodo irure amet et pariatur laboris. Voluptate magna ad magna dolore cillum cillum irure laboris ipsum officia id Lorem veniam.\r\n", + "Esse sunt elit est aliquip cupidatat commodo deserunt. Deserunt pariatur ipsum qui ad esse esse magna qui cillum laborum. Exercitation veniam pariatur elit amet enim.\r\n", + "Esse quis in id elit nulla occaecat incididunt. Et amet Lorem mollit in veniam do. Velit mollit Lorem consequat commodo Lorem aliquip cupidatat. Minim consequat nostrud nulla in nostrud.\r\n", + "Cillum nulla et eu est nostrud quis elit cupidatat dolor enim excepteur exercitation nisi voluptate. Nulla dolore non ex velit et qui tempor proident id deserunt nisi eu. Tempor ad Lorem ipsum reprehenderit in anim. Anim dolore ullamco enim deserunt quis ex id exercitation velit. Magna exercitation fugiat mollit pariatur ipsum ex consectetur nostrud. Id dolore officia nostrud excepteur laborum. Magna incididunt elit ipsum pariatur adipisicing enim duis est qui commodo velit aute.\r\n", + "Quis esse ex qui nisi dolor. Ullamco laborum dolor esse laboris eiusmod ea magna laboris ea esse ut. Dolore ipsum pariatur veniam sint mollit. Lorem ea proident fugiat ullamco ut nisi culpa eu exercitation exercitation aliquip veniam laborum consectetur.\r\n", + "Pariatur veniam laboris sit aliquip pariatur tempor aute sunt id et ut. Laboris excepteur eiusmod nisi qui quis elit enim ut cupidatat. Et et laborum in fugiat veniam consectetur ipsum laboris duis excepteur ullamco aliqua dolor Lorem. Aliqua ex amet sint anim cupidatat nisi ipsum anim et sunt deserunt. Occaecat culpa ut tempor cillum pariatur ex tempor.\r\n", + "Dolor deserunt eiusmod magna do officia voluptate excepteur est cupidatat. Veniam qui cupidatat amet anim est qui consectetur sit commodo commodo ea ad. Enim ad adipisicing qui nostrud. Non nulla esse ullamco nulla et ex.\r\n", + "Id ullamco ea consectetur est incididunt deserunt et esse. Elit nostrud voluptate eiusmod ut. Excepteur adipisicing qui cupidatat consequat labore id. Qui dolor aliqua do dolore do cupidatat labore ex consectetur ea sit cillum. Sint veniam eiusmod in consectetur consequat fugiat et mollit ut fugiat esse dolor adipisicing.\r\n", + "Ea magna proident labore duis pariatur. Esse cillum aliquip dolor duis fugiat ea ex officia ea irure. Sint elit nisi pariatur sunt nostrud exercitation ullamco culpa magna do.\r\n", + "Minim aliqua voluptate dolor consequat sint tempor deserunt amet magna excepteur. Irure do voluptate magna velit. Nostrud in reprehenderit magna officia nostrud. Cupidatat nulla irure laboris non fugiat ex ex est cupidatat excepteur officia aute velit duis. Sit voluptate id ea exercitation deserunt culpa voluptate nostrud est adipisicing incididunt. Amet proident laborum commodo magna ipsum quis.\r\n", + "Ipsum consectetur consectetur excepteur tempor eiusmod ea fugiat aute velit magna in officia sunt. Sit ut sunt dolore cupidatat dolor adipisicing. Veniam nisi adipisicing esse reprehenderit amet aliqua voluptate ex commodo occaecat est voluptate mollit sunt. Pariatur aliqua qui qui in dolor. Fugiat reprehenderit sit nostrud do sint esse. Tempor sit irure adipisicing ea pariatur duis est sit est incididunt laboris quis do. Et voluptate anim minim aliquip excepteur consequat nisi anim pariatur aliquip ut ipsum dolor magna.\r\n", + "Cillum sit labore excepteur magna id aliqua exercitation consequat laborum Lorem id pariatur nostrud. Lorem qui est labore sint cupidatat sint excepteur nulla in eu aliqua et. Adipisicing velit do enim occaecat laboris quis excepteur ipsum dolor occaecat Lorem dolore id exercitation.\r\n", + "Incididunt in laborum reprehenderit eiusmod irure ex. Elit duis consequat minim magna. Esse consectetur aliquip cillum excepteur excepteur fugiat. Sint tempor consequat minim reprehenderit consectetur adipisicing dolor id Lorem elit non. Occaecat esse quis mollit ea et sint aute fugiat qui tempor. Adipisicing tempor duis non dolore irure elit deserunt qui do.\r\n", + "Labore fugiat eiusmod sint laborum sit duis occaecat. Magna in laborum non cillum excepteur nostrud sit proident pariatur voluptate voluptate adipisicing exercitation occaecat. Ad non dolor aute ex sint do do minim exercitation veniam laborum irure magna ea. Magna do non quis sit consequat Lorem aliquip.\r\n", + "Velit anim do laborum laboris laborum Lorem. Sunt do Lorem amet ipsum est sint velit sit do voluptate mollit veniam enim. Commodo do deserunt in pariatur ut elit sint elit deserunt ea. Ad dolor anim consequat aliquip ut mollit nostrud tempor sunt mollit elit. Reprehenderit laboris labore excepteur occaecat veniam adipisicing cupidatat esse. Ad enim aliquip ea minim excepteur magna. Sint velit veniam pariatur qui dolor est adipisicing ex laboris.\r\n", + "Ea cupidatat ex nulla in sunt est sit dolor enim ad. Eu tempor consequat cupidatat consequat ex incididunt sint culpa. Est Lorem Lorem non cupidatat sunt ut aliqua non nostrud do ullamco. Reprehenderit ad ad nulla nostrud do nulla in. Ipsum adipisicing commodo mollit ipsum exercitation. Aliqua ea anim anim est elit. Ea incididunt consequat minim ad sunt eu cillum.\r\n", + "Tempor quis excepteur eiusmod cupidatat ipsum occaecat id et occaecat. Eiusmod magna aliquip excepteur id amet elit. Ullamco dolore amet anim dolor enim ea magna magna elit. Occaecat magna pariatur in deserunt consectetur officia aliquip ullamco ex aute anim. Minim laborum eu sit elit officia esse do irure pariatur tempor et reprehenderit ullamco labore.\r\n", + "Sit tempor eu minim dolore velit pariatur magna duis reprehenderit ea nulla in. Amet est do consectetur commodo do adipisicing adipisicing in amet. Cillum id ut commodo do pariatur duis aliqua nisi sint ad irure officia reprehenderit. Mollit labore id enim fugiat ullamco irure mollit cupidatat. Quis nisi amet labore eu dolor occaecat commodo aliqua laboris deserunt excepteur deserunt officia. Aliqua non ut sit ad. Laborum veniam ad velit minim dolore ea id magna dolor qui in.\r\n", + "Dolore nostrud ipsum aliqua pariatur id reprehenderit enim ad eiusmod qui. Deserunt anim commodo pariatur excepteur velit eu irure nulla ex labore ipsum aliqua minim aute. Id consequat amet tempor aliquip ex elit adipisicing est do. Eu enim Lorem consectetur minim id irure nulla culpa. Consectetur do consequat aute tempor anim. Qui ad non elit dolor est adipisicing nisi amet cillum sunt quis anim laboris incididunt. Incididunt proident adipisicing labore Lorem.\r\n", + "Et reprehenderit ea officia veniam. Aliquip ullamco consequat elit nisi magna mollit id elit. Amet amet sint velit labore ad nisi. Consectetur tempor id dolor aliqua esse deserunt amet. Qui laborum enim proident voluptate aute eu aute aute sit sit incididunt eu. Sunt ullamco nisi nostrud labore commodo non consectetur quis do duis minim irure. Tempor sint dolor sint aliquip dolore nostrud fugiat.\r\n", + "Aute ullamco quis nisi ut excepteur nostrud duis elit. Veniam ex ad incididunt veniam voluptate. Commodo dolore ullamco sit sint adipisicing proident amet aute duis deserunt.\r\n", + "Labore velit eu cillum nisi. Laboris do cupidatat et non duis cillum. Ullamco dolor tempor cupidatat voluptate laborum ullamco ea duis.\r\n", + "Deserunt consequat aliqua duis aliquip nostrud nostrud dolore nisi. Culpa do sint laborum consectetur ipsum quis laborum laborum pariatur eiusmod. Consectetur laboris ad ad ut quis. Ullamco laboris qui velit id laborum voluptate qui aute nostrud aliquip ea.\r\n", + "Ad cillum anim ex est consectetur mollit id in. Non enim aliquip consequat qui deserunt commodo cillum ad laborum fugiat. Dolor deserunt amet laborum tempor adipisicing voluptate dolor pariatur dolor cillum. Eu mollit ex sunt officia veniam qui est sunt proident. Non aliqua qui elit eu cupidatat ex enim ex proident. Lorem sit minim ullamco officia cupidatat duis minim. Exercitation laborum deserunt voluptate culpa tempor quis nulla id pariatur.\r\n", + "Nostrud quis consectetur ut aliqua excepteur elit consectetur occaecat. Occaecat voluptate Lorem pariatur consequat ullamco fugiat minim. Anim voluptate eu eu cillum tempor dolore aliquip aliqua. Fugiat incididunt ut tempor amet minim. Voluptate nostrud minim pariatur non excepteur ullamco.\r\n", + "Dolore nulla velit officia exercitation irure laboris incididunt anim in laborum in fugiat ut proident. Fugiat aute id consequat fugiat officia ut. Labore sint amet proident amet sint nisi laboris amet id ullamco culpa quis consequat proident. Magna do fugiat veniam dolore elit irure minim. Esse ullamco excepteur labore tempor labore fugiat dolore nisi cupidatat irure dolor pariatur. Magna excepteur laboris nisi eiusmod sit pariatur mollit.\r\n", + "In enim aliquip officia ea ad exercitation cillum culpa occaecat dolore Lorem. Irure cillum commodo adipisicing sunt pariatur ea duis fugiat exercitation laboris culpa ullamco aute. Ut voluptate exercitation qui dolor. Irure et duis elit consequat deserunt proident.\r\n", + "Officia ea Lorem sunt culpa id et tempor excepteur enim deserunt proident. Dolore aliquip dolor laboris cillum proident velit. Et culpa occaecat exercitation cupidatat irure sint adipisicing excepteur pariatur incididunt ad occaecat. Qui proident ipsum cillum minim. Quis ut culpa irure aliqua minim fugiat. In voluptate cupidatat fugiat est laborum dolor esse in pariatur voluptate.\r\n", + "Voluptate enim ipsum officia aute ea adipisicing nisi ut ex do aliquip amet. Reprehenderit enim voluptate tempor ex adipisicing culpa. Culpa occaecat voluptate dolor mollit ipsum exercitation labore et tempor sit ea consectetur aliqua. Elit elit sit minim ea ea commodo do tempor cupidatat irure dolore. Occaecat esse adipisicing anim eiusmod commodo fugiat mollit amet. Incididunt tempor tempor qui occaecat cupidatat in.\r\n", + "Ut qui anim velit enim aliquip do ut nulla labore. Mollit ut commodo ut eiusmod consectetur laboris aliqua qui voluptate culpa fugiat incididunt elit. Lorem ullamco esse elit elit. Labore amet incididunt ea nulla aliquip eiusmod. Sit nulla est voluptate officia ipsum aute aute cillum tempor deserunt. Laboris commodo eiusmod labore sunt aute excepteur ea consectetur reprehenderit veniam nisi. Culpa nisi sint sunt sint tempor laboris dolore cupidatat.\r\n", + "Duis cillum qui nisi duis amet velit ad cillum ut elit aute sint ad. Amet laboris pariatur excepteur ipsum Lorem aliqua veniam Lorem quis mollit cupidatat aliqua exercitation. Pariatur ex ullamco sit commodo cillum eiusmod ut proident elit cillum. Commodo ut ipsum excepteur occaecat sint elit consequat ex dolor adipisicing consectetur id ut ad. Velit sit eiusmod est esse tempor incididunt consectetur eiusmod duis commodo veniam.\r\n", + "Ut sunt qui officia anim laboris exercitation Lorem quis laborum do eiusmod officia. Enim consectetur occaecat fugiat cillum cillum. Dolore dolore nostrud in commodo fugiat mollit consequat occaecat non et et elit ullamco. Sit voluptate minim ut est culpa velit nulla fugiat reprehenderit eu aliquip adipisicing labore. Sit minim minim do dolor dolor. Lorem Lorem labore exercitation magna veniam eiusmod do.\r\n", + "Fugiat dolor adipisicing quis aliquip aute dolore. Qui proident anim elit veniam ex aliquip eiusmod ipsum sunt pariatur est. Non fugiat duis do est officia adipisicing.\r\n", + "Nulla deserunt do laboris cupidatat veniam do consectetur ipsum elit veniam in mollit eu. Ea in consequat cupidatat laboris sint fugiat irure. In commodo esse reprehenderit deserunt minim velit ullamco enim eu cupidatat tempor ex. Ullamco in non id culpa amet occaecat culpa nostrud id. Non occaecat culpa magna incididunt.\r\n", + "Enim laboris ex mollit reprehenderit eiusmod exercitation magna. Exercitation Lorem ex mollit non non culpa labore enim. Adipisicing labore dolore incididunt do amet aliquip excepteur ad et nostrud officia aute veniam voluptate. Fugiat enim eiusmod Lorem esse. Minim ullamco commodo consequat ex commodo aliqua eu nulla eu. Veniam non enim nulla ut Lorem nostrud minim sint duis.\r\n", + "Enim duis consectetur in ullamco cillum veniam nulla amet. Exercitation nisi sunt sunt duis in culpa nisi magna ex id ipsum laboris reprehenderit qui. Officia pariatur qui ex fugiat veniam et sunt sit nostrud. Veniam ullamco tempor fugiat minim Lorem proident velit in eiusmod elit. Enim minim excepteur aute aliquip ex magna commodo dolore qui et labore. Proident eu aliquip cillum dolor. Nostrud ipsum ut irure consequat fugiat nulla proident occaecat laborum.\r\n", + "Amet duis eiusmod sunt adipisicing esse ex nostrud consectetur voluptate cillum. Ipsum occaecat sit et anim velit irure ea incididunt cupidatat ullamco in nisi quis. Esse officia ipsum commodo qui quis qui do. Commodo aliquip amet aute sit sit ut cupidatat elit nostrud.\r\n", + "Laboris laboris sit mollit cillum nulla deserunt commodo culpa est commodo anim id anim sit. Officia id consectetur velit incididunt est dolor sunt ipsum magna aliqua consectetur. Eiusmod pariatur minim deserunt cupidatat veniam Lorem aliquip sunt proident eu Lorem sit dolor fugiat. Proident qui ut ex in incididunt nulla nulla dolor ex laboris ea ad.\r\n", + "Ex incididunt enim labore nulla cupidatat elit. Quis ut incididunt incididunt non irure commodo do mollit cillum anim excepteur. Qui consequat laborum dolore elit tempor aute ut nulla pariatur eu ullamco veniam. Nisi non velit labore in commodo excepteur culpa nulla tempor cillum. Ipsum qui sit sint reprehenderit ut labore incididunt dolor aliquip sunt. Reprehenderit occaecat tempor nisi laborum.\r\n", + "Lorem officia ullamco eu occaecat in magna eiusmod consectetur nisi aliqua mollit esse. Ullamco ex aute nostrud pariatur do enim cillum sint do fugiat nostrud culpa tempor. Do aliquip excepteur nostrud culpa eu pariatur eiusmod cillum excepteur do. Est sunt non quis cillum voluptate ex.\r\n", + "Deserunt consectetur tempor irure mollit qui tempor et. Labore enim eu irure laboris in. Nisi in tempor ex occaecat amet cupidatat laboris occaecat amet minim ut magna incididunt id. Consequat cillum laborum commodo mollit. Et magna culpa sunt dolore consequat laboris et sit. Deserunt qui voluptate excepteur dolor. Eu qui amet est proident.\r\n", + "Eu elit minim eiusmod occaecat eu nostrud dolor qui ut elit. Sunt dolore proident ea eu do eiusmod fugiat incididunt pariatur duis amet Lorem nisi ut. Adipisicing quis veniam cupidatat Lorem sint culpa sunt veniam sint. Excepteur eu exercitation est magna pariatur veniam dolore qui fugiat labore proident eiusmod cillum. Commodo reprehenderit elit proident duis sint magna.\r\n", + "Ut aliquip pariatur deserunt nostrud commodo ad proident est exercitation. Sit minim do ea enim sint officia nisi incididunt laborum. Ex amet duis commodo fugiat. Ut aute tempor deserunt irure occaecat aliquip voluptate cillum aute elit qui nostrud.\r\n", + "Irure et quis consectetur sit est do sunt aliquip eu. Cupidatat pariatur consequat dolore consectetur. Adipisicing magna velit mollit occaecat do id. Nisi pariatur cupidatat cillum incididunt excepteur consectetur excepteur do laborum deserunt irure pariatur cillum.\r\n", + "Adipisicing esse incididunt cillum est irure consequat irure ad aute voluptate. Incididunt do occaecat nostrud do ipsum pariatur Lorem qui laboris et pariatur. Est exercitation dolor culpa ad velit ut et.\r\n", + "Sit eiusmod id enim ad ex dolor pariatur do. Ullamco occaecat quis dolor minim non elit labore amet est. Commodo velit eu nulla eiusmod ullamco. Incididunt anim pariatur aute eiusmod veniam tempor enim officia elit id. Elit Lorem est commodo dolore nostrud. Labore et consectetur do exercitation veniam laboris incididunt aliqua proident dolore ea officia cupidatat. Velit laboris aliquip deserunt labore commodo.\r\n", + "Proident nostrud labore eu nostrud. Excepteur ut in velit labore ea proident labore ea sint cillum. Incididunt ipsum consectetur officia irure sit pariatur veniam id velit officia mollit. Adipisicing magna voluptate velit excepteur enim consectetur incididunt voluptate tempor occaecat fugiat velit excepteur labore. Do do incididunt qui nisi voluptate enim. Laboris aute sit voluptate cillum pariatur minim excepteur ullamco mollit deserunt.\r\n", + "Excepteur laborum adipisicing nisi elit fugiat tempor. Elit laboris qui enim labore duis. Proident tempor in consectetur proident excepteur do ex laboris sit.\r\n", + "Dolore do ea incididunt do duis dolore eu labore nisi cupidatat voluptate amet incididunt minim. Nulla pariatur mollit cupidatat adipisicing nulla et. Dolor aliquip in ex magna excepteur. Nulla consequat minim consequat ullamco dolor laboris ullamco eu reprehenderit duis nostrud pariatur.\r\n", + "Id nisi labore duis qui. Incididunt laboris tempor aute do sit. Occaecat excepteur est mollit ea in mollit ullamco est amet reprehenderit.\r\n", + "Aute labore ipsum velit non voluptate eiusmod et reprehenderit cupidatat occaecat. Lorem tempor tempor consectetur exercitation qui nostrud sunt cillum quis ut non dolore. Reprehenderit consequat reprehenderit laborum qui pariatur anim et officia est cupidatat enim velit velit.\r\n", + "Commodo ex et fugiat cupidatat non adipisicing commodo. Minim ad dolore fugiat mollit cupidatat aliqua sunt dolor sit. Labore esse labore velit aute enim. Nulla duis incididunt est aliquip consectetur elit qui incididunt minim minim labore amet sit cillum.\r\n" +] \ No newline at end of file diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/readme.txt b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/readme.txt new file mode 100644 index 0000000000..da1dae675e --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/bin/types/readme.txt @@ -0,0 +1 @@ +Test data obtained from https://github.com/xpol/lua-rapidjson/tree/master/performance diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/allocators.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/allocators.h new file mode 100644 index 0000000000..98affe03fb --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/allocators.h @@ -0,0 +1,271 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ALLOCATORS_H_ +#define RAPIDJSON_ALLOCATORS_H_ + +#include "rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Allocator + +/*! \class rapidjson::Allocator + \brief Concept for allocating, resizing and freeing memory block. + + Note that Malloc() and Realloc() are non-static but Free() is static. + + So if an allocator need to support Free(), it needs to put its pointer in + the header of memory block. + +\code +concept Allocator { + static const bool kNeedFree; //!< Whether this allocator needs to call Free(). + + // Allocate a memory block. + // \param size of the memory block in bytes. + // \returns pointer to the memory block. + void* Malloc(size_t size); + + // Resize a memory block. + // \param originalPtr The pointer to current memory block. Null pointer is permitted. + // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) + // \param newSize the new size in bytes. + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); + + // Free a memory block. + // \param pointer to the memory block. Null pointer is permitted. + static void Free(void *ptr); +}; +\endcode +*/ + +/////////////////////////////////////////////////////////////////////////////// +// CrtAllocator + +//! C-runtime library allocator. +/*! This class is just wrapper for standard C library memory routines. + \note implements Allocator concept +*/ +class CrtAllocator { +public: + static const bool kNeedFree = true; + void* Malloc(size_t size) { + if (size) // behavior of malloc(0) is implementation defined. + return std::malloc(size); + else + return NULL; // standardize to returning NULL. + } + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + (void)originalSize; + if (newSize == 0) { + std::free(originalPtr); + return NULL; + } + return std::realloc(originalPtr, newSize); + } + static void Free(void *ptr) { std::free(ptr); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// MemoryPoolAllocator + +//! Default memory allocator used by the parser and DOM. +/*! This allocator allocate memory blocks from pre-allocated memory chunks. + + It does not free memory blocks. And Realloc() only allocate new memory. + + The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. + + User may also supply a buffer as the first chunk. + + If the user-buffer is full then additional chunks are allocated by BaseAllocator. + + The user-buffer is not deallocated by this allocator. + + \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. + \note implements Allocator concept +*/ +template +class MemoryPoolAllocator { +public: + static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) + + //! Constructor with chunkSize. + /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) + { + } + + //! Constructor with user-supplied buffer. + /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. + + The user buffer will not be deallocated when this allocator is destructed. + + \param buffer User supplied buffer. + \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). + \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) + { + RAPIDJSON_ASSERT(buffer != 0); + RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); + chunkHead_ = reinterpret_cast(buffer); + chunkHead_->capacity = size - sizeof(ChunkHeader); + chunkHead_->size = 0; + chunkHead_->next = 0; + } + + //! Destructor. + /*! This deallocates all memory chunks, excluding the user-supplied buffer. + */ + ~MemoryPoolAllocator() { + Clear(); + RAPIDJSON_DELETE(ownBaseAllocator_); + } + + //! Deallocates all memory chunks, excluding the user-supplied buffer. + void Clear() { + while (chunkHead_ && chunkHead_ != userBuffer_) { + ChunkHeader* next = chunkHead_->next; + baseAllocator_->Free(chunkHead_); + chunkHead_ = next; + } + if (chunkHead_ && chunkHead_ == userBuffer_) + chunkHead_->size = 0; // Clear user buffer + } + + //! Computes the total capacity of allocated memory chunks. + /*! \return total capacity in bytes. + */ + size_t Capacity() const { + size_t capacity = 0; + for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) + capacity += c->capacity; + return capacity; + } + + //! Computes the memory blocks allocated. + /*! \return total used bytes. + */ + size_t Size() const { + size_t size = 0; + for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) + size += c->size; + return size; + } + + //! Allocates a memory block. (concept Allocator) + void* Malloc(size_t size) { + if (!size) + return NULL; + + size = RAPIDJSON_ALIGN(size); + if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity) + if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size)) + return NULL; + + void *buffer = reinterpret_cast(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size; + chunkHead_->size += size; + return buffer; + } + + //! Resizes a memory block (concept Allocator) + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + if (originalPtr == 0) + return Malloc(newSize); + + if (newSize == 0) + return NULL; + + originalSize = RAPIDJSON_ALIGN(originalSize); + newSize = RAPIDJSON_ALIGN(newSize); + + // Do not shrink if new size is smaller than original + if (originalSize >= newSize) + return originalPtr; + + // Simply expand it if it is the last allocation and there is sufficient space + if (originalPtr == reinterpret_cast(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) { + size_t increment = static_cast(newSize - originalSize); + if (chunkHead_->size + increment <= chunkHead_->capacity) { + chunkHead_->size += increment; + return originalPtr; + } + } + + // Realloc process: allocate and copy memory, do not free original buffer. + if (void* newBuffer = Malloc(newSize)) { + if (originalSize) + std::memcpy(newBuffer, originalPtr, originalSize); + return newBuffer; + } + else + return NULL; + } + + //! Frees a memory block (concept Allocator) + static void Free(void *ptr) { (void)ptr; } // Do nothing + +private: + //! Copy constructor is not permitted. + MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */; + //! Copy assignment operator is not permitted. + MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */; + + //! Creates a new chunk. + /*! \param capacity Capacity of the chunk in bytes. + \return true if success. + */ + bool AddChunk(size_t capacity) { + if (!baseAllocator_) + ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator()); + if (ChunkHeader* chunk = reinterpret_cast(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) { + chunk->capacity = capacity; + chunk->size = 0; + chunk->next = chunkHead_; + chunkHead_ = chunk; + return true; + } + else + return false; + } + + static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity. + + //! Chunk header for perpending to each chunk. + /*! Chunks are stored as a singly linked list. + */ + struct ChunkHeader { + size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). + size_t size; //!< Current size of allocated memory in bytes. + ChunkHeader *next; //!< Next chunk in the linked list. + }; + + ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation. + size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. + void *userBuffer_; //!< User supplied buffer. + BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. + BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object. +}; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/document.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/document.h new file mode 100644 index 0000000000..19f5a6a5ff --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/document.h @@ -0,0 +1,2575 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_DOCUMENT_H_ +#define RAPIDJSON_DOCUMENT_H_ + +/*! \file document.h */ + +#include "reader.h" +#include "internal/meta.h" +#include "internal/strfunc.h" +#include "memorystream.h" +#include "encodedstream.h" +#include // placement new +#include + +RAPIDJSON_DIAG_PUSH +#ifdef _MSC_VER +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_OFF(effc++) +#if __GNUC__ >= 6 +RAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions +#endif +#endif // __GNUC__ + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS +#include // std::iterator, std::random_access_iterator_tag +#endif + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#include // std::move +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +// Forward declaration. +template +class GenericValue; + +template +class GenericDocument; + +//! Name-value pair in a JSON object value. +/*! + This class was internal to GenericValue. It used to be a inner struct. + But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct. + https://code.google.com/p/rapidjson/issues/detail?id=64 +*/ +template +struct GenericMember { + GenericValue name; //!< name of member (must be a string) + GenericValue value; //!< value of member. +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericMemberIterator + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS + +//! (Constant) member iterator for a JSON object value +/*! + \tparam Const Is this a constant iterator? + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. + + This class implements a Random Access Iterator for GenericMember elements + of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements]. + + \note This iterator implementation is mainly intended to avoid implicit + conversions from iterator values to \c NULL, + e.g. from GenericValue::FindMember. + + \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a + pointer-based implementation, if your platform doesn't provide + the C++ header. + + \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator + */ +template +class GenericMemberIterator + : public std::iterator >::Type> { + + friend class GenericValue; + template friend class GenericMemberIterator; + + typedef GenericMember PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef std::iterator BaseType; + +public: + //! Iterator type itself + typedef GenericMemberIterator Iterator; + //! Constant iterator type + typedef GenericMemberIterator ConstIterator; + //! Non-constant iterator type + typedef GenericMemberIterator NonConstIterator; + + //! Pointer to (const) GenericMember + typedef typename BaseType::pointer Pointer; + //! Reference to (const) GenericMember + typedef typename BaseType::reference Reference; + //! Signed integer type (e.g. \c ptrdiff_t) + typedef typename BaseType::difference_type DifferenceType; + + //! Default constructor (singular value) + /*! Creates an iterator pointing to no element. + \note All operations, except for comparisons, are undefined on such values. + */ + GenericMemberIterator() : ptr_() {} + + //! Iterator conversions to more const + /*! + \param it (Non-const) iterator to copy from + + Allows the creation of an iterator from another GenericMemberIterator + that is "less const". Especially, creating a non-constant iterator + from a constant iterator are disabled: + \li const -> non-const (not ok) + \li const -> const (ok) + \li non-const -> const (ok) + \li non-const -> non-const (ok) + + \note If the \c Const template parameter is already \c false, this + constructor effectively defines a regular copy-constructor. + Otherwise, the copy constructor is implicitly defined. + */ + GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {} + Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; } + + //! @name stepping + //@{ + Iterator& operator++(){ ++ptr_; return *this; } + Iterator& operator--(){ --ptr_; return *this; } + Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; } + Iterator operator--(int){ Iterator old(*this); --ptr_; return old; } + //@} + + //! @name increment/decrement + //@{ + Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); } + Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); } + + Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; } + Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; } + //@} + + //! @name relations + //@{ + bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; } + bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; } + bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; } + bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; } + bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; } + bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; } + //@} + + //! @name dereference + //@{ + Reference operator*() const { return *ptr_; } + Pointer operator->() const { return ptr_; } + Reference operator[](DifferenceType n) const { return ptr_[n]; } + //@} + + //! Distance + DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; } + +private: + //! Internal constructor from plain pointer + explicit GenericMemberIterator(Pointer p) : ptr_(p) {} + + Pointer ptr_; //!< raw pointer +}; + +#else // RAPIDJSON_NOMEMBERITERATORCLASS + +// class-based member iterator implementation disabled, use plain pointers + +template +struct GenericMemberIterator; + +//! non-const GenericMemberIterator +template +struct GenericMemberIterator { + //! use plain pointer as iterator type + typedef GenericMember* Iterator; +}; +//! const GenericMemberIterator +template +struct GenericMemberIterator { + //! use plain const pointer as iterator type + typedef const GenericMember* Iterator; +}; + +#endif // RAPIDJSON_NOMEMBERITERATORCLASS + +/////////////////////////////////////////////////////////////////////////////// +// GenericStringRef + +//! Reference to a constant string (not taking a copy) +/*! + \tparam CharType character type of the string + + This helper class is used to automatically infer constant string + references for string literals, especially from \c const \b (!) + character arrays. + + The main use is for creating JSON string values without copying the + source string via an \ref Allocator. This requires that the referenced + string pointers have a sufficient lifetime, which exceeds the lifetime + of the associated GenericValue. + + \b Example + \code + Value v("foo"); // ok, no need to copy & calculate length + const char foo[] = "foo"; + v.SetString(foo); // ok + + const char* bar = foo; + // Value x(bar); // not ok, can't rely on bar's lifetime + Value x(StringRef(bar)); // lifetime explicitly guaranteed by user + Value y(StringRef(bar, 3)); // ok, explicitly pass length + \endcode + + \see StringRef, GenericValue::SetString +*/ +template +struct GenericStringRef { + typedef CharType Ch; //!< character type of the string + + //! Create string reference from \c const character array +#ifndef __clang__ // -Wdocumentation + /*! + This constructor implicitly creates a constant string reference from + a \c const character array. It has better performance than + \ref StringRef(const CharType*) by inferring the string \ref length + from the array length, and also supports strings containing null + characters. + + \tparam N length of the string, automatically inferred + + \param str Constant character array, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note Constant complexity. + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ +#endif + template + GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT + : s(str), length(N-1) {} + + //! Explicitly create string reference from \c const character pointer +#ifndef __clang__ // -Wdocumentation + /*! + This constructor can be used to \b explicitly create a reference to + a constant string pointer. + + \see StringRef(const CharType*) + + \param str Constant character pointer, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ +#endif + explicit GenericStringRef(const CharType* str) + : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != 0); } + + //! Create constant string reference from pointer and length +#ifndef __clang__ // -Wdocumentation + /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param len length of the string, excluding the trailing NULL terminator + + \post \ref s == str && \ref length == len + \note Constant complexity. + */ +#endif + GenericStringRef(const CharType* str, SizeType len) + : s(str), length(len) { RAPIDJSON_ASSERT(s != 0); } + + GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {} + + //! implicit conversion to plain CharType pointer + operator const Ch *() const { return s; } + + const Ch* const s; //!< plain CharType pointer + const SizeType length; //!< length of the string (excluding the trailing NULL terminator) + +private: + //! Disallow construction from non-const array + template + GenericStringRef(CharType (&str)[N]) /* = delete */; + //! Copy assignment operator not permitted - immutable type + GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */; +}; + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + \tparam CharType Character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + + \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember +*/ +template +inline GenericStringRef StringRef(const CharType* str) { + return GenericStringRef(str, internal::StrLen(str)); +} + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + This version has better performance with supplied length, and also + supports string containing null characters. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param length The length of source string. + \return GenericStringRef string reference object + \relatesalso GenericStringRef +*/ +template +inline GenericStringRef StringRef(const CharType* str, size_t length) { + return GenericStringRef(str, SizeType(length)); +} + +#if RAPIDJSON_HAS_STDSTRING +//! Mark a string object as constant string +/*! Mark a string object (e.g. \c std::string) as a "string literal". + This function can be used to avoid copying a string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. +*/ +template +inline GenericStringRef StringRef(const std::basic_string& str) { + return GenericStringRef(str.data(), SizeType(str.size())); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue type traits +namespace internal { + +template +struct IsGenericValueImpl : FalseType {}; + +// select candidates according to nested encoding and allocator types +template struct IsGenericValueImpl::Type, typename Void::Type> + : IsBaseOf, T>::Type {}; + +// helper to match arbitrary GenericValue instantiations, including derived classes +template struct IsGenericValue : IsGenericValueImpl::Type {}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// TypeHelper + +namespace internal { + +template +struct TypeHelper {}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsBool(); } + static bool Get(const ValueType& v) { return v.GetBool(); } + static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); } + static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsInt(); } + static int Get(const ValueType& v) { return v.GetInt(); } + static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); } + static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsUint(); } + static unsigned Get(const ValueType& v) { return v.GetUint(); } + static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); } + static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsInt64(); } + static int64_t Get(const ValueType& v) { return v.GetInt64(); } + static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); } + static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsUint64(); } + static uint64_t Get(const ValueType& v) { return v.GetUint64(); } + static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); } + static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsDouble(); } + static double Get(const ValueType& v) { return v.GetDouble(); } + static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); } + static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsFloat(); } + static float Get(const ValueType& v) { return v.GetFloat(); } + static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); } + static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); } +}; + +template +struct TypeHelper { + typedef const typename ValueType::Ch* StringType; + static bool Is(const ValueType& v) { return v.IsString(); } + static StringType Get(const ValueType& v) { return v.GetString(); } + static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); } + static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } +}; + +#if RAPIDJSON_HAS_STDSTRING +template +struct TypeHelper > { + typedef std::basic_string StringType; + static bool Is(const ValueType& v) { return v.IsString(); } + static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); } + static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } +}; +#endif + +template +struct TypeHelper { + typedef typename ValueType::Array ArrayType; + static bool Is(const ValueType& v) { return v.IsArray(); } + static ArrayType Get(ValueType& v) { return v.GetArray(); } + static ValueType& Set(ValueType& v, ArrayType data) { return v = data; } + static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; } +}; + +template +struct TypeHelper { + typedef typename ValueType::ConstArray ArrayType; + static bool Is(const ValueType& v) { return v.IsArray(); } + static ArrayType Get(const ValueType& v) { return v.GetArray(); } +}; + +template +struct TypeHelper { + typedef typename ValueType::Object ObjectType; + static bool Is(const ValueType& v) { return v.IsObject(); } + static ObjectType Get(ValueType& v) { return v.GetObject(); } + static ValueType& Set(ValueType& v, ObjectType data) { return v = data; } + static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { v = data; } +}; + +template +struct TypeHelper { + typedef typename ValueType::ConstObject ObjectType; + static bool Is(const ValueType& v) { return v.IsObject(); } + static ObjectType Get(const ValueType& v) { return v.GetObject(); } +}; + +} // namespace internal + +// Forward declarations +template class GenericArray; +template class GenericObject; + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue + +//! Represents a JSON value. Use Value for UTF8 encoding and default allocator. +/*! + A JSON value can be one of 7 types. This class is a variant type supporting + these types. + + Use the Value if UTF8 and default allocator + + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. +*/ +template > +class GenericValue { +public: + //! Name-value pair in an object. + typedef GenericMember Member; + typedef Encoding EncodingType; //!< Encoding type from template parameter. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericStringRef StringRefType; //!< Reference to a constant string + typedef typename GenericMemberIterator::Iterator MemberIterator; //!< Member iterator for iterating in object. + typedef typename GenericMemberIterator::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object. + typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. + typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. + typedef GenericValue ValueType; //!< Value type of itself. + typedef GenericArray Array; + typedef GenericArray ConstArray; + typedef GenericObject Object; + typedef GenericObject ConstObject; + + //!@name Constructors and destructor. + //@{ + + //! Default constructor creates a null value. + GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) { + rhs.data_.f.flags = kNullFlag; // give up contents + } +#endif + +private: + //! Copy constructor is not permitted. + GenericValue(const GenericValue& rhs); + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Moving from a GenericDocument is not permitted. + template + GenericValue(GenericDocument&& rhs); + + //! Move assignment from a GenericDocument is not permitted. + template + GenericValue& operator=(GenericDocument&& rhs); +#endif + +public: + + //! Constructor with JSON value type. + /*! This creates a Value of specified type with default content. + \param type Type of the value. + \note Default content for number is zero. + */ + explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() { + static const uint16_t defaultFlags[7] = { + kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag, + kNumberAnyFlag + }; + RAPIDJSON_ASSERT(type <= kNumberType); + data_.f.flags = defaultFlags[type]; + + // Use ShortString to store empty string. + if (type == kStringType) + data_.ss.SetLength(0); + } + + //! Explicit copy constructor (with allocator) + /*! Creates a copy of a Value by using the given Allocator + \tparam SourceAllocator allocator of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). + \see CopyFrom() + */ + template< typename SourceAllocator > + GenericValue(const GenericValue& rhs, Allocator & allocator); + + //! Constructor for boolean value. + /*! \param b Boolean value + \note This constructor is limited to \em real boolean values and rejects + implicitly converted types like arbitrary pointers. Use an explicit cast + to \c bool, if you want to construct a boolean JSON value in such cases. + */ +#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen + template + explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame))) RAPIDJSON_NOEXCEPT // See #472 +#else + explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT +#endif + : data_() { + // safe-guard against failing SFINAE + RAPIDJSON_STATIC_ASSERT((internal::IsSame::Value)); + data_.f.flags = b ? kTrueFlag : kFalseFlag; + } + + //! Constructor for int value. + explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() { + data_.n.i64 = i; + data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag; + } + + //! Constructor for unsigned value. + explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() { + data_.n.u64 = u; + data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag); + } + + //! Constructor for int64_t value. + explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() { + data_.n.i64 = i64; + data_.f.flags = kNumberInt64Flag; + if (i64 >= 0) { + data_.f.flags |= kNumberUint64Flag; + if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + data_.f.flags |= kUintFlag; + if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + else if (i64 >= static_cast(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + + //! Constructor for uint64_t value. + explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() { + data_.n.u64 = u64; + data_.f.flags = kNumberUint64Flag; + if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))) + data_.f.flags |= kInt64Flag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + data_.f.flags |= kUintFlag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + + //! Constructor for double value. + explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; } + + //! Constructor for constant string (i.e. do not make a copy of string) + GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); } + + //! Constructor for constant string (i.e. do not make a copy of string) + explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } + +#if RAPIDJSON_HAS_STDSTRING + //! Constructor for copy-string from a string object (i.e. do make a copy of string) + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue(const std::basic_string& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } +#endif + + //! Constructor for Array. + /*! + \param a An array obtained by \c GetArray(). + \note \c Array is always pass-by-value. + \note the source array is moved into this value and the sourec array becomes empty. + */ + GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) { + a.value_.data_ = Data(); + a.value_.data_.f.flags = kArrayFlag; + } + + //! Constructor for Object. + /*! + \param o An object obtained by \c GetObject(). + \note \c Object is always pass-by-value. + \note the source object is moved into this value and the sourec object becomes empty. + */ + GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) { + o.value_.data_ = Data(); + o.value_.data_.f.flags = kObjectFlag; + } + + //! Destructor. + /*! Need to destruct elements of array, members of object, or copy-string. + */ + ~GenericValue() { + if (Allocator::kNeedFree) { // Shortcut by Allocator's trait + switch(data_.f.flags) { + case kArrayFlag: + { + GenericValue* e = GetElementsPointer(); + for (GenericValue* v = e; v != e + data_.a.size; ++v) + v->~GenericValue(); + Allocator::Free(e); + } + break; + + case kObjectFlag: + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + Allocator::Free(GetMembersPointer()); + break; + + case kCopyStringFlag: + Allocator::Free(const_cast(GetStringPointer())); + break; + + default: + break; // Do nothing for other types. + } + } + } + + //@} + + //!@name Assignment operators + //@{ + + //! Assignment with move semantics. + /*! \param rhs Source of the assignment. It will become a null value after assignment. + */ + GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + RAPIDJSON_ASSERT(this != &rhs); + this->~GenericValue(); + RawAssign(rhs); + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT { + return *this = rhs.Move(); + } +#endif + + //! Assignment of constant string reference (no copy) + /*! \param str Constant string reference to be assigned + \note This overload is needed to avoid clashes with the generic primitive type assignment overload below. + \see GenericStringRef, operator=(T) + */ + GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT { + GenericValue s(str); + return *this = s; + } + + //! Assignment with primitive types. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value The value to be assigned. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref SetString(const Ch*, Allocator&) (for copying) or + \ref StringRef() (to explicitly mark the pointer as constant) instead. + All other pointer types would implicitly convert to \c bool, + use \ref SetBool() instead. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer), (GenericValue&)) + operator=(T value) { + GenericValue v(value); + return *this = v; + } + + //! Deep-copy assignment from Value + /*! Assigns a \b copy of the Value to the current Value object + \tparam SourceAllocator Allocator type of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator to use for copying + */ + template + GenericValue& CopyFrom(const GenericValue& rhs, Allocator& allocator) { + RAPIDJSON_ASSERT(static_cast(this) != static_cast(&rhs)); + this->~GenericValue(); + new (this) GenericValue(rhs, allocator); + return *this; + } + + //! Exchange the contents of this value with those of other. + /*! + \param other Another value. + \note Constant complexity. + */ + GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT { + GenericValue temp; + temp.RawAssign(*this); + RawAssign(other); + other.RawAssign(temp); + return *this; + } + + //! free-standing swap function helper + /*! + Helper function to enable support for common swap implementation pattern based on \c std::swap: + \code + void swap(MyClass& a, MyClass& b) { + using std::swap; + swap(a.value, b.value); + // ... + } + \endcode + \see Swap() + */ + friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } + + //! Prepare Value for move semantics + /*! \return *this */ + GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; } + //@} + + //!@name Equal-to and not-equal-to operators + //@{ + //! Equal-to operator + /*! + \note If an object contains duplicated named member, comparing equality with any object is always \c false. + \note Linear time complexity (number of all values in the subtree and total lengths of all strings). + */ + template + bool operator==(const GenericValue& rhs) const { + typedef GenericValue RhsType; + if (GetType() != rhs.GetType()) + return false; + + switch (GetType()) { + case kObjectType: // Warning: O(n^2) inner-loop + if (data_.o.size != rhs.data_.o.size) + return false; + for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) { + typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name); + if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value) + return false; + } + return true; + + case kArrayType: + if (data_.a.size != rhs.data_.a.size) + return false; + for (SizeType i = 0; i < data_.a.size; i++) + if ((*this)[i] != rhs[i]) + return false; + return true; + + case kStringType: + return StringEqual(rhs); + + case kNumberType: + if (IsDouble() || rhs.IsDouble()) { + double a = GetDouble(); // May convert from integer to double. + double b = rhs.GetDouble(); // Ditto + return a >= b && a <= b; // Prevent -Wfloat-equal + } + else + return data_.n.u64 == rhs.data_.n.u64; + + default: + return true; + } + } + + //! Equal-to operator with const C-string pointer + bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } + +#if RAPIDJSON_HAS_STDSTRING + //! Equal-to operator with string object + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + bool operator==(const std::basic_string& rhs) const { return *this == GenericValue(StringRef(rhs)); } +#endif + + //! Equal-to operator with primitive types + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false + */ + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr,internal::IsGenericValue >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); } + + //! Not-equal-to operator + /*! \return !(*this == rhs) + */ + template + bool operator!=(const GenericValue& rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with const C-string pointer + bool operator!=(const Ch* rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with arbitrary types + /*! \return !(*this == rhs) + */ + template RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); } + + //! Equal-to operator with arbitrary types (symmetric version) + /*! \return (rhs == lhs) + */ + template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; } + + //! Not-Equal-to operator with arbitrary types (symmetric version) + /*! \return !(rhs == lhs) + */ + template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); } + //@} + + //!@name Type + //@{ + + Type GetType() const { return static_cast(data_.f.flags & kTypeMask); } + bool IsNull() const { return data_.f.flags == kNullFlag; } + bool IsFalse() const { return data_.f.flags == kFalseFlag; } + bool IsTrue() const { return data_.f.flags == kTrueFlag; } + bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; } + bool IsObject() const { return data_.f.flags == kObjectFlag; } + bool IsArray() const { return data_.f.flags == kArrayFlag; } + bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; } + bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; } + bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; } + bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; } + bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; } + bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; } + bool IsString() const { return (data_.f.flags & kStringFlag) != 0; } + + // Checks whether a number can be losslessly converted to a double. + bool IsLosslessDouble() const { + if (!IsNumber()) return false; + if (IsUint64()) { + uint64_t u = GetUint64(); + volatile double d = static_cast(u); + return (d >= 0.0) + && (d < static_cast(std::numeric_limits::max())) + && (u == static_cast(d)); + } + if (IsInt64()) { + int64_t i = GetInt64(); + volatile double d = static_cast(i); + return (d >= static_cast(std::numeric_limits::min())) + && (d < static_cast(std::numeric_limits::max())) + && (i == static_cast(d)); + } + return true; // double, int, uint are always lossless + } + + // Checks whether a number is a float (possible lossy). + bool IsFloat() const { + if ((data_.f.flags & kDoubleFlag) == 0) + return false; + double d = GetDouble(); + return d >= -3.4028234e38 && d <= 3.4028234e38; + } + // Checks whether a number can be losslessly converted to a float. + bool IsLosslessFloat() const { + if (!IsNumber()) return false; + double a = GetDouble(); + if (a < static_cast(-std::numeric_limits::max()) + || a > static_cast(std::numeric_limits::max())) + return false; + double b = static_cast(static_cast(a)); + return a >= b && a <= b; // Prevent -Wfloat-equal + } + + //@} + + //!@name Null + //@{ + + GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } + + //@} + + //!@name Bool + //@{ + + bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; } + //!< Set boolean value + /*! \post IsBool() == true */ + GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } + + //@} + + //!@name Object + //@{ + + //! Set this value as an empty object. + /*! \post IsObject() == true */ + GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } + + //! Get the number of members in the object. + SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; } + + //! Check whether the object is empty. + bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } + + //! Get a value from an object associated with the name. + /*! \pre IsObject() == true + \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType)) + \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. + Since 0.2, if the name is not correct, it will assert. + If user is unsure whether a member exists, user should use HasMember() first. + A better approach is to use FindMember(). + \note Linear time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >),(GenericValue&)) operator[](T* name) { + GenericValue n(StringRef(name)); + return (*this)[n]; + } + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast(*this)[name]; } + + //! Get a value from an object associated with the name. + /*! \pre IsObject() == true + \tparam SourceAllocator Allocator of the \c name value + + \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen(). + And it can also handle strings with embedded null characters. + + \note Linear time complexity. + */ + template + GenericValue& operator[](const GenericValue& name) { + MemberIterator member = FindMember(name); + if (member != MemberEnd()) + return member->value; + else { + RAPIDJSON_ASSERT(false); // see above note + + // This will generate -Wexit-time-destructors in clang + // static GenericValue NullValue; + // return NullValue; + + // Use static buffer and placement-new to prevent destruction + static char buffer[sizeof(GenericValue)]; + return *new (buffer) GenericValue(); + } + } + template + const GenericValue& operator[](const GenericValue& name) const { return const_cast(*this)[name]; } + +#if RAPIDJSON_HAS_STDSTRING + //! Get a value from an object associated with name (string object). + GenericValue& operator[](const std::basic_string& name) { return (*this)[GenericValue(StringRef(name))]; } + const GenericValue& operator[](const std::basic_string& name) const { return (*this)[GenericValue(StringRef(name))]; } +#endif + + //! Const member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); } + //! Const \em past-the-end member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); } + //! Member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); } + //! \em Past-the-end member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); } + + //! Check whether a member exists in the object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); } + +#if RAPIDJSON_HAS_STDSTRING + //! Check whether a member exists in the object with string object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const std::basic_string& name) const { return FindMember(name) != MemberEnd(); } +#endif + + //! Check whether a member exists in the object with GenericValue name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + template + bool HasMember(const GenericValue& name) const { return FindMember(name) != MemberEnd(); } + + //! Find member by name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + MemberIterator FindMember(const Ch* name) { + GenericValue n(StringRef(name)); + return FindMember(n); + } + + ConstMemberIterator FindMember(const Ch* name) const { return const_cast(*this).FindMember(name); } + + //! Find member by name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + template + MemberIterator FindMember(const GenericValue& name) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + MemberIterator member = MemberBegin(); + for ( ; member != MemberEnd(); ++member) + if (name.StringEqual(member->name)) + break; + return member; + } + template ConstMemberIterator FindMember(const GenericValue& name) const { return const_cast(*this).FindMember(name); } + +#if RAPIDJSON_HAS_STDSTRING + //! Find member by string object name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + */ + MemberIterator FindMember(const std::basic_string& name) { return FindMember(GenericValue(StringRef(name))); } + ConstMemberIterator FindMember(const std::basic_string& name) const { return FindMember(GenericValue(StringRef(name))); } +#endif + + //! Add a member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c name and \c value will be transferred to this object on success. + \pre IsObject() && name.IsString() + \post name.IsNull() && value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + + ObjectData& o = data_.o; + if (o.size >= o.capacity) { + if (o.capacity == 0) { + o.capacity = kDefaultObjectCapacity; + SetMembersPointer(reinterpret_cast(allocator.Malloc(o.capacity * sizeof(Member)))); + } + else { + SizeType oldCapacity = o.capacity; + o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5 + SetMembersPointer(reinterpret_cast(allocator.Realloc(GetMembersPointer(), oldCapacity * sizeof(Member), o.capacity * sizeof(Member)))); + } + } + Member* members = GetMembersPointer(); + members[o.size].name.RawAssign(name); + members[o.size].value.RawAssign(value); + o.size++; + return *this; + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Add a string object as member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, std::basic_string& value, Allocator& allocator) { + GenericValue v(value, allocator); + return AddMember(name, v, allocator); + } +#endif + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A string value as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + AddMember(GenericValue& name, T value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + + //! Add a member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this object on success. + \pre IsObject() + \post value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A constant string reference as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + AddMember(StringRefType name, T value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Remove all members in the object. + /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void RemoveAllMembers() { + RAPIDJSON_ASSERT(IsObject()); + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + data_.o.size = 0; + } + + //! Remove a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note This function may reorder the object members. Use \ref + EraseMember(ConstMemberIterator) if you need to preserve the + relative order of the remaining members. + \note Linear time complexity. + */ + bool RemoveMember(const Ch* name) { + GenericValue n(StringRef(name)); + return RemoveMember(n); + } + +#if RAPIDJSON_HAS_STDSTRING + bool RemoveMember(const std::basic_string& name) { return RemoveMember(GenericValue(StringRef(name))); } +#endif + + template + bool RemoveMember(const GenericValue& name) { + MemberIterator m = FindMember(name); + if (m != MemberEnd()) { + RemoveMember(m); + return true; + } + else + return false; + } + + //! Remove a member in object by iterator. + /*! \param m member iterator (obtained by FindMember() or MemberBegin()). + \return the new iterator after removal. + \note This function may reorder the object members. Use \ref + EraseMember(ConstMemberIterator) if you need to preserve the + relative order of the remaining members. + \note Constant time complexity. + */ + MemberIterator RemoveMember(MemberIterator m) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(GetMembersPointer() != 0); + RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd()); + + MemberIterator last(GetMembersPointer() + (data_.o.size - 1)); + if (data_.o.size > 1 && m != last) + *m = *last; // Move the last one to this place + else + m->~Member(); // Only one left, just destroy + --data_.o.size; + return m; + } + + //! Remove a member from an object by iterator. + /*! \param pos iterator to the member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd() + \return Iterator following the removed element. + If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned. + \note This function preserves the relative order of the remaining object + members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator). + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator pos) { + return EraseMember(pos, pos +1); + } + + //! Remove members in the range [first, last) from an object. + /*! \param first iterator to the first member to remove + \param last iterator following the last member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd() + \return Iterator following the last removed element. + \note This function preserves the relative order of the remaining object + members. + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(GetMembersPointer() != 0); + RAPIDJSON_ASSERT(first >= MemberBegin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= MemberEnd()); + + MemberIterator pos = MemberBegin() + (first - MemberBegin()); + for (MemberIterator itr = pos; itr != last; ++itr) + itr->~Member(); + std::memmove(&*pos, &*last, static_cast(MemberEnd() - last) * sizeof(Member)); + data_.o.size -= static_cast(last - first); + return pos; + } + + //! Erase a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note Linear time complexity. + */ + bool EraseMember(const Ch* name) { + GenericValue n(StringRef(name)); + return EraseMember(n); + } + +#if RAPIDJSON_HAS_STDSTRING + bool EraseMember(const std::basic_string& name) { return EraseMember(GenericValue(StringRef(name))); } +#endif + + template + bool EraseMember(const GenericValue& name) { + MemberIterator m = FindMember(name); + if (m != MemberEnd()) { + EraseMember(m); + return true; + } + else + return false; + } + + Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); } + ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); } + + //@} + + //!@name Array + //@{ + + //! Set this value as an empty array. + /*! \post IsArray == true */ + GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } + + //! Get the number of elements in array. + SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } + + //! Get the capacity of array. + SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } + + //! Check whether the array is empty. + bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } + + //! Remove all elements in the array. + /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void Clear() { + RAPIDJSON_ASSERT(IsArray()); + GenericValue* e = GetElementsPointer(); + for (GenericValue* v = e; v != e + data_.a.size; ++v) + v->~GenericValue(); + data_.a.size = 0; + } + + //! Get an element from array by index. + /*! \pre IsArray() == true + \param index Zero-based index of element. + \see operator[](T*) + */ + GenericValue& operator[](SizeType index) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(index < data_.a.size); + return GetElementsPointer()[index]; + } + const GenericValue& operator[](SizeType index) const { return const_cast(*this)[index]; } + + //! Element iterator + /*! \pre IsArray() == true */ + ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); } + //! \em Past-the-end element iterator + /*! \pre IsArray() == true */ + ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; } + //! Constant element iterator + /*! \pre IsArray() == true */ + ConstValueIterator Begin() const { return const_cast(*this).Begin(); } + //! Constant \em past-the-end element iterator + /*! \pre IsArray() == true */ + ConstValueIterator End() const { return const_cast(*this).End(); } + + //! Request the array to have enough capacity to store elements. + /*! \param newCapacity The capacity that the array at least need to have. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note Linear time complexity. + */ + GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (newCapacity > data_.a.capacity) { + SetElementsPointer(reinterpret_cast(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)))); + data_.a.capacity = newCapacity; + } + return *this; + } + + //! Append a GenericValue at the end of the array. + /*! \param value Value to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \post value.IsNull() == true + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this array on success. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + */ + GenericValue& PushBack(GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (data_.a.size >= data_.a.capacity) + Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator); + GetElementsPointer()[data_.a.size++].RawAssign(value); + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& PushBack(GenericValue&& value, Allocator& allocator) { + return PushBack(value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + //! Append a constant string reference at the end of the array. + /*! \param value Constant string reference to be appended. + \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + \see GenericStringRef + */ + GenericValue& PushBack(StringRefType value, Allocator& allocator) { + return (*this).template PushBack(value, allocator); + } + + //! Append a primitive value at the end of the array. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value Value of primitive type T to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref PushBack(GenericValue&, Allocator&) or \ref + PushBack(StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + PushBack(T value, Allocator& allocator) { + GenericValue v(value); + return PushBack(v, allocator); + } + + //! Remove the last element in the array. + /*! + \note Constant time complexity. + */ + GenericValue& PopBack() { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(!Empty()); + GetElementsPointer()[--data_.a.size].~GenericValue(); + return *this; + } + + //! Remove an element of array by iterator. + /*! + \param pos iterator to the element to remove + \pre IsArray() == true && \ref Begin() <= \c pos < \ref End() + \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator pos) { + return Erase(pos, pos + 1); + } + + //! Remove elements in the range [first, last) of the array. + /*! + \param first iterator to the first element to remove + \param last iterator following the last element to remove + \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End() + \return Iterator following the last removed element. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(data_.a.size > 0); + RAPIDJSON_ASSERT(GetElementsPointer() != 0); + RAPIDJSON_ASSERT(first >= Begin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= End()); + ValueIterator pos = Begin() + (first - Begin()); + for (ValueIterator itr = pos; itr != last; ++itr) + itr->~GenericValue(); + std::memmove(pos, last, static_cast(End() - last) * sizeof(GenericValue)); + data_.a.size -= static_cast(last - first); + return pos; + } + + Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); } + ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); } + + //@} + + //!@name Number + //@{ + + int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; } + unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; } + int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; } + uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; } + + //! Get the value as double type. + /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless. + */ + double GetDouble() const { + RAPIDJSON_ASSERT(IsNumber()); + if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. + if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double + if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double + if ((data_.f.flags & kInt64Flag) != 0) return static_cast(data_.n.i64); // int64_t -> double (may lose precision) + RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast(data_.n.u64); // uint64_t -> double (may lose precision) + } + + //! Get the value as float type. + /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the converison is lossless. + */ + float GetFloat() const { + return static_cast(GetDouble()); + } + + GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } + GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } + GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } + GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } + GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } + GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(f); return *this; } + + //@} + + //!@name String + //@{ + + const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); } + + //! Get the length of string. + /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). + */ + SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); } + + //! Set this value as a string without copying source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string pointer. + \param length The length of source string, excluding the trailing null terminator. + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == length + \see SetString(StringRefType) + */ + GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); } + + //! Set this value as a string without copying source string. + /*! \param s source string reference + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == s.length + */ + GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; } + + //! Set this value as a string by copying from source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string. + \param length The length of source string, excluding the trailing null terminator. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; } + + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); } + +#if RAPIDJSON_HAS_STDSTRING + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size() + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue& SetString(const std::basic_string& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); } +#endif + + //@} + + //!@name Array + //@{ + + //! Templated version for checking whether this value is type T. + /*! + \tparam T Either \c bool, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c float, \c const \c char*, \c std::basic_string + */ + template + bool Is() const { return internal::TypeHelper::Is(*this); } + + template + T Get() const { return internal::TypeHelper::Get(*this); } + + template + T Get() { return internal::TypeHelper::Get(*this); } + + template + ValueType& Set(const T& data) { return internal::TypeHelper::Set(*this, data); } + + template + ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper::Set(*this, data, allocator); } + + //@} + + //! Generate events of this value to a Handler. + /*! This function adopts the GoF visitor pattern. + Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. + It can also be used to deep clone this value via GenericDocument, which is also a Handler. + \tparam Handler type of handler. + \param handler An object implementing concept Handler. + */ + template + bool Accept(Handler& handler) const { + switch(GetType()) { + case kNullType: return handler.Null(); + case kFalseType: return handler.Bool(false); + case kTrueType: return handler.Bool(true); + + case kObjectType: + if (RAPIDJSON_UNLIKELY(!handler.StartObject())) + return false; + for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { + RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator. + if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0))) + return false; + if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler))) + return false; + } + return handler.EndObject(data_.o.size); + + case kArrayType: + if (RAPIDJSON_UNLIKELY(!handler.StartArray())) + return false; + for (const GenericValue* v = Begin(); v != End(); ++v) + if (RAPIDJSON_UNLIKELY(!v->Accept(handler))) + return false; + return handler.EndArray(data_.a.size); + + case kStringType: + return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0); + + default: + RAPIDJSON_ASSERT(GetType() == kNumberType); + if (IsDouble()) return handler.Double(data_.n.d); + else if (IsInt()) return handler.Int(data_.n.i.i); + else if (IsUint()) return handler.Uint(data_.n.u.u); + else if (IsInt64()) return handler.Int64(data_.n.i64); + else return handler.Uint64(data_.n.u64); + } + } + +private: + template friend class GenericValue; + template friend class GenericDocument; + + enum { + kBoolFlag = 0x0008, + kNumberFlag = 0x0010, + kIntFlag = 0x0020, + kUintFlag = 0x0040, + kInt64Flag = 0x0080, + kUint64Flag = 0x0100, + kDoubleFlag = 0x0200, + kStringFlag = 0x0400, + kCopyFlag = 0x0800, + kInlineStrFlag = 0x1000, + + // Initial flags of different types. + kNullFlag = kNullType, + kTrueFlag = kTrueType | kBoolFlag, + kFalseFlag = kFalseType | kBoolFlag, + kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, + kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, + kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, + kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, + kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, + kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag, + kConstStringFlag = kStringType | kStringFlag, + kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, + kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag, + kObjectFlag = kObjectType, + kArrayFlag = kArrayType, + + kTypeMask = 0x07 + }; + + static const SizeType kDefaultArrayCapacity = 16; + static const SizeType kDefaultObjectCapacity = 16; + + struct Flag { +#if RAPIDJSON_48BITPOINTER_OPTIMIZATION + char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer +#elif RAPIDJSON_64BIT + char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes +#else + char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes +#endif + uint16_t flags; + }; + + struct String { + SizeType length; + SizeType hashcode; //!< reserved + const Ch* str; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars + // (excluding the terminating zero) and store a value to determine the length of the contained + // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string + // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as + // the string terminator as well. For getting the string length back from that value just use + // "MaxSize - str[LenPos]". + // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode, + // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings). + struct ShortString { + enum { MaxChars = sizeof(static_cast(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize }; + Ch str[MaxChars]; + + inline static bool Usable(SizeType len) { return (MaxSize >= len); } + inline void SetLength(SizeType len) { str[LenPos] = static_cast(MaxSize - len); } + inline SizeType GetLength() const { return static_cast(MaxSize - str[LenPos]); } + }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // By using proper binary layout, retrieval of different integer types do not need conversions. + union Number { +#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN + struct I { + int i; + char padding[4]; + }i; + struct U { + unsigned u; + char padding2[4]; + }u; +#else + struct I { + char padding[4]; + int i; + }i; + struct U { + char padding2[4]; + unsigned u; + }u; +#endif + int64_t i64; + uint64_t u64; + double d; + }; // 8 bytes + + struct ObjectData { + SizeType size; + SizeType capacity; + Member* members; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + struct ArrayData { + SizeType size; + SizeType capacity; + GenericValue* elements; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + union Data { + String s; + ShortString ss; + Number n; + ObjectData o; + ArrayData a; + Flag f; + }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION + + RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); } + RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); } + RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); } + RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); } + RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); } + RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); } + + // Initialize this value as array with initial data, without calling destructor. + void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { + data_.f.flags = kArrayFlag; + if (count) { + GenericValue* e = static_cast(allocator.Malloc(count * sizeof(GenericValue))); + SetElementsPointer(e); + std::memcpy(e, values, count * sizeof(GenericValue)); + } + else + SetElementsPointer(0); + data_.a.size = data_.a.capacity = count; + } + + //! Initialize this value as object with initial data, without calling destructor. + void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { + data_.f.flags = kObjectFlag; + if (count) { + Member* m = static_cast(allocator.Malloc(count * sizeof(Member))); + SetMembersPointer(m); + std::memcpy(m, members, count * sizeof(Member)); + } + else + SetMembersPointer(0); + data_.o.size = data_.o.capacity = count; + } + + //! Initialize this value as constant string, without calling destructor. + void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT { + data_.f.flags = kConstStringFlag; + SetStringPointer(s); + data_.s.length = s.length; + } + + //! Initialize this value as copy string with initial data, without calling destructor. + void SetStringRaw(StringRefType s, Allocator& allocator) { + Ch* str = 0; + if (ShortString::Usable(s.length)) { + data_.f.flags = kShortStringFlag; + data_.ss.SetLength(s.length); + str = data_.ss.str; + } else { + data_.f.flags = kCopyStringFlag; + data_.s.length = s.length; + str = static_cast(allocator.Malloc((s.length + 1) * sizeof(Ch))); + SetStringPointer(str); + } + std::memcpy(str, s, s.length * sizeof(Ch)); + str[s.length] = '\0'; + } + + //! Assignment without calling destructor + void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + data_ = rhs.data_; + // data_.f.flags = rhs.data_.f.flags; + rhs.data_.f.flags = kNullFlag; + } + + template + bool StringEqual(const GenericValue& rhs) const { + RAPIDJSON_ASSERT(IsString()); + RAPIDJSON_ASSERT(rhs.IsString()); + + const SizeType len1 = GetStringLength(); + const SizeType len2 = rhs.GetStringLength(); + if(len1 != len2) { return false; } + + const Ch* const str1 = GetString(); + const Ch* const str2 = rhs.GetString(); + if(str1 == str2) { return true; } // fast path for constant string + + return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0); + } + + Data data_; +}; + +//! GenericValue with UTF8 encoding +typedef GenericValue > Value; + +/////////////////////////////////////////////////////////////////////////////// +// GenericDocument + +//! A document for parsing JSON text as DOM. +/*! + \note implements Handler concept + \tparam Encoding Encoding for both parsing and string storage. + \tparam Allocator Allocator for allocating memory for the DOM + \tparam StackAllocator Allocator for allocating memory for stack during parsing. + \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue. +*/ +template , typename StackAllocator = CrtAllocator> +class GenericDocument : public GenericValue { +public: + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericValue ValueType; //!< Value type of the document. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + + //! Constructor + /*! Creates an empty document of specified type. + \param type Mandatory type of object to create. + \param allocator Optional allocator for allocating memory. + \param stackCapacity Optional initial capacity of stack in bytes. + \param stackAllocator Optional allocator for allocating memory for stack. + */ + explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : + GenericValue(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + } + + //! Constructor + /*! Creates an empty document which type is Null. + \param allocator Optional allocator for allocating memory. + \param stackCapacity Optional initial capacity of stack in bytes. + \param stackAllocator Optional allocator for allocating memory for stack. + */ + GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : + allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT + : ValueType(std::forward(rhs)), // explicit cast to avoid prohibited move from Document + allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + stack_(std::move(rhs.stack_)), + parseResult_(rhs.parseResult_) + { + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.parseResult_ = ParseResult(); + } +#endif + + ~GenericDocument() { + Destroy(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT + { + // The cast to ValueType is necessary here, because otherwise it would + // attempt to call GenericValue's templated assignment operator. + ValueType::operator=(std::forward(rhs)); + + // Calling the destructor here would prematurely call stack_'s destructor + Destroy(); + + allocator_ = rhs.allocator_; + ownAllocator_ = rhs.ownAllocator_; + stack_ = std::move(rhs.stack_); + parseResult_ = rhs.parseResult_; + + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.parseResult_ = ParseResult(); + + return *this; + } +#endif + + //! Exchange the contents of this document with those of another. + /*! + \param rhs Another document. + \note Constant complexity. + \see GenericValue::Swap + */ + GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT { + ValueType::Swap(rhs); + stack_.Swap(rhs.stack_); + internal::Swap(allocator_, rhs.allocator_); + internal::Swap(ownAllocator_, rhs.ownAllocator_); + internal::Swap(parseResult_, rhs.parseResult_); + return *this; + } + + //! free-standing swap function helper + /*! + Helper function to enable support for common swap implementation pattern based on \c std::swap: + \code + void swap(MyClass& a, MyClass& b) { + using std::swap; + swap(a.doc, b.doc); + // ... + } + \endcode + \see Swap() + */ + friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } + + //! Populate this document by a generator which produces SAX events. + /*! \tparam Generator A functor with bool f(Handler) prototype. + \param g Generator functor which sends SAX events to the parameter. + \return The document itself for fluent API. + */ + template + GenericDocument& Populate(Generator& g) { + ClearStackOnExit scope(*this); + if (g(*this)) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + ValueType::operator=(*stack_.template Pop(1));// Move value from stack to document + } + return *this; + } + + //!@name Parse from stream + //!@{ + + //! Parse JSON text from an input stream (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam SourceEncoding Encoding of input stream + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + GenericReader reader( + stack_.HasAllocator() ? &stack_.GetAllocator() : 0); + ClearStackOnExit scope(*this); + parseResult_ = reader.template Parse(is, *this); + if (parseResult_) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + ValueType::operator=(*stack_.template Pop(1));// Move value from stack to document + } + return *this; + } + + //! Parse JSON text from an input stream + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + return ParseStream(is); + } + + //! Parse JSON text from an input stream (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + return ParseStream(is); + } + //!@} + + //!@name Parse in-place from mutable string + //!@{ + + //! Parse JSON text from a mutable string + /*! \tparam parseFlags Combination of \ref ParseFlag. + \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseInsitu(Ch* str) { + GenericInsituStringStream s(str); + return ParseStream(s); + } + + //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags) + /*! \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + GenericDocument& ParseInsitu(Ch* str) { + return ParseInsitu(str); + } + //!@} + + //!@name Parse from read-only string + //!@{ + + //! Parse JSON text from a read-only string (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \tparam SourceEncoding Transcoding from input Encoding + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const typename SourceEncoding::Ch* str) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + GenericStringStream s(str); + return ParseStream(s); + } + + //! Parse JSON text from a read-only string + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const Ch* str) { + return Parse(str); + } + + //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags) + /*! \param str Read-only zero-terminated string to be parsed. + */ + GenericDocument& Parse(const Ch* str) { + return Parse(str); + } + + template + GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + MemoryStream ms(static_cast(str), length * sizeof(typename SourceEncoding::Ch)); + EncodedInputStream is(ms); + ParseStream(is); + return *this; + } + + template + GenericDocument& Parse(const Ch* str, size_t length) { + return Parse(str, length); + } + + GenericDocument& Parse(const Ch* str, size_t length) { + return Parse(str, length); + } + +#if RAPIDJSON_HAS_STDSTRING + template + GenericDocument& Parse(const std::basic_string& str) { + // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t) + return Parse(str.c_str()); + } + + template + GenericDocument& Parse(const std::basic_string& str) { + return Parse(str.c_str()); + } + + GenericDocument& Parse(const std::basic_string& str) { + return Parse(str); + } +#endif // RAPIDJSON_HAS_STDSTRING + + //!@} + + //!@name Handling parse errors + //!@{ + + //! Whether a parse error has occured in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseError() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + + //! Implicit conversion to get the last parse result +#ifndef __clang // -Wdocumentation + /*! \return \ref ParseResult of the last parse operation + + \code + Document doc; + ParseResult ok = doc.Parse(json); + if (!ok) + printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset()); + \endcode + */ +#endif + operator ParseResult() const { return parseResult_; } + //!@} + + //! Get the allocator of this document. + Allocator& GetAllocator() { + RAPIDJSON_ASSERT(allocator_); + return *allocator_; + } + + //! Get the capacity of stack in bytes. + size_t GetStackCapacity() const { return stack_.GetCapacity(); } + +private: + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericDocument& d) : d_(d) {} + ~ClearStackOnExit() { d_.ClearStack(); } + private: + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + GenericDocument& d_; + }; + + // callers of the following private Handler functions + // template friend class GenericReader; // for parsing + template friend class GenericValue; // for deep copying + +public: + // Implementation of Handler + bool Null() { new (stack_.template Push()) ValueType(); return true; } + bool Bool(bool b) { new (stack_.template Push()) ValueType(b); return true; } + bool Int(int i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint(unsigned i) { new (stack_.template Push()) ValueType(i); return true; } + bool Int64(int64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint64(uint64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Double(double d) { new (stack_.template Push()) ValueType(d); return true; } + + bool RawNumber(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push()) ValueType(str, length); + return true; + } + + bool String(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push()) ValueType(str, length); + return true; + } + + bool StartObject() { new (stack_.template Push()) ValueType(kObjectType); return true; } + + bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount) { + typename ValueType::Member* members = stack_.template Pop(memberCount); + stack_.template Top()->SetObjectRaw(members, memberCount, GetAllocator()); + return true; + } + + bool StartArray() { new (stack_.template Push()) ValueType(kArrayType); return true; } + + bool EndArray(SizeType elementCount) { + ValueType* elements = stack_.template Pop(elementCount); + stack_.template Top()->SetArrayRaw(elements, elementCount, GetAllocator()); + return true; + } + +private: + //! Prohibit copying + GenericDocument(const GenericDocument&); + //! Prohibit assignment + GenericDocument& operator=(const GenericDocument&); + + void ClearStack() { + if (Allocator::kNeedFree) + while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) + (stack_.template Pop(1))->~ValueType(); + else + stack_.Clear(); + stack_.ShrinkToFit(); + } + + void Destroy() { + RAPIDJSON_DELETE(ownAllocator_); + } + + static const size_t kDefaultStackCapacity = 1024; + Allocator* allocator_; + Allocator* ownAllocator_; + internal::Stack stack_; + ParseResult parseResult_; +}; + +//! GenericDocument with UTF8 encoding +typedef GenericDocument > Document; + +// defined here due to the dependency on GenericDocument +template +template +inline +GenericValue::GenericValue(const GenericValue& rhs, Allocator& allocator) +{ + switch (rhs.GetType()) { + case kObjectType: + case kArrayType: { // perform deep copy via SAX Handler + GenericDocument d(&allocator); + rhs.Accept(d); + RawAssign(*d.stack_.template Pop(1)); + } + break; + case kStringType: + if (rhs.data_.f.flags == kConstStringFlag) { + data_.f.flags = rhs.data_.f.flags; + data_ = *reinterpret_cast(&rhs.data_); + } else { + SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); + } + break; + default: + data_.f.flags = rhs.data_.f.flags; + data_ = *reinterpret_cast(&rhs.data_); + break; + } +} + +//! Helper class for accessing Value of array type. +/*! + Instance of this helper class is obtained by \c GenericValue::GetArray(). + In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. +*/ +template +class GenericArray { +public: + typedef GenericArray ConstArray; + typedef GenericArray Array; + typedef ValueT PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef ValueType* ValueIterator; // This may be const or non-const iterator + typedef const ValueT* ConstValueIterator; + typedef typename ValueType::AllocatorType AllocatorType; + typedef typename ValueType::StringRefType StringRefType; + + template + friend class GenericValue; + + GenericArray(const GenericArray& rhs) : value_(rhs.value_) {} + GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; } + ~GenericArray() {} + + SizeType Size() const { return value_.Size(); } + SizeType Capacity() const { return value_.Capacity(); } + bool Empty() const { return value_.Empty(); } + void Clear() const { value_.Clear(); } + ValueType& operator[](SizeType index) const { return value_[index]; } + ValueIterator Begin() const { return value_.Begin(); } + ValueIterator End() const { return value_.End(); } + GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; } + GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } + GenericArray PopBack() const { value_.PopBack(); return *this; } + ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); } + ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); } + +#if RAPIDJSON_HAS_CXX11_RANGE_FOR + ValueIterator begin() const { return value_.Begin(); } + ValueIterator end() const { return value_.End(); } +#endif + +private: + GenericArray(); + GenericArray(ValueType& value) : value_(value) {} + ValueType& value_; +}; + +//! Helper class for accessing Value of object type. +/*! + Instance of this helper class is obtained by \c GenericValue::GetObject(). + In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. +*/ +template +class GenericObject { +public: + typedef GenericObject ConstObject; + typedef GenericObject Object; + typedef ValueT PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef GenericMemberIterator MemberIterator; // This may be const or non-const iterator + typedef GenericMemberIterator ConstMemberIterator; + typedef typename ValueType::AllocatorType AllocatorType; + typedef typename ValueType::StringRefType StringRefType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename ValueType::Ch Ch; + + template + friend class GenericValue; + + GenericObject(const GenericObject& rhs) : value_(rhs.value_) {} + GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; } + ~GenericObject() {} + + SizeType MemberCount() const { return value_.MemberCount(); } + bool ObjectEmpty() const { return value_.ObjectEmpty(); } + template ValueType& operator[](T* name) const { return value_[name]; } + template ValueType& operator[](const GenericValue& name) const { return value_[name]; } +#if RAPIDJSON_HAS_STDSTRING + ValueType& operator[](const std::basic_string& name) const { return value_[name]; } +#endif + MemberIterator MemberBegin() const { return value_.MemberBegin(); } + MemberIterator MemberEnd() const { return value_.MemberEnd(); } + bool HasMember(const Ch* name) const { return value_.HasMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool HasMember(const std::basic_string& name) const { return value_.HasMember(name); } +#endif + template bool HasMember(const GenericValue& name) const { return value_.HasMember(name); } + MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); } + template MemberIterator FindMember(const GenericValue& name) const { return value_.FindMember(name); } +#if RAPIDJSON_HAS_STDSTRING + MemberIterator FindMember(const std::basic_string& name) const { return value_.FindMember(name); } +#endif + GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#if RAPIDJSON_HAS_STDSTRING + GenericObject AddMember(ValueType& name, std::basic_string& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#endif + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + void RemoveAllMembers() { return value_.RemoveAllMembers(); } + bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool RemoveMember(const std::basic_string& name) const { return value_.RemoveMember(name); } +#endif + template bool RemoveMember(const GenericValue& name) const { return value_.RemoveMember(name); } + MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); } + MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); } + MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); } + bool EraseMember(const Ch* name) const { return value_.EraseMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool EraseMember(const std::basic_string& name) const { return EraseMember(ValueType(StringRef(name))); } +#endif + template bool EraseMember(const GenericValue& name) const { return value_.EraseMember(name); } + +#if RAPIDJSON_HAS_CXX11_RANGE_FOR + MemberIterator begin() const { return value_.MemberBegin(); } + MemberIterator end() const { return value_.MemberEnd(); } +#endif + +private: + GenericObject(); + GenericObject(ValueType& value) : value_(value) {} + ValueType& value_; +}; + +RAPIDJSON_NAMESPACE_END +RAPIDJSON_DIAG_POP + +#endif // RAPIDJSON_DOCUMENT_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/encodedstream.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/encodedstream.h new file mode 100644 index 0000000000..145068386a --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/encodedstream.h @@ -0,0 +1,299 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ENCODEDSTREAM_H_ +#define RAPIDJSON_ENCODEDSTREAM_H_ + +#include "stream.h" +#include "memorystream.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Input byte stream wrapper with a statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam InputByteStream Type of input byte stream. For example, FileReadStream. +*/ +template +class EncodedInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedInputStream(InputByteStream& is) : is_(is) { + current_ = Encoding::TakeBOM(is_); + } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; } + size_t Tell() const { return is_.Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedInputStream(const EncodedInputStream&); + EncodedInputStream& operator=(const EncodedInputStream&); + + InputByteStream& is_; + Ch current_; +}; + +//! Specialized for UTF8 MemoryStream. +template <> +class EncodedInputStream, MemoryStream> { +public: + typedef UTF8<>::Ch Ch; + + EncodedInputStream(MemoryStream& is) : is_(is) { + if (static_cast(is_.Peek()) == 0xEFu) is_.Take(); + if (static_cast(is_.Peek()) == 0xBBu) is_.Take(); + if (static_cast(is_.Peek()) == 0xBFu) is_.Take(); + } + Ch Peek() const { return is_.Peek(); } + Ch Take() { return is_.Take(); } + size_t Tell() const { return is_.Tell(); } + + // Not implemented + void Put(Ch) {} + void Flush() {} + Ch* PutBegin() { return 0; } + size_t PutEnd(Ch*) { return 0; } + + MemoryStream& is_; + +private: + EncodedInputStream(const EncodedInputStream&); + EncodedInputStream& operator=(const EncodedInputStream&); +}; + +//! Output byte stream wrapper with statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam OutputByteStream Type of input byte stream. For example, FileWriteStream. +*/ +template +class EncodedOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { + if (putBOM) + Encoding::PutBOM(os_); + } + + void Put(Ch c) { Encoding::Put(os_, c); } + void Flush() { os_.Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} + Ch Take() { RAPIDJSON_ASSERT(false); return 0;} + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedOutputStream(const EncodedOutputStream&); + EncodedOutputStream& operator=(const EncodedOutputStream&); + + OutputByteStream& os_; +}; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x + +//! Input stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for reading. + \tparam InputByteStream type of input byte stream to be wrapped. +*/ +template +class AutoUTFInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param is input stream to be wrapped. + \param type UTF encoding type if it is not detected from the stream. + */ + AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) { + RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); + DetectType(); + static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) }; + takeFunc_ = f[type_]; + current_ = takeFunc_(*is_); + } + + UTFType GetType() const { return type_; } + bool HasBOM() const { return hasBOM_; } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; } + size_t Tell() const { return is_->Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFInputStream(const AutoUTFInputStream&); + AutoUTFInputStream& operator=(const AutoUTFInputStream&); + + // Detect encoding type with BOM or RFC 4627 + void DetectType() { + // BOM (Byte Order Mark): + // 00 00 FE FF UTF-32BE + // FF FE 00 00 UTF-32LE + // FE FF UTF-16BE + // FF FE UTF-16LE + // EF BB BF UTF-8 + + const unsigned char* c = reinterpret_cast(is_->Peek4()); + if (!c) + return; + + unsigned bom = static_cast(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24)); + hasBOM_ = false; + if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); } + + // RFC 4627: Section 3 + // "Since the first two characters of a JSON text will always be ASCII + // characters [RFC0020], it is possible to determine whether an octet + // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking + // at the pattern of nulls in the first four octets." + // 00 00 00 xx UTF-32BE + // 00 xx 00 xx UTF-16BE + // xx 00 00 00 UTF-32LE + // xx 00 xx 00 UTF-16LE + // xx xx xx xx UTF-8 + + if (!hasBOM_) { + unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); + switch (pattern) { + case 0x08: type_ = kUTF32BE; break; + case 0x0A: type_ = kUTF16BE; break; + case 0x01: type_ = kUTF32LE; break; + case 0x05: type_ = kUTF16LE; break; + case 0x0F: type_ = kUTF8; break; + default: break; // Use type defined by user. + } + } + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + } + + typedef Ch (*TakeFunc)(InputByteStream& is); + InputByteStream* is_; + UTFType type_; + Ch current_; + TakeFunc takeFunc_; + bool hasBOM_; +}; + +//! Output stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for writing. + \tparam OutputByteStream type of output byte stream to be wrapped. +*/ +template +class AutoUTFOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param os output stream to be wrapped. + \param type UTF encoding type. + \param putBOM Whether to write BOM at the beginning of the stream. + */ + AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) { + RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + + static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) }; + putFunc_ = f[type_]; + + if (putBOM) + PutBOM(); + } + + UTFType GetType() const { return type_; } + + void Put(Ch c) { putFunc_(*os_, c); } + void Flush() { os_->Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} + Ch Take() { RAPIDJSON_ASSERT(false); return 0;} + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFOutputStream(const AutoUTFOutputStream&); + AutoUTFOutputStream& operator=(const AutoUTFOutputStream&); + + void PutBOM() { + typedef void (*PutBOMFunc)(OutputByteStream&); + static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) }; + f[type_](*os_); + } + + typedef void (*PutFunc)(OutputByteStream&, Ch); + + OutputByteStream* os_; + UTFType type_; + PutFunc putFunc_; +}; + +#undef RAPIDJSON_ENCODINGS_FUNC + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/encodings.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/encodings.h new file mode 100644 index 0000000000..baa7c2b17f --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/encodings.h @@ -0,0 +1,716 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ENCODINGS_H_ +#define RAPIDJSON_ENCODINGS_H_ + +#include "rapidjson.h" + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#elif defined(__GNUC__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +RAPIDJSON_DIAG_OFF(overflow) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Encoding + +/*! \class rapidjson::Encoding + \brief Concept for encoding of Unicode characters. + +\code +concept Encoding { + typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition. + + enum { supportUnicode = 1 }; // or 0 if not supporting unicode + + //! \brief Encode a Unicode codepoint to an output stream. + //! \param os Output stream. + //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. + template + static void Encode(OutputStream& os, unsigned codepoint); + + //! \brief Decode a Unicode codepoint from an input stream. + //! \param is Input stream. + //! \param codepoint Output of the unicode codepoint. + //! \return true if a valid codepoint can be decoded from the stream. + template + static bool Decode(InputStream& is, unsigned* codepoint); + + //! \brief Validate one Unicode codepoint from an encoded stream. + //! \param is Input stream to obtain codepoint. + //! \param os Output for copying one codepoint. + //! \return true if it is valid. + //! \note This function just validating and copying the codepoint without actually decode it. + template + static bool Validate(InputStream& is, OutputStream& os); + + // The following functions are deal with byte streams. + + //! Take a character from input byte stream, skip BOM if exist. + template + static CharType TakeBOM(InputByteStream& is); + + //! Take a character from input byte stream. + template + static Ch Take(InputByteStream& is); + + //! Put BOM to output byte stream. + template + static void PutBOM(OutputByteStream& os); + + //! Put a character to output byte stream. + template + static void Put(OutputByteStream& os, Ch c); +}; +\endcode +*/ + +/////////////////////////////////////////////////////////////////////////////// +// UTF8 + +//! UTF-8 encoding. +/*! http://en.wikipedia.org/wiki/UTF-8 + http://tools.ietf.org/html/rfc3629 + \tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char. + \note implements Encoding concept +*/ +template +struct UTF8 { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + os.Put(static_cast(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + os.Put(static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + os.Put(static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast(0x80 | (codepoint & 0x3F))); + } + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + PutUnsafe(os, static_cast(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + PutUnsafe(os, static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + PutUnsafe(os, static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + PutUnsafe(os, static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); + } + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { +#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast(c) & 0x3Fu) +#define TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) +#define TAIL() COPY(); TRANS(0x70) + typename InputStream::Ch c = is.Take(); + if (!(c & 0x80)) { + *codepoint = static_cast(c); + return true; + } + + unsigned char type = GetRange(static_cast(c)); + if (type >= 32) { + *codepoint = 0; + } else { + *codepoint = (0xFF >> type) & static_cast(c); + } + bool result = true; + switch (type) { + case 2: TAIL(); return result; + case 3: TAIL(); TAIL(); return result; + case 4: COPY(); TRANS(0x50); TAIL(); return result; + case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; + case 6: TAIL(); TAIL(); TAIL(); return result; + case 10: COPY(); TRANS(0x20); TAIL(); return result; + case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; + default: return false; + } +#undef COPY +#undef TRANS +#undef TAIL + } + + template + static bool Validate(InputStream& is, OutputStream& os) { +#define COPY() os.Put(c = is.Take()) +#define TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) +#define TAIL() COPY(); TRANS(0x70) + Ch c; + COPY(); + if (!(c & 0x80)) + return true; + + bool result = true; + switch (GetRange(static_cast(c))) { + case 2: TAIL(); return result; + case 3: TAIL(); TAIL(); return result; + case 4: COPY(); TRANS(0x50); TAIL(); return result; + case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; + case 6: TAIL(); TAIL(); TAIL(); return result; + case 10: COPY(); TRANS(0x20); TAIL(); return result; + case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; + default: return false; + } +#undef COPY +#undef TRANS +#undef TAIL + } + + static unsigned char GetRange(unsigned char c) { + // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ + // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types. + static const unsigned char type[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + }; + return type[c]; + } + + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + typename InputByteStream::Ch c = Take(is); + if (static_cast(c) != 0xEFu) return c; + c = is.Take(); + if (static_cast(c) != 0xBBu) return c; + c = is.Take(); + if (static_cast(c) != 0xBFu) return c; + c = is.Take(); + return c; + } + + template + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return static_cast(is.Take()); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xEFu)); + os.Put(static_cast(0xBBu)); + os.Put(static_cast(0xBFu)); + } + + template + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF16 + +//! UTF-16 encoding. +/*! http://en.wikipedia.org/wiki/UTF-16 + http://tools.ietf.org/html/rfc2781 + \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF16LE and UTF16BE, which handle endianness. +*/ +template +struct UTF16 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2); + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + os.Put(static_cast(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + os.Put(static_cast((v >> 10) | 0xD800)); + os.Put((v & 0x3FF) | 0xDC00); + } + } + + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + PutUnsafe(os, static_cast(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + PutUnsafe(os, static_cast((v >> 10) | 0xD800)); + PutUnsafe(os, (v & 0x3FF) | 0xDC00); + } + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + typename InputStream::Ch c = is.Take(); + if (c < 0xD800 || c > 0xDFFF) { + *codepoint = static_cast(c); + return true; + } + else if (c <= 0xDBFF) { + *codepoint = (static_cast(c) & 0x3FF) << 10; + c = is.Take(); + *codepoint |= (static_cast(c) & 0x3FF); + *codepoint += 0x10000; + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + typename InputStream::Ch c; + os.Put(static_cast(c = is.Take())); + if (c < 0xD800 || c > 0xDFFF) + return true; + else if (c <= 0xDBFF) { + os.Put(c = is.Take()); + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } +}; + +//! UTF-16 little endian encoding. +template +struct UTF16LE : UTF16 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0xFEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(is.Take()); + c |= static_cast(static_cast(is.Take())) << 8; + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFFu)); + os.Put(static_cast(0xFEu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(static_cast(c) & 0xFFu)); + os.Put(static_cast((static_cast(c) >> 8) & 0xFFu)); + } +}; + +//! UTF-16 big endian encoding. +template +struct UTF16BE : UTF16 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0xFEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(static_cast(is.Take())) << 8; + c |= static_cast(is.Take()); + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0xFFu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast((static_cast(c) >> 8) & 0xFFu)); + os.Put(static_cast(static_cast(c) & 0xFFu)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF32 + +//! UTF-32 encoding. +/*! http://en.wikipedia.org/wiki/UTF-32 + \tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF32LE and UTF32BE, which handle endianness. +*/ +template +struct UTF32 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4); + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(codepoint); + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + PutUnsafe(os, codepoint); + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c = is.Take(); + *codepoint = c; + return c <= 0x10FFFF; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c; + os.Put(c = is.Take()); + return c <= 0x10FFFF; + } +}; + +//! UTF-32 little endian enocoding. +template +struct UTF32LE : UTF32 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0x0000FEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(is.Take()); + c |= static_cast(static_cast(is.Take())) << 8; + c |= static_cast(static_cast(is.Take())) << 16; + c |= static_cast(static_cast(is.Take())) << 24; + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFFu)); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0x00u)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c & 0xFFu)); + os.Put(static_cast((c >> 8) & 0xFFu)); + os.Put(static_cast((c >> 16) & 0xFFu)); + os.Put(static_cast((c >> 24) & 0xFFu)); + } +}; + +//! UTF-32 big endian encoding. +template +struct UTF32BE : UTF32 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0x0000FEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(static_cast(is.Take())) << 24; + c |= static_cast(static_cast(is.Take())) << 16; + c |= static_cast(static_cast(is.Take())) << 8; + c |= static_cast(static_cast(is.Take())); + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0xFFu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast((c >> 24) & 0xFFu)); + os.Put(static_cast((c >> 16) & 0xFFu)); + os.Put(static_cast((c >> 8) & 0xFFu)); + os.Put(static_cast(c & 0xFFu)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// ASCII + +//! ASCII encoding. +/*! http://en.wikipedia.org/wiki/ASCII + \tparam CharType Code unit for storing 7-bit ASCII data. Default is char. + \note implements Encoding concept +*/ +template +struct ASCII { + typedef CharType Ch; + + enum { supportUnicode = 0 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + os.Put(static_cast(codepoint & 0xFF)); + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + PutUnsafe(os, static_cast(codepoint & 0xFF)); + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + uint8_t c = static_cast(is.Take()); + *codepoint = c; + return c <= 0X7F; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + uint8_t c = static_cast(is.Take()); + os.Put(static_cast(c)); + return c <= 0x7F; + } + + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + uint8_t c = static_cast(Take(is)); + return static_cast(c); + } + + template + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return static_cast(is.Take()); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + (void)os; + } + + template + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// AutoUTF + +//! Runtime-specified UTF encoding type of a stream. +enum UTFType { + kUTF8 = 0, //!< UTF-8. + kUTF16LE = 1, //!< UTF-16 little endian. + kUTF16BE = 2, //!< UTF-16 big endian. + kUTF32LE = 3, //!< UTF-32 little endian. + kUTF32BE = 4 //!< UTF-32 big endian. +}; + +//! Dynamically select encoding according to stream's runtime-specified UTF encoding type. +/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType(). +*/ +template +struct AutoUTF { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x + + template + RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) }; + (*f[os.GetType()])(os, codepoint); + } + + template + RAPIDJSON_FORCEINLINE static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) }; + (*f[os.GetType()])(os, codepoint); + } + + template + RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) { + typedef bool (*DecodeFunc)(InputStream&, unsigned*); + static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) }; + return (*f[is.GetType()])(is, codepoint); + } + + template + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + typedef bool (*ValidateFunc)(InputStream&, OutputStream&); + static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) }; + return (*f[is.GetType()])(is, os); + } + +#undef RAPIDJSON_ENCODINGS_FUNC +}; + +/////////////////////////////////////////////////////////////////////////////// +// Transcoder + +//! Encoding conversion. +template +struct Transcoder { + //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream. + template + RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::Encode(os, codepoint); + return true; + } + + template + RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::EncodeUnsafe(os, codepoint); + return true; + } + + //! Validate one Unicode codepoint from an encoded stream. + template + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + return Transcode(is, os); // Since source/target encoding is different, must transcode. + } +}; + +// Forward declaration. +template +inline void PutUnsafe(Stream& stream, typename Stream::Ch c); + +//! Specialization of Transcoder with same source and target encoding. +template +struct Transcoder { + template + RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { + os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + + template + RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) { + PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + + template + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + return Encoding::Validate(is, os); // source/target encoding are the same + } +}; + +RAPIDJSON_NAMESPACE_END + +#if defined(__GNUC__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/error/en.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/error/en.h new file mode 100644 index 0000000000..2db838bff2 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/error/en.h @@ -0,0 +1,74 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ERROR_EN_H_ +#define RAPIDJSON_ERROR_EN_H_ + +#include "error.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(covered-switch-default) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Maps error code of parsing into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param parseErrorCode Error code obtained in parsing. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ +inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { + switch (parseErrorCode) { + case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); + case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values."); + + case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); + + case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); + case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); + case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); + + case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); + + case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); + case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); + case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); + case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); + case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); + + case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); + case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); + case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); + + case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); + case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); + + default: return RAPIDJSON_ERROR_STRING("Unknown error."); + } +} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ERROR_EN_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/error/error.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/error/error.h new file mode 100644 index 0000000000..95cb31a72f --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/error/error.h @@ -0,0 +1,155 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ERROR_ERROR_H_ +#define RAPIDJSON_ERROR_ERROR_H_ + +#include "../rapidjson.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +/*! \file error.h */ + +/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_CHARTYPE + +//! Character type of error messages. +/*! \ingroup RAPIDJSON_ERRORS + The default character type is \c char. + On Windows, user can define this macro as \c TCHAR for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_CHARTYPE +#define RAPIDJSON_ERROR_CHARTYPE char +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_STRING + +//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[]. +/*! \ingroup RAPIDJSON_ERRORS + By default this conversion macro does nothing. + On Windows, user can define this macro as \c _T(x) for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_STRING +#define RAPIDJSON_ERROR_STRING(x) x +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// ParseErrorCode + +//! Error code of parsing. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericReader::Parse, GenericReader::GetParseErrorCode +*/ +enum ParseErrorCode { + kParseErrorNone = 0, //!< No error. + + kParseErrorDocumentEmpty, //!< The document is empty. + kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. + + kParseErrorValueInvalid, //!< Invalid value. + + kParseErrorObjectMissName, //!< Missing a name for object member. + kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. + kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. + + kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. + + kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. + kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. + kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. + kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. + kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. + + kParseErrorNumberTooBig, //!< Number too big to be stored in double. + kParseErrorNumberMissFraction, //!< Miss fraction part in number. + kParseErrorNumberMissExponent, //!< Miss exponent in number. + + kParseErrorTermination, //!< Parsing was terminated. + kParseErrorUnspecificSyntaxError //!< Unspecific syntax error. +}; + +//! Result of parsing (wraps ParseErrorCode) +/*! + \ingroup RAPIDJSON_ERRORS + \code + Document doc; + ParseResult ok = doc.Parse("[42]"); + if (!ok) { + fprintf(stderr, "JSON parse error: %s (%u)", + GetParseError_En(ok.Code()), ok.Offset()); + exit(EXIT_FAILURE); + } + \endcode + \see GenericReader::Parse, GenericDocument::Parse +*/ +struct ParseResult { +public: + //! Default constructor, no error. + ParseResult() : code_(kParseErrorNone), offset_(0) {} + //! Constructor to set an error. + ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} + + //! Get the error code. + ParseErrorCode Code() const { return code_; } + //! Get the error offset, if \ref IsError(), 0 otherwise. + size_t Offset() const { return offset_; } + + //! Conversion to \c bool, returns \c true, iff !\ref IsError(). + operator bool() const { return !IsError(); } + //! Whether the result is an error. + bool IsError() const { return code_ != kParseErrorNone; } + + bool operator==(const ParseResult& that) const { return code_ == that.code_; } + bool operator==(ParseErrorCode code) const { return code_ == code; } + friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } + + //! Reset error code. + void Clear() { Set(kParseErrorNone); } + //! Update error code and offset. + void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } + +private: + ParseErrorCode code_; + size_t offset_; +}; + +//! Function pointer type of GetParseError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetParseError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetParseErrorFunc GetParseError = GetParseError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ERROR_ERROR_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/filereadstream.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/filereadstream.h new file mode 100644 index 0000000000..b56ea13b34 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/filereadstream.h @@ -0,0 +1,99 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FILEREADSTREAM_H_ +#define RAPIDJSON_FILEREADSTREAM_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(unreachable-code) +RAPIDJSON_DIAG_OFF(missing-noreturn) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! File byte stream for input using fread(). +/*! + \note implements Stream concept +*/ +class FileReadStream { +public: + typedef char Ch; //!< Character type (byte). + + //! Constructor. + /*! + \param fp File pointer opened for read. + \param buffer user-supplied buffer. + \param bufferSize size of buffer in bytes. Must >=4 bytes. + */ + FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { + RAPIDJSON_ASSERT(fp_ != 0); + RAPIDJSON_ASSERT(bufferSize >= 4); + Read(); + } + + Ch Peek() const { return *current_; } + Ch Take() { Ch c = *current_; Read(); return c; } + size_t Tell() const { return count_ + static_cast(current_ - buffer_); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return (current_ + 4 <= bufferLast_) ? current_ : 0; + } + +private: + void Read() { + if (current_ < bufferLast_) + ++current_; + else if (!eof_) { + count_ += readCount_; + readCount_ = fread(buffer_, 1, bufferSize_, fp_); + bufferLast_ = buffer_ + readCount_ - 1; + current_ = buffer_; + + if (readCount_ < bufferSize_) { + buffer_[readCount_] = '\0'; + ++bufferLast_; + eof_ = true; + } + } + } + + std::FILE* fp_; + Ch *buffer_; + size_t bufferSize_; + Ch *bufferLast_; + Ch *current_; + size_t readCount_; + size_t count_; //!< Number of characters read + bool eof_; +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/filewritestream.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/filewritestream.h new file mode 100644 index 0000000000..6378dd60ed --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/filewritestream.h @@ -0,0 +1,104 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FILEWRITESTREAM_H_ +#define RAPIDJSON_FILEWRITESTREAM_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(unreachable-code) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of C file stream for input using fread(). +/*! + \note implements Stream concept +*/ +class FileWriteStream { +public: + typedef char Ch; //!< Character type. Only support char. + + FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { + RAPIDJSON_ASSERT(fp_ != 0); + } + + void Put(char c) { + if (current_ >= bufferEnd_) + Flush(); + + *current_++ = c; + } + + void PutN(char c, size_t n) { + size_t avail = static_cast(bufferEnd_ - current_); + while (n > avail) { + std::memset(current_, c, avail); + current_ += avail; + Flush(); + n -= avail; + avail = static_cast(bufferEnd_ - current_); + } + + if (n > 0) { + std::memset(current_, c, n); + current_ += n; + } + } + + void Flush() { + if (current_ != buffer_) { + size_t result = fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_); + if (result < static_cast(current_ - buffer_)) { + // failure deliberately ignored at this time + // added to avoid warn_unused_result build errors + } + current_ = buffer_; + } + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + // Prohibit copy constructor & assignment operator. + FileWriteStream(const FileWriteStream&); + FileWriteStream& operator=(const FileWriteStream&); + + std::FILE* fp_; + char *buffer_; + char *bufferEnd_; + char *current_; +}; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(FileWriteStream& stream, char c, size_t n) { + stream.PutN(c, n); +} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/fwd.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/fwd.h new file mode 100644 index 0000000000..e8104e841b --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/fwd.h @@ -0,0 +1,151 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FWD_H_ +#define RAPIDJSON_FWD_H_ + +#include "rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN + +// encodings.h + +template struct UTF8; +template struct UTF16; +template struct UTF16BE; +template struct UTF16LE; +template struct UTF32; +template struct UTF32BE; +template struct UTF32LE; +template struct ASCII; +template struct AutoUTF; + +template +struct Transcoder; + +// allocators.h + +class CrtAllocator; + +template +class MemoryPoolAllocator; + +// stream.h + +template +struct GenericStringStream; + +typedef GenericStringStream > StringStream; + +template +struct GenericInsituStringStream; + +typedef GenericInsituStringStream > InsituStringStream; + +// stringbuffer.h + +template +class GenericStringBuffer; + +typedef GenericStringBuffer, CrtAllocator> StringBuffer; + +// filereadstream.h + +class FileReadStream; + +// filewritestream.h + +class FileWriteStream; + +// memorybuffer.h + +template +struct GenericMemoryBuffer; + +typedef GenericMemoryBuffer MemoryBuffer; + +// memorystream.h + +struct MemoryStream; + +// reader.h + +template +struct BaseReaderHandler; + +template +class GenericReader; + +typedef GenericReader, UTF8, CrtAllocator> Reader; + +// writer.h + +template +class Writer; + +// prettywriter.h + +template +class PrettyWriter; + +// document.h + +template +struct GenericMember; + +template +class GenericMemberIterator; + +template +struct GenericStringRef; + +template +class GenericValue; + +typedef GenericValue, MemoryPoolAllocator > Value; + +template +class GenericDocument; + +typedef GenericDocument, MemoryPoolAllocator, CrtAllocator> Document; + +// pointer.h + +template +class GenericPointer; + +typedef GenericPointer Pointer; + +// schema.h + +template +class IGenericRemoteSchemaDocumentProvider; + +template +class GenericSchemaDocument; + +typedef GenericSchemaDocument SchemaDocument; +typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; + +template < + typename SchemaDocumentType, + typename OutputHandler, + typename StateAllocator> +class GenericSchemaValidator; + +typedef GenericSchemaValidator, void>, CrtAllocator> SchemaValidator; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_RAPIDJSONFWD_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/biginteger.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/biginteger.h new file mode 100644 index 0000000000..9d3e88c998 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/biginteger.h @@ -0,0 +1,290 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_BIGINTEGER_H_ +#define RAPIDJSON_BIGINTEGER_H_ + +#include "../rapidjson.h" + +#if defined(_MSC_VER) && defined(_M_AMD64) +#include // for _umul128 +#pragma intrinsic(_umul128) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +class BigInteger { +public: + typedef uint64_t Type; + + BigInteger(const BigInteger& rhs) : count_(rhs.count_) { + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); + } + + explicit BigInteger(uint64_t u) : count_(1) { + digits_[0] = u; + } + + BigInteger(const char* decimals, size_t length) : count_(1) { + RAPIDJSON_ASSERT(length > 0); + digits_[0] = 0; + size_t i = 0; + const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19 + while (length >= kMaxDigitPerIteration) { + AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration); + length -= kMaxDigitPerIteration; + i += kMaxDigitPerIteration; + } + + if (length > 0) + AppendDecimal64(decimals + i, decimals + i + length); + } + + BigInteger& operator=(const BigInteger &rhs) + { + if (this != &rhs) { + count_ = rhs.count_; + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); + } + return *this; + } + + BigInteger& operator=(uint64_t u) { + digits_[0] = u; + count_ = 1; + return *this; + } + + BigInteger& operator+=(uint64_t u) { + Type backup = digits_[0]; + digits_[0] += u; + for (size_t i = 0; i < count_ - 1; i++) { + if (digits_[i] >= backup) + return *this; // no carry + backup = digits_[i + 1]; + digits_[i + 1] += 1; + } + + // Last carry + if (digits_[count_ - 1] < backup) + PushBack(1); + + return *this; + } + + BigInteger& operator*=(uint64_t u) { + if (u == 0) return *this = 0; + if (u == 1) return *this; + if (*this == 1) return *this = u; + + uint64_t k = 0; + for (size_t i = 0; i < count_; i++) { + uint64_t hi; + digits_[i] = MulAdd64(digits_[i], u, k, &hi); + k = hi; + } + + if (k > 0) + PushBack(k); + + return *this; + } + + BigInteger& operator*=(uint32_t u) { + if (u == 0) return *this = 0; + if (u == 1) return *this; + if (*this == 1) return *this = u; + + uint64_t k = 0; + for (size_t i = 0; i < count_; i++) { + const uint64_t c = digits_[i] >> 32; + const uint64_t d = digits_[i] & 0xFFFFFFFF; + const uint64_t uc = u * c; + const uint64_t ud = u * d; + const uint64_t p0 = ud + k; + const uint64_t p1 = uc + (p0 >> 32); + digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32); + k = p1 >> 32; + } + + if (k > 0) + PushBack(k); + + return *this; + } + + BigInteger& operator<<=(size_t shift) { + if (IsZero() || shift == 0) return *this; + + size_t offset = shift / kTypeBit; + size_t interShift = shift % kTypeBit; + RAPIDJSON_ASSERT(count_ + offset <= kCapacity); + + if (interShift == 0) { + std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type)); + count_ += offset; + } + else { + digits_[count_] = 0; + for (size_t i = count_; i > 0; i--) + digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift)); + digits_[offset] = digits_[0] << interShift; + count_ += offset; + if (digits_[count_]) + count_++; + } + + std::memset(digits_, 0, offset * sizeof(Type)); + + return *this; + } + + bool operator==(const BigInteger& rhs) const { + return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0; + } + + bool operator==(const Type rhs) const { + return count_ == 1 && digits_[0] == rhs; + } + + BigInteger& MultiplyPow5(unsigned exp) { + static const uint32_t kPow5[12] = { + 5, + 5 * 5, + 5 * 5 * 5, + 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 + }; + if (exp == 0) return *this; + for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27 + for (; exp >= 13; exp -= 13) *this *= static_cast(1220703125u); // 5^13 + if (exp > 0) *this *= kPow5[exp - 1]; + return *this; + } + + // Compute absolute difference of this and rhs. + // Assume this != rhs + bool Difference(const BigInteger& rhs, BigInteger* out) const { + int cmp = Compare(rhs); + RAPIDJSON_ASSERT(cmp != 0); + const BigInteger *a, *b; // Makes a > b + bool ret; + if (cmp < 0) { a = &rhs; b = this; ret = true; } + else { a = this; b = &rhs; ret = false; } + + Type borrow = 0; + for (size_t i = 0; i < a->count_; i++) { + Type d = a->digits_[i] - borrow; + if (i < b->count_) + d -= b->digits_[i]; + borrow = (d > a->digits_[i]) ? 1 : 0; + out->digits_[i] = d; + if (d != 0) + out->count_ = i + 1; + } + + return ret; + } + + int Compare(const BigInteger& rhs) const { + if (count_ != rhs.count_) + return count_ < rhs.count_ ? -1 : 1; + + for (size_t i = count_; i-- > 0;) + if (digits_[i] != rhs.digits_[i]) + return digits_[i] < rhs.digits_[i] ? -1 : 1; + + return 0; + } + + size_t GetCount() const { return count_; } + Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; } + bool IsZero() const { return count_ == 1 && digits_[0] == 0; } + +private: + void AppendDecimal64(const char* begin, const char* end) { + uint64_t u = ParseUint64(begin, end); + if (IsZero()) + *this = u; + else { + unsigned exp = static_cast(end - begin); + (MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u + } + } + + void PushBack(Type digit) { + RAPIDJSON_ASSERT(count_ < kCapacity); + digits_[count_++] = digit; + } + + static uint64_t ParseUint64(const char* begin, const char* end) { + uint64_t r = 0; + for (const char* p = begin; p != end; ++p) { + RAPIDJSON_ASSERT(*p >= '0' && *p <= '9'); + r = r * 10u + static_cast(*p - '0'); + } + return r; + } + + // Assume a * b + k < 2^128 + static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t low = _umul128(a, b, outHigh) + k; + if (low < k) + (*outHigh)++; + return low; +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) + __extension__ typedef unsigned __int128 uint128; + uint128 p = static_cast(a) * static_cast(b); + p += k; + *outHigh = static_cast(p >> 64); + return static_cast(p); +#else + const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32; + uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1; + x1 += (x0 >> 32); // can't give carry + x1 += x2; + if (x1 < x2) + x3 += (static_cast(1) << 32); + uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF); + uint64_t hi = x3 + (x1 >> 32); + + lo += k; + if (lo < k) + hi++; + *outHigh = hi; + return lo; +#endif + } + + static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000 + static const size_t kCapacity = kBitCount / sizeof(Type); + static const size_t kTypeBit = sizeof(Type) * 8; + + Type digits_[kCapacity]; + size_t count_; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_BIGINTEGER_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/diyfp.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/diyfp.h new file mode 100644 index 0000000000..c9fefdc613 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/diyfp.h @@ -0,0 +1,258 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DIYFP_H_ +#define RAPIDJSON_DIYFP_H_ + +#include "../rapidjson.h" + +#if defined(_MSC_VER) && defined(_M_AMD64) +#include +#pragma intrinsic(_BitScanReverse64) +#pragma intrinsic(_umul128) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +struct DiyFp { + DiyFp() : f(), e() {} + + DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {} + + explicit DiyFp(double d) { + union { + double d; + uint64_t u64; + } u = { d }; + + int biased_e = static_cast((u.u64 & kDpExponentMask) >> kDpSignificandSize); + uint64_t significand = (u.u64 & kDpSignificandMask); + if (biased_e != 0) { + f = significand + kDpHiddenBit; + e = biased_e - kDpExponentBias; + } + else { + f = significand; + e = kDpMinExponent + 1; + } + } + + DiyFp operator-(const DiyFp& rhs) const { + return DiyFp(f - rhs.f, e); + } + + DiyFp operator*(const DiyFp& rhs) const { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t h; + uint64_t l = _umul128(f, rhs.f, &h); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) + __extension__ typedef unsigned __int128 uint128; + uint128 p = static_cast(f) * static_cast(rhs.f); + uint64_t h = static_cast(p >> 64); + uint64_t l = static_cast(p); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#else + const uint64_t M32 = 0xFFFFFFFF; + const uint64_t a = f >> 32; + const uint64_t b = f & M32; + const uint64_t c = rhs.f >> 32; + const uint64_t d = rhs.f & M32; + const uint64_t ac = a * c; + const uint64_t bc = b * c; + const uint64_t ad = a * d; + const uint64_t bd = b * d; + uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32); + tmp += 1U << 31; /// mult_round + return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64); +#endif + } + + DiyFp Normalize() const { +#if defined(_MSC_VER) && defined(_M_AMD64) + unsigned long index; + _BitScanReverse64(&index, f); + return DiyFp(f << (63 - index), e - (63 - index)); +#elif defined(__GNUC__) && __GNUC__ >= 4 + int s = __builtin_clzll(f); + return DiyFp(f << s, e - s); +#else + DiyFp res = *this; + while (!(res.f & (static_cast(1) << 63))) { + res.f <<= 1; + res.e--; + } + return res; +#endif + } + + DiyFp NormalizeBoundary() const { + DiyFp res = *this; + while (!(res.f & (kDpHiddenBit << 1))) { + res.f <<= 1; + res.e--; + } + res.f <<= (kDiySignificandSize - kDpSignificandSize - 2); + res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2); + return res; + } + + void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const { + DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary(); + DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1); + mi.f <<= mi.e - pl.e; + mi.e = pl.e; + *plus = pl; + *minus = mi; + } + + double ToDouble() const { + union { + double d; + uint64_t u64; + }u; + const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : + static_cast(e + kDpExponentBias); + u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize); + return u.d; + } + + static const int kDiySignificandSize = 64; + static const int kDpSignificandSize = 52; + static const int kDpExponentBias = 0x3FF + kDpSignificandSize; + static const int kDpMaxExponent = 0x7FF - kDpExponentBias; + static const int kDpMinExponent = -kDpExponentBias; + static const int kDpDenormalExponent = -kDpExponentBias + 1; + static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + uint64_t f; + int e; +}; + +inline DiyFp GetCachedPowerByIndex(size_t index) { + // 10^-348, 10^-340, ..., 10^340 + static const uint64_t kCachedPowers_F[] = { + RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76), + RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea), + RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df), + RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f), + RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c), + RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5), + RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d), + RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637), + RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7), + RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5), + RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b), + RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996), + RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6), + RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8), + RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053), + RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd), + RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94), + RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b), + RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac), + RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3), + RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb), + RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c), + RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000), + RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984), + RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70), + RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245), + RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8), + RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a), + RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea), + RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85), + RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2), + RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3), + RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25), + RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece), + RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5), + RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a), + RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c), + RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a), + RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129), + RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429), + RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d), + RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841), + RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9), + RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b) + }; + static const int16_t kCachedPowers_E[] = { + -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, + -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, + -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, + -422, -396, -369, -343, -316, -289, -263, -236, -210, -183, + -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, + 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, + 375, 402, 428, 455, 481, 508, 534, 561, 588, 614, + 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, + 907, 933, 960, 986, 1013, 1039, 1066 + }; + return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]); +} + +inline DiyFp GetCachedPower(int e, int* K) { + + //int k = static_cast(ceil((-61 - e) * 0.30102999566398114)) + 374; + double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive + int k = static_cast(dk); + if (dk - k > 0.0) + k++; + + unsigned index = static_cast((k >> 3) + 1); + *K = -(-348 + static_cast(index << 3)); // decimal exponent no need lookup table + + return GetCachedPowerByIndex(index); +} + +inline DiyFp GetCachedPower10(int exp, int *outExp) { + unsigned index = (static_cast(exp) + 348u) / 8u; + *outExp = -348 + static_cast(index) * 8; + return GetCachedPowerByIndex(index); + } + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +RAPIDJSON_DIAG_OFF(padded) +#endif + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_DIYFP_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/dtoa.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/dtoa.h new file mode 100644 index 0000000000..8d6350e626 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/dtoa.h @@ -0,0 +1,245 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DTOA_ +#define RAPIDJSON_DTOA_ + +#include "itoa.h" // GetDigitsLut() +#include "diyfp.h" +#include "ieee754.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124 +#endif + +inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) { + while (rest < wp_w && delta - rest >= ten_kappa && + (rest + ten_kappa < wp_w || /// closer + wp_w - rest > rest + ten_kappa - wp_w)) { + buffer[len - 1]--; + rest += ten_kappa; + } +} + +inline unsigned CountDecimalDigit32(uint32_t n) { + // Simple pure C++ implementation was faster than __builtin_clz version in this situation. + if (n < 10) return 1; + if (n < 100) return 2; + if (n < 1000) return 3; + if (n < 10000) return 4; + if (n < 100000) return 5; + if (n < 1000000) return 6; + if (n < 10000000) return 7; + if (n < 100000000) return 8; + // Will not reach 10 digits in DigitGen() + //if (n < 1000000000) return 9; + //return 10; + return 9; +} + +inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) { + static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + const DiyFp one(uint64_t(1) << -Mp.e, Mp.e); + const DiyFp wp_w = Mp - W; + uint32_t p1 = static_cast(Mp.f >> -one.e); + uint64_t p2 = Mp.f & (one.f - 1); + unsigned kappa = CountDecimalDigit32(p1); // kappa in [0, 9] + *len = 0; + + while (kappa > 0) { + uint32_t d = 0; + switch (kappa) { + case 9: d = p1 / 100000000; p1 %= 100000000; break; + case 8: d = p1 / 10000000; p1 %= 10000000; break; + case 7: d = p1 / 1000000; p1 %= 1000000; break; + case 6: d = p1 / 100000; p1 %= 100000; break; + case 5: d = p1 / 10000; p1 %= 10000; break; + case 4: d = p1 / 1000; p1 %= 1000; break; + case 3: d = p1 / 100; p1 %= 100; break; + case 2: d = p1 / 10; p1 %= 10; break; + case 1: d = p1; p1 = 0; break; + default:; + } + if (d || *len) + buffer[(*len)++] = static_cast('0' + static_cast(d)); + kappa--; + uint64_t tmp = (static_cast(p1) << -one.e) + p2; + if (tmp <= delta) { + *K += kappa; + GrisuRound(buffer, *len, delta, tmp, static_cast(kPow10[kappa]) << -one.e, wp_w.f); + return; + } + } + + // kappa = 0 + for (;;) { + p2 *= 10; + delta *= 10; + char d = static_cast(p2 >> -one.e); + if (d || *len) + buffer[(*len)++] = static_cast('0' + d); + p2 &= one.f - 1; + kappa--; + if (p2 < delta) { + *K += kappa; + int index = -static_cast(kappa); + GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[-static_cast(kappa)] : 0)); + return; + } + } +} + +inline void Grisu2(double value, char* buffer, int* length, int* K) { + const DiyFp v(value); + DiyFp w_m, w_p; + v.NormalizedBoundaries(&w_m, &w_p); + + const DiyFp c_mk = GetCachedPower(w_p.e, K); + const DiyFp W = v.Normalize() * c_mk; + DiyFp Wp = w_p * c_mk; + DiyFp Wm = w_m * c_mk; + Wm.f++; + Wp.f--; + DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K); +} + +inline char* WriteExponent(int K, char* buffer) { + if (K < 0) { + *buffer++ = '-'; + K = -K; + } + + if (K >= 100) { + *buffer++ = static_cast('0' + static_cast(K / 100)); + K %= 100; + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else if (K >= 10) { + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else + *buffer++ = static_cast('0' + static_cast(K)); + + return buffer; +} + +inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) { + const int kk = length + k; // 10^(kk-1) <= v < 10^kk + + if (0 <= k && kk <= 21) { + // 1234e7 -> 12340000000 + for (int i = length; i < kk; i++) + buffer[i] = '0'; + buffer[kk] = '.'; + buffer[kk + 1] = '0'; + return &buffer[kk + 2]; + } + else if (0 < kk && kk <= 21) { + // 1234e-2 -> 12.34 + std::memmove(&buffer[kk + 1], &buffer[kk], static_cast(length - kk)); + buffer[kk] = '.'; + if (0 > k + maxDecimalPlaces) { + // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1 + // Remove extra trailing zeros (at least one) after truncation. + for (int i = kk + maxDecimalPlaces; i > kk + 1; i--) + if (buffer[i] != '0') + return &buffer[i + 1]; + return &buffer[kk + 2]; // Reserve one zero + } + else + return &buffer[length + 1]; + } + else if (-6 < kk && kk <= 0) { + // 1234e-6 -> 0.001234 + const int offset = 2 - kk; + std::memmove(&buffer[offset], &buffer[0], static_cast(length)); + buffer[0] = '0'; + buffer[1] = '.'; + for (int i = 2; i < offset; i++) + buffer[i] = '0'; + if (length - kk > maxDecimalPlaces) { + // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1 + // Remove extra trailing zeros (at least one) after truncation. + for (int i = maxDecimalPlaces + 1; i > 2; i--) + if (buffer[i] != '0') + return &buffer[i + 1]; + return &buffer[3]; // Reserve one zero + } + else + return &buffer[length + offset]; + } + else if (kk < -maxDecimalPlaces) { + // Truncate to zero + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + return &buffer[3]; + } + else if (length == 1) { + // 1e30 + buffer[1] = 'e'; + return WriteExponent(kk - 1, &buffer[2]); + } + else { + // 1234e30 -> 1.234e33 + std::memmove(&buffer[2], &buffer[1], static_cast(length - 1)); + buffer[1] = '.'; + buffer[length + 1] = 'e'; + return WriteExponent(kk - 1, &buffer[0 + length + 2]); + } +} + +inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) { + RAPIDJSON_ASSERT(maxDecimalPlaces >= 1); + Double d(value); + if (d.IsZero()) { + if (d.Sign()) + *buffer++ = '-'; // -0.0, Issue #289 + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + return &buffer[3]; + } + else { + if (value < 0) { + *buffer++ = '-'; + value = -value; + } + int length, K; + Grisu2(value, buffer, &length, &K); + return Prettify(buffer, length, K, maxDecimalPlaces); + } +} + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_DTOA_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/ieee754.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/ieee754.h new file mode 100644 index 0000000000..82bb0b99e5 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/ieee754.h @@ -0,0 +1,78 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_IEEE754_ +#define RAPIDJSON_IEEE754_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +class Double { +public: + Double() {} + Double(double d) : d_(d) {} + Double(uint64_t u) : u_(u) {} + + double Value() const { return d_; } + uint64_t Uint64Value() const { return u_; } + + double NextPositiveDouble() const { + RAPIDJSON_ASSERT(!Sign()); + return Double(u_ + 1).Value(); + } + + bool Sign() const { return (u_ & kSignMask) != 0; } + uint64_t Significand() const { return u_ & kSignificandMask; } + int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } + + bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } + bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } + bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; } + bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } + bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } + + uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } + int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } + uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } + + static unsigned EffectiveSignificandSize(int order) { + if (order >= -1021) + return 53; + else if (order <= -1074) + return 0; + else + return static_cast(order) + 1074; + } + +private: + static const int kSignificandSize = 52; + static const int kExponentBias = 0x3FF; + static const int kDenormalExponent = 1 - kExponentBias; + static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); + static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + union { + double d_; + uint64_t u_; + }; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_IEEE754_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/itoa.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/itoa.h new file mode 100644 index 0000000000..01a4e7e72d --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/itoa.h @@ -0,0 +1,304 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ITOA_ +#define RAPIDJSON_ITOA_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline const char* GetDigitsLut() { + static const char cDigitsLut[200] = { + '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', + '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9', + '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9', + '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9', + '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9', + '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9', + '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9', + '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9', + '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', + '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' + }; + return cDigitsLut; +} + +inline char* u32toa(uint32_t value, char* buffer) { + const char* cDigitsLut = GetDigitsLut(); + + if (value < 10000) { + const uint32_t d1 = (value / 100) << 1; + const uint32_t d2 = (value % 100) << 1; + + if (value >= 1000) + *buffer++ = cDigitsLut[d1]; + if (value >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else if (value < 100000000) { + // value = bbbbcccc + const uint32_t b = value / 10000; + const uint32_t c = value % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + else { + // value = aabbbbcccc in decimal + + const uint32_t a = value / 100000000; // 1 to 42 + value %= 100000000; + + if (a >= 10) { + const unsigned i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else + *buffer++ = static_cast('0' + static_cast(a)); + + const uint32_t b = value / 10000; // 0 to 9999 + const uint32_t c = value % 10000; // 0 to 9999 + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + return buffer; +} + +inline char* i32toa(int32_t value, char* buffer) { + uint32_t u = static_cast(value); + if (value < 0) { + *buffer++ = '-'; + u = ~u + 1; + } + + return u32toa(u, buffer); +} + +inline char* u64toa(uint64_t value, char* buffer) { + const char* cDigitsLut = GetDigitsLut(); + const uint64_t kTen8 = 100000000; + const uint64_t kTen9 = kTen8 * 10; + const uint64_t kTen10 = kTen8 * 100; + const uint64_t kTen11 = kTen8 * 1000; + const uint64_t kTen12 = kTen8 * 10000; + const uint64_t kTen13 = kTen8 * 100000; + const uint64_t kTen14 = kTen8 * 1000000; + const uint64_t kTen15 = kTen8 * 10000000; + const uint64_t kTen16 = kTen8 * kTen8; + + if (value < kTen8) { + uint32_t v = static_cast(value); + if (v < 10000) { + const uint32_t d1 = (v / 100) << 1; + const uint32_t d2 = (v % 100) << 1; + + if (v >= 1000) + *buffer++ = cDigitsLut[d1]; + if (v >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (v >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else { + // value = bbbbcccc + const uint32_t b = v / 10000; + const uint32_t c = v % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + } + else if (value < kTen16) { + const uint32_t v0 = static_cast(value / kTen8); + const uint32_t v1 = static_cast(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + if (value >= kTen15) + *buffer++ = cDigitsLut[d1]; + if (value >= kTen14) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= kTen13) + *buffer++ = cDigitsLut[d2]; + if (value >= kTen12) + *buffer++ = cDigitsLut[d2 + 1]; + if (value >= kTen11) + *buffer++ = cDigitsLut[d3]; + if (value >= kTen10) + *buffer++ = cDigitsLut[d3 + 1]; + if (value >= kTen9) + *buffer++ = cDigitsLut[d4]; + if (value >= kTen8) + *buffer++ = cDigitsLut[d4 + 1]; + + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + else { + const uint32_t a = static_cast(value / kTen16); // 1 to 1844 + value %= kTen16; + + if (a < 10) + *buffer++ = static_cast('0' + static_cast(a)); + else if (a < 100) { + const uint32_t i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else if (a < 1000) { + *buffer++ = static_cast('0' + static_cast(a / 100)); + + const uint32_t i = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else { + const uint32_t i = (a / 100) << 1; + const uint32_t j = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + *buffer++ = cDigitsLut[j]; + *buffer++ = cDigitsLut[j + 1]; + } + + const uint32_t v0 = static_cast(value / kTen8); + const uint32_t v1 = static_cast(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + + return buffer; +} + +inline char* i64toa(int64_t value, char* buffer) { + uint64_t u = static_cast(value); + if (value < 0) { + *buffer++ = '-'; + u = ~u + 1; + } + + return u64toa(u, buffer); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ITOA_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/meta.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/meta.h new file mode 100644 index 0000000000..5a9aaa4286 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/meta.h @@ -0,0 +1,181 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_META_H_ +#define RAPIDJSON_INTERNAL_META_H_ + +#include "../rapidjson.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif +#if defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(6334) +#endif + +#if RAPIDJSON_HAS_CXX11_TYPETRAITS +#include +#endif + +//@cond RAPIDJSON_INTERNAL +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching +template struct Void { typedef void Type; }; + +/////////////////////////////////////////////////////////////////////////////// +// BoolType, TrueType, FalseType +// +template struct BoolType { + static const bool Value = Cond; + typedef BoolType Type; +}; +typedef BoolType TrueType; +typedef BoolType FalseType; + + +/////////////////////////////////////////////////////////////////////////////// +// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr +// + +template struct SelectIfImpl { template struct Apply { typedef T1 Type; }; }; +template <> struct SelectIfImpl { template struct Apply { typedef T2 Type; }; }; +template struct SelectIfCond : SelectIfImpl::template Apply {}; +template struct SelectIf : SelectIfCond {}; + +template struct AndExprCond : FalseType {}; +template <> struct AndExprCond : TrueType {}; +template struct OrExprCond : TrueType {}; +template <> struct OrExprCond : FalseType {}; + +template struct BoolExpr : SelectIf::Type {}; +template struct NotExpr : SelectIf::Type {}; +template struct AndExpr : AndExprCond::Type {}; +template struct OrExpr : OrExprCond::Type {}; + + +/////////////////////////////////////////////////////////////////////////////// +// AddConst, MaybeAddConst, RemoveConst +template struct AddConst { typedef const T Type; }; +template struct MaybeAddConst : SelectIfCond {}; +template struct RemoveConst { typedef T Type; }; +template struct RemoveConst { typedef T Type; }; + + +/////////////////////////////////////////////////////////////////////////////// +// IsSame, IsConst, IsMoreConst, IsPointer +// +template struct IsSame : FalseType {}; +template struct IsSame : TrueType {}; + +template struct IsConst : FalseType {}; +template struct IsConst : TrueType {}; + +template +struct IsMoreConst + : AndExpr::Type, typename RemoveConst::Type>, + BoolType::Value >= IsConst::Value> >::Type {}; + +template struct IsPointer : FalseType {}; +template struct IsPointer : TrueType {}; + +/////////////////////////////////////////////////////////////////////////////// +// IsBaseOf +// +#if RAPIDJSON_HAS_CXX11_TYPETRAITS + +template struct IsBaseOf + : BoolType< ::std::is_base_of::value> {}; + +#else // simplified version adopted from Boost + +template struct IsBaseOfImpl { + RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0); + RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0); + + typedef char (&Yes)[1]; + typedef char (&No) [2]; + + template + static Yes Check(const D*, T); + static No Check(const B*, int); + + struct Host { + operator const B*() const; + operator const D*(); + }; + + enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) }; +}; + +template struct IsBaseOf + : OrExpr, BoolExpr > >::Type {}; + +#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS + + +////////////////////////////////////////////////////////////////////////// +// EnableIf / DisableIf +// +template struct EnableIfCond { typedef T Type; }; +template struct EnableIfCond { /* empty */ }; + +template struct DisableIfCond { typedef T Type; }; +template struct DisableIfCond { /* empty */ }; + +template +struct EnableIf : EnableIfCond {}; + +template +struct DisableIf : DisableIfCond {}; + +// SFINAE helpers +struct SfinaeTag {}; +template struct RemoveSfinaeTag; +template struct RemoveSfinaeTag { typedef T Type; }; + +#define RAPIDJSON_REMOVEFPTR_(type) \ + typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \ + < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type + +#define RAPIDJSON_ENABLEIF(cond) \ + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ + ::Type * = NULL + +#define RAPIDJSON_DISABLEIF(cond) \ + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ + ::Type * = NULL + +#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \ + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ + ::Type + +#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ + ::Type + +} // namespace internal +RAPIDJSON_NAMESPACE_END +//@endcond + +#if defined(__GNUC__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_META_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/pow10.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/pow10.h new file mode 100644 index 0000000000..02f475d705 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/pow10.h @@ -0,0 +1,55 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_POW10_ +#define RAPIDJSON_POW10_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Computes integer powers of 10 in double (10.0^n). +/*! This function uses lookup table for fast and accurate results. + \param n non-negative exponent. Must <= 308. + \return 10.0^n +*/ +inline double Pow10(int n) { + static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes + 1e+0, + 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, + 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, + 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, + 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, + 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, + 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, + 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, + 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, + 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, + 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, + 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, + 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, + 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, + 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, + 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 + }; + RAPIDJSON_ASSERT(n >= 0 && n <= 308); + return e[n]; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_POW10_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/regex.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/regex.h new file mode 100644 index 0000000000..422a5240bf --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/regex.h @@ -0,0 +1,701 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_REGEX_H_ +#define RAPIDJSON_INTERNAL_REGEX_H_ + +#include "../allocators.h" +#include "../stream.h" +#include "stack.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(implicit-fallthrough) +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +#ifndef RAPIDJSON_REGEX_VERBOSE +#define RAPIDJSON_REGEX_VERBOSE 0 +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +/////////////////////////////////////////////////////////////////////////////// +// GenericRegex + +static const SizeType kRegexInvalidState = ~SizeType(0); //!< Represents an invalid index in GenericRegex::State::out, out1 +static const SizeType kRegexInvalidRange = ~SizeType(0); + +//! Regular expression engine with subset of ECMAscript grammar. +/*! + Supported regular expression syntax: + - \c ab Concatenation + - \c a|b Alternation + - \c a? Zero or one + - \c a* Zero or more + - \c a+ One or more + - \c a{3} Exactly 3 times + - \c a{3,} At least 3 times + - \c a{3,5} 3 to 5 times + - \c (ab) Grouping + - \c ^a At the beginning + - \c a$ At the end + - \c . Any character + - \c [abc] Character classes + - \c [a-c] Character class range + - \c [a-z0-9_] Character class combination + - \c [^abc] Negated character classes + - \c [^a-c] Negated character class range + - \c [\b] Backspace (U+0008) + - \c \\| \\\\ ... Escape characters + - \c \\f Form feed (U+000C) + - \c \\n Line feed (U+000A) + - \c \\r Carriage return (U+000D) + - \c \\t Tab (U+0009) + - \c \\v Vertical tab (U+000B) + + \note This is a Thompson NFA engine, implemented with reference to + Cox, Russ. "Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby,...).", + https://swtch.com/~rsc/regexp/regexp1.html +*/ +template +class GenericRegex { +public: + typedef typename Encoding::Ch Ch; + + GenericRegex(const Ch* source, Allocator* allocator = 0) : + states_(allocator, 256), ranges_(allocator, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(), + stateSet_(), state0_(allocator, 0), state1_(allocator, 0), anchorBegin_(), anchorEnd_() + { + GenericStringStream ss(source); + DecodedStream > ds(ss); + Parse(ds); + } + + ~GenericRegex() { + Allocator::Free(stateSet_); + } + + bool IsValid() const { + return root_ != kRegexInvalidState; + } + + template + bool Match(InputStream& is) const { + return SearchWithAnchoring(is, true, true); + } + + bool Match(const Ch* s) const { + GenericStringStream is(s); + return Match(is); + } + + template + bool Search(InputStream& is) const { + return SearchWithAnchoring(is, anchorBegin_, anchorEnd_); + } + + bool Search(const Ch* s) const { + GenericStringStream is(s); + return Search(is); + } + +private: + enum Operator { + kZeroOrOne, + kZeroOrMore, + kOneOrMore, + kConcatenation, + kAlternation, + kLeftParenthesis + }; + + static const unsigned kAnyCharacterClass = 0xFFFFFFFF; //!< For '.' + static const unsigned kRangeCharacterClass = 0xFFFFFFFE; + static const unsigned kRangeNegationFlag = 0x80000000; + + struct Range { + unsigned start; // + unsigned end; + SizeType next; + }; + + struct State { + SizeType out; //!< Equals to kInvalid for matching state + SizeType out1; //!< Equals to non-kInvalid for split + SizeType rangeStart; + unsigned codepoint; + }; + + struct Frag { + Frag(SizeType s, SizeType o, SizeType m) : start(s), out(o), minIndex(m) {} + SizeType start; + SizeType out; //!< link-list of all output states + SizeType minIndex; + }; + + template + class DecodedStream { + public: + DecodedStream(SourceStream& ss) : ss_(ss), codepoint_() { Decode(); } + unsigned Peek() { return codepoint_; } + unsigned Take() { + unsigned c = codepoint_; + if (c) // No further decoding when '\0' + Decode(); + return c; + } + + private: + void Decode() { + if (!Encoding::Decode(ss_, &codepoint_)) + codepoint_ = 0; + } + + SourceStream& ss_; + unsigned codepoint_; + }; + + State& GetState(SizeType index) { + RAPIDJSON_ASSERT(index < stateCount_); + return states_.template Bottom()[index]; + } + + const State& GetState(SizeType index) const { + RAPIDJSON_ASSERT(index < stateCount_); + return states_.template Bottom()[index]; + } + + Range& GetRange(SizeType index) { + RAPIDJSON_ASSERT(index < rangeCount_); + return ranges_.template Bottom()[index]; + } + + const Range& GetRange(SizeType index) const { + RAPIDJSON_ASSERT(index < rangeCount_); + return ranges_.template Bottom()[index]; + } + + template + void Parse(DecodedStream& ds) { + Allocator allocator; + Stack operandStack(&allocator, 256); // Frag + Stack operatorStack(&allocator, 256); // Operator + Stack atomCountStack(&allocator, 256); // unsigned (Atom per parenthesis) + + *atomCountStack.template Push() = 0; + + unsigned codepoint; + while (ds.Peek() != 0) { + switch (codepoint = ds.Take()) { + case '^': + anchorBegin_ = true; + break; + + case '$': + anchorEnd_ = true; + break; + + case '|': + while (!operatorStack.Empty() && *operatorStack.template Top() < kAlternation) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + *operatorStack.template Push() = kAlternation; + *atomCountStack.template Top() = 0; + break; + + case '(': + *operatorStack.template Push() = kLeftParenthesis; + *atomCountStack.template Push() = 0; + break; + + case ')': + while (!operatorStack.Empty() && *operatorStack.template Top() != kLeftParenthesis) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + if (operatorStack.Empty()) + return; + operatorStack.template Pop(1); + atomCountStack.template Pop(1); + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '?': + if (!Eval(operandStack, kZeroOrOne)) + return; + break; + + case '*': + if (!Eval(operandStack, kZeroOrMore)) + return; + break; + + case '+': + if (!Eval(operandStack, kOneOrMore)) + return; + break; + + case '{': + { + unsigned n, m; + if (!ParseUnsigned(ds, &n)) + return; + + if (ds.Peek() == ',') { + ds.Take(); + if (ds.Peek() == '}') + m = kInfinityQuantifier; + else if (!ParseUnsigned(ds, &m) || m < n) + return; + } + else + m = n; + + if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}') + return; + ds.Take(); + } + break; + + case '.': + PushOperand(operandStack, kAnyCharacterClass); + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '[': + { + SizeType range; + if (!ParseRange(ds, &range)) + return; + SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, kRangeCharacterClass); + GetState(s).rangeStart = range; + *operandStack.template Push() = Frag(s, s, s); + } + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '\\': // Escape character + if (!CharacterEscape(ds, &codepoint)) + return; // Unsupported escape character + // fall through to default + + default: // Pattern character + PushOperand(operandStack, codepoint); + ImplicitConcatenation(atomCountStack, operatorStack); + } + } + + while (!operatorStack.Empty()) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + + // Link the operand to matching state. + if (operandStack.GetSize() == sizeof(Frag)) { + Frag* e = operandStack.template Pop(1); + Patch(e->out, NewState(kRegexInvalidState, kRegexInvalidState, 0)); + root_ = e->start; + +#if RAPIDJSON_REGEX_VERBOSE + printf("root: %d\n", root_); + for (SizeType i = 0; i < stateCount_ ; i++) { + State& s = GetState(i); + printf("[%2d] out: %2d out1: %2d c: '%c'\n", i, s.out, s.out1, (char)s.codepoint); + } + printf("\n"); +#endif + } + + // Preallocate buffer for SearchWithAnchoring() + RAPIDJSON_ASSERT(stateSet_ == 0); + if (stateCount_ > 0) { + stateSet_ = static_cast(states_.GetAllocator().Malloc(GetStateSetSize())); + state0_.template Reserve(stateCount_); + state1_.template Reserve(stateCount_); + } + } + + SizeType NewState(SizeType out, SizeType out1, unsigned codepoint) { + State* s = states_.template Push(); + s->out = out; + s->out1 = out1; + s->codepoint = codepoint; + s->rangeStart = kRegexInvalidRange; + return stateCount_++; + } + + void PushOperand(Stack& operandStack, unsigned codepoint) { + SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, codepoint); + *operandStack.template Push() = Frag(s, s, s); + } + + void ImplicitConcatenation(Stack& atomCountStack, Stack& operatorStack) { + if (*atomCountStack.template Top()) + *operatorStack.template Push() = kConcatenation; + (*atomCountStack.template Top())++; + } + + SizeType Append(SizeType l1, SizeType l2) { + SizeType old = l1; + while (GetState(l1).out != kRegexInvalidState) + l1 = GetState(l1).out; + GetState(l1).out = l2; + return old; + } + + void Patch(SizeType l, SizeType s) { + for (SizeType next; l != kRegexInvalidState; l = next) { + next = GetState(l).out; + GetState(l).out = s; + } + } + + bool Eval(Stack& operandStack, Operator op) { + switch (op) { + case kConcatenation: + RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag) * 2); + { + Frag e2 = *operandStack.template Pop(1); + Frag e1 = *operandStack.template Pop(1); + Patch(e1.out, e2.start); + *operandStack.template Push() = Frag(e1.start, e2.out, Min(e1.minIndex, e2.minIndex)); + } + return true; + + case kAlternation: + if (operandStack.GetSize() >= sizeof(Frag) * 2) { + Frag e2 = *operandStack.template Pop(1); + Frag e1 = *operandStack.template Pop(1); + SizeType s = NewState(e1.start, e2.start, 0); + *operandStack.template Push() = Frag(s, Append(e1.out, e2.out), Min(e1.minIndex, e2.minIndex)); + return true; + } + return false; + + case kZeroOrOne: + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + *operandStack.template Push() = Frag(s, Append(e.out, s), e.minIndex); + return true; + } + return false; + + case kZeroOrMore: + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + Patch(e.out, s); + *operandStack.template Push() = Frag(s, s, e.minIndex); + return true; + } + return false; + + default: + RAPIDJSON_ASSERT(op == kOneOrMore); + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + Patch(e.out, s); + *operandStack.template Push() = Frag(e.start, s, e.minIndex); + return true; + } + return false; + } + } + + bool EvalQuantifier(Stack& operandStack, unsigned n, unsigned m) { + RAPIDJSON_ASSERT(n <= m); + RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag)); + + if (n == 0) { + if (m == 0) // a{0} not support + return false; + else if (m == kInfinityQuantifier) + Eval(operandStack, kZeroOrMore); // a{0,} -> a* + else { + Eval(operandStack, kZeroOrOne); // a{0,5} -> a? + for (unsigned i = 0; i < m - 1; i++) + CloneTopOperand(operandStack); // a{0,5} -> a? a? a? a? a? + for (unsigned i = 0; i < m - 1; i++) + Eval(operandStack, kConcatenation); // a{0,5} -> a?a?a?a?a? + } + return true; + } + + for (unsigned i = 0; i < n - 1; i++) // a{3} -> a a a + CloneTopOperand(operandStack); + + if (m == kInfinityQuantifier) + Eval(operandStack, kOneOrMore); // a{3,} -> a a a+ + else if (m > n) { + CloneTopOperand(operandStack); // a{3,5} -> a a a a + Eval(operandStack, kZeroOrOne); // a{3,5} -> a a a a? + for (unsigned i = n; i < m - 1; i++) + CloneTopOperand(operandStack); // a{3,5} -> a a a a? a? + for (unsigned i = n; i < m; i++) + Eval(operandStack, kConcatenation); // a{3,5} -> a a aa?a? + } + + for (unsigned i = 0; i < n - 1; i++) + Eval(operandStack, kConcatenation); // a{3} -> aaa, a{3,} -> aaa+, a{3.5} -> aaaa?a? + + return true; + } + + static SizeType Min(SizeType a, SizeType b) { return a < b ? a : b; } + + void CloneTopOperand(Stack& operandStack) { + const Frag src = *operandStack.template Top(); // Copy constructor to prevent invalidation + SizeType count = stateCount_ - src.minIndex; // Assumes top operand contains states in [src->minIndex, stateCount_) + State* s = states_.template Push(count); + memcpy(s, &GetState(src.minIndex), count * sizeof(State)); + for (SizeType j = 0; j < count; j++) { + if (s[j].out != kRegexInvalidState) + s[j].out += count; + if (s[j].out1 != kRegexInvalidState) + s[j].out1 += count; + } + *operandStack.template Push() = Frag(src.start + count, src.out + count, src.minIndex + count); + stateCount_ += count; + } + + template + bool ParseUnsigned(DecodedStream& ds, unsigned* u) { + unsigned r = 0; + if (ds.Peek() < '0' || ds.Peek() > '9') + return false; + while (ds.Peek() >= '0' && ds.Peek() <= '9') { + if (r >= 429496729 && ds.Peek() > '5') // 2^32 - 1 = 4294967295 + return false; // overflow + r = r * 10 + (ds.Take() - '0'); + } + *u = r; + return true; + } + + template + bool ParseRange(DecodedStream& ds, SizeType* range) { + bool isBegin = true; + bool negate = false; + int step = 0; + SizeType start = kRegexInvalidRange; + SizeType current = kRegexInvalidRange; + unsigned codepoint; + while ((codepoint = ds.Take()) != 0) { + if (isBegin) { + isBegin = false; + if (codepoint == '^') { + negate = true; + continue; + } + } + + switch (codepoint) { + case ']': + if (start == kRegexInvalidRange) + return false; // Error: nothing inside [] + if (step == 2) { // Add trailing '-' + SizeType r = NewRange('-'); + RAPIDJSON_ASSERT(current != kRegexInvalidRange); + GetRange(current).next = r; + } + if (negate) + GetRange(start).start |= kRangeNegationFlag; + *range = start; + return true; + + case '\\': + if (ds.Peek() == 'b') { + ds.Take(); + codepoint = 0x0008; // Escape backspace character + } + else if (!CharacterEscape(ds, &codepoint)) + return false; + // fall through to default + + default: + switch (step) { + case 1: + if (codepoint == '-') { + step++; + break; + } + // fall through to step 0 for other characters + + case 0: + { + SizeType r = NewRange(codepoint); + if (current != kRegexInvalidRange) + GetRange(current).next = r; + if (start == kRegexInvalidRange) + start = r; + current = r; + } + step = 1; + break; + + default: + RAPIDJSON_ASSERT(step == 2); + GetRange(current).end = codepoint; + step = 0; + } + } + } + return false; + } + + SizeType NewRange(unsigned codepoint) { + Range* r = ranges_.template Push(); + r->start = r->end = codepoint; + r->next = kRegexInvalidRange; + return rangeCount_++; + } + + template + bool CharacterEscape(DecodedStream& ds, unsigned* escapedCodepoint) { + unsigned codepoint; + switch (codepoint = ds.Take()) { + case '^': + case '$': + case '|': + case '(': + case ')': + case '?': + case '*': + case '+': + case '.': + case '[': + case ']': + case '{': + case '}': + case '\\': + *escapedCodepoint = codepoint; return true; + case 'f': *escapedCodepoint = 0x000C; return true; + case 'n': *escapedCodepoint = 0x000A; return true; + case 'r': *escapedCodepoint = 0x000D; return true; + case 't': *escapedCodepoint = 0x0009; return true; + case 'v': *escapedCodepoint = 0x000B; return true; + default: + return false; // Unsupported escape character + } + } + + template + bool SearchWithAnchoring(InputStream& is, bool anchorBegin, bool anchorEnd) const { + RAPIDJSON_ASSERT(IsValid()); + DecodedStream ds(is); + + state0_.Clear(); + Stack *current = &state0_, *next = &state1_; + const size_t stateSetSize = GetStateSetSize(); + std::memset(stateSet_, 0, stateSetSize); + + bool matched = AddState(*current, root_); + unsigned codepoint; + while (!current->Empty() && (codepoint = ds.Take()) != 0) { + std::memset(stateSet_, 0, stateSetSize); + next->Clear(); + matched = false; + for (const SizeType* s = current->template Bottom(); s != current->template End(); ++s) { + const State& sr = GetState(*s); + if (sr.codepoint == codepoint || + sr.codepoint == kAnyCharacterClass || + (sr.codepoint == kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint))) + { + matched = AddState(*next, sr.out) || matched; + if (!anchorEnd && matched) + return true; + } + if (!anchorBegin) + AddState(*next, root_); + } + internal::Swap(current, next); + } + + return matched; + } + + size_t GetStateSetSize() const { + return (stateCount_ + 31) / 32 * 4; + } + + // Return whether the added states is a match state + bool AddState(Stack& l, SizeType index) const { + RAPIDJSON_ASSERT(index != kRegexInvalidState); + + const State& s = GetState(index); + if (s.out1 != kRegexInvalidState) { // Split + bool matched = AddState(l, s.out); + return AddState(l, s.out1) || matched; + } + else if (!(stateSet_[index >> 5] & (1 << (index & 31)))) { + stateSet_[index >> 5] |= (1 << (index & 31)); + *l.template PushUnsafe() = index; + } + return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation. + } + + bool MatchRange(SizeType rangeIndex, unsigned codepoint) const { + bool yes = (GetRange(rangeIndex).start & kRangeNegationFlag) == 0; + while (rangeIndex != kRegexInvalidRange) { + const Range& r = GetRange(rangeIndex); + if (codepoint >= (r.start & ~kRangeNegationFlag) && codepoint <= r.end) + return yes; + rangeIndex = r.next; + } + return !yes; + } + + Stack states_; + Stack ranges_; + SizeType root_; + SizeType stateCount_; + SizeType rangeCount_; + + static const unsigned kInfinityQuantifier = ~0u; + + // For SearchWithAnchoring() + uint32_t* stateSet_; // allocated by states_.GetAllocator() + mutable Stack state0_; + mutable Stack state1_; + bool anchorBegin_; + bool anchorEnd_; +}; + +typedef GenericRegex > Regex; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_REGEX_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/stack.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/stack.h new file mode 100644 index 0000000000..022c9aab41 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/stack.h @@ -0,0 +1,230 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_STACK_H_ +#define RAPIDJSON_INTERNAL_STACK_H_ + +#include "../allocators.h" +#include "swap.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +/////////////////////////////////////////////////////////////////////////////// +// Stack + +//! A type-unsafe stack for storing different types of data. +/*! \tparam Allocator Allocator for allocating stack memory. +*/ +template +class Stack { +public: + // Optimization note: Do not allocate memory for stack_ in constructor. + // Do it lazily when first Push() -> Expand() -> Resize(). + Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) { + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Stack(Stack&& rhs) + : allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + stack_(rhs.stack_), + stackTop_(rhs.stackTop_), + stackEnd_(rhs.stackEnd_), + initialCapacity_(rhs.initialCapacity_) + { + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.stack_ = 0; + rhs.stackTop_ = 0; + rhs.stackEnd_ = 0; + rhs.initialCapacity_ = 0; + } +#endif + + ~Stack() { + Destroy(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Stack& operator=(Stack&& rhs) { + if (&rhs != this) + { + Destroy(); + + allocator_ = rhs.allocator_; + ownAllocator_ = rhs.ownAllocator_; + stack_ = rhs.stack_; + stackTop_ = rhs.stackTop_; + stackEnd_ = rhs.stackEnd_; + initialCapacity_ = rhs.initialCapacity_; + + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.stack_ = 0; + rhs.stackTop_ = 0; + rhs.stackEnd_ = 0; + rhs.initialCapacity_ = 0; + } + return *this; + } +#endif + + void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT { + internal::Swap(allocator_, rhs.allocator_); + internal::Swap(ownAllocator_, rhs.ownAllocator_); + internal::Swap(stack_, rhs.stack_); + internal::Swap(stackTop_, rhs.stackTop_); + internal::Swap(stackEnd_, rhs.stackEnd_); + internal::Swap(initialCapacity_, rhs.initialCapacity_); + } + + void Clear() { stackTop_ = stack_; } + + void ShrinkToFit() { + if (Empty()) { + // If the stack is empty, completely deallocate the memory. + Allocator::Free(stack_); + stack_ = 0; + stackTop_ = 0; + stackEnd_ = 0; + } + else + Resize(GetSize()); + } + + // Optimization note: try to minimize the size of this function for force inline. + // Expansion is run very infrequently, so it is moved to another (probably non-inline) function. + template + RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) { + // Expand the stack if needed + if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_)) + Expand(count); + } + + template + RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { + Reserve(count); + return PushUnsafe(count); + } + + template + RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) { + RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_); + T* ret = reinterpret_cast(stackTop_); + stackTop_ += sizeof(T) * count; + return ret; + } + + template + T* Pop(size_t count) { + RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); + stackTop_ -= count * sizeof(T); + return reinterpret_cast(stackTop_); + } + + template + T* Top() { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return reinterpret_cast(stackTop_ - sizeof(T)); + } + + template + const T* Top() const { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return reinterpret_cast(stackTop_ - sizeof(T)); + } + + template + T* End() { return reinterpret_cast(stackTop_); } + + template + const T* End() const { return reinterpret_cast(stackTop_); } + + template + T* Bottom() { return reinterpret_cast(stack_); } + + template + const T* Bottom() const { return reinterpret_cast(stack_); } + + bool HasAllocator() const { + return allocator_ != 0; + } + + Allocator& GetAllocator() { + RAPIDJSON_ASSERT(allocator_); + return *allocator_; + } + + bool Empty() const { return stackTop_ == stack_; } + size_t GetSize() const { return static_cast(stackTop_ - stack_); } + size_t GetCapacity() const { return static_cast(stackEnd_ - stack_); } + +private: + template + void Expand(size_t count) { + // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity. + size_t newCapacity; + if (stack_ == 0) { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + newCapacity = initialCapacity_; + } else { + newCapacity = GetCapacity(); + newCapacity += (newCapacity + 1) / 2; + } + size_t newSize = GetSize() + sizeof(T) * count; + if (newCapacity < newSize) + newCapacity = newSize; + + Resize(newCapacity); + } + + void Resize(size_t newCapacity) { + const size_t size = GetSize(); // Backup the current size + stack_ = static_cast(allocator_->Realloc(stack_, GetCapacity(), newCapacity)); + stackTop_ = stack_ + size; + stackEnd_ = stack_ + newCapacity; + } + + void Destroy() { + Allocator::Free(stack_); + RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack + } + + // Prohibit copy constructor & assignment operator. + Stack(const Stack&); + Stack& operator=(const Stack&); + + Allocator* allocator_; + Allocator* ownAllocator_; + char *stack_; + char *stackTop_; + char *stackEnd_; + size_t initialCapacity_; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_STACK_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/strfunc.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/strfunc.h new file mode 100644 index 0000000000..2edfae5267 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/strfunc.h @@ -0,0 +1,55 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ +#define RAPIDJSON_INTERNAL_STRFUNC_H_ + +#include "../stream.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Custom strlen() which works on different character types. +/*! \tparam Ch Character type (e.g. char, wchar_t, short) + \param s Null-terminated input string. + \return Number of characters in the string. + \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. +*/ +template +inline SizeType StrLen(const Ch* s) { + const Ch* p = s; + while (*p) ++p; + return SizeType(p - s); +} + +//! Returns number of code points in a encoded string. +template +bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { + GenericStringStream is(s); + const typename Encoding::Ch* end = s + length; + SizeType count = 0; + while (is.src_ < end) { + unsigned codepoint; + if (!Encoding::Decode(is, &codepoint)) + return false; + count++; + } + *outCount = count; + return true; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_INTERNAL_STRFUNC_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/strtod.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/strtod.h new file mode 100644 index 0000000000..289c413b07 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/strtod.h @@ -0,0 +1,269 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_STRTOD_ +#define RAPIDJSON_STRTOD_ + +#include "ieee754.h" +#include "biginteger.h" +#include "diyfp.h" +#include "pow10.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline double FastPath(double significand, int exp) { + if (exp < -308) + return 0.0; + else if (exp >= 0) + return significand * internal::Pow10(exp); + else + return significand / internal::Pow10(-exp); +} + +inline double StrtodNormalPrecision(double d, int p) { + if (p < -308) { + // Prevent expSum < -308, making Pow10(p) = 0 + d = FastPath(d, -308); + d = FastPath(d, p + 308); + } + else + d = FastPath(d, p); + return d; +} + +template +inline T Min3(T a, T b, T c) { + T m = a; + if (m > b) m = b; + if (m > c) m = c; + return m; +} + +inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) { + const Double db(b); + const uint64_t bInt = db.IntegerSignificand(); + const int bExp = db.IntegerExponent(); + const int hExp = bExp - 1; + + int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0; + + // Adjust for decimal exponent + if (dExp >= 0) { + dS_Exp2 += dExp; + dS_Exp5 += dExp; + } + else { + bS_Exp2 -= dExp; + bS_Exp5 -= dExp; + hS_Exp2 -= dExp; + hS_Exp5 -= dExp; + } + + // Adjust for binary exponent + if (bExp >= 0) + bS_Exp2 += bExp; + else { + dS_Exp2 -= bExp; + hS_Exp2 -= bExp; + } + + // Adjust for half ulp exponent + if (hExp >= 0) + hS_Exp2 += hExp; + else { + dS_Exp2 -= hExp; + bS_Exp2 -= hExp; + } + + // Remove common power of two factor from all three scaled values + int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2); + dS_Exp2 -= common_Exp2; + bS_Exp2 -= common_Exp2; + hS_Exp2 -= common_Exp2; + + BigInteger dS = d; + dS.MultiplyPow5(static_cast(dS_Exp5)) <<= static_cast(dS_Exp2); + + BigInteger bS(bInt); + bS.MultiplyPow5(static_cast(bS_Exp5)) <<= static_cast(bS_Exp2); + + BigInteger hS(1); + hS.MultiplyPow5(static_cast(hS_Exp5)) <<= static_cast(hS_Exp2); + + BigInteger delta(0); + dS.Difference(bS, &delta); + + return delta.Compare(hS); +} + +inline bool StrtodFast(double d, int p, double* result) { + // Use fast path for string-to-double conversion if possible + // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + if (p > 22 && p < 22 + 16) { + // Fast Path Cases In Disguise + d *= internal::Pow10(p - 22); + p = 22; + } + + if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1 + *result = FastPath(d, p); + return true; + } + else + return false; +} + +// Compute an approximation and see if it is within 1/2 ULP +inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) { + uint64_t significand = 0; + size_t i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999 + for (; i < length; i++) { + if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || + (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5')) + break; + significand = significand * 10u + static_cast(decimals[i] - '0'); + } + + if (i < length && decimals[i] >= '5') // Rounding + significand++; + + size_t remaining = length - i; + const unsigned kUlpShift = 3; + const unsigned kUlp = 1 << kUlpShift; + int64_t error = (remaining == 0) ? 0 : kUlp / 2; + + DiyFp v(significand, 0); + v = v.Normalize(); + error <<= -v.e; + + const int dExp = static_cast(decimalPosition) - static_cast(i) + exp; + + int actualExp; + DiyFp cachedPower = GetCachedPower10(dExp, &actualExp); + if (actualExp != dExp) { + static const DiyFp kPow10[] = { + DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60), // 10^1 + DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57), // 10^2 + DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54), // 10^3 + DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50), // 10^4 + DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47), // 10^5 + DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6 + DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7 + }; + int adjustment = dExp - actualExp - 1; + RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7); + v = v * kPow10[adjustment]; + if (length + static_cast(adjustment)> 19u) // has more digits than decimal digits in 64-bit + error += kUlp / 2; + } + + v = v * cachedPower; + + error += kUlp + (error == 0 ? 0 : 1); + + const int oldExp = v.e; + v = v.Normalize(); + error <<= oldExp - v.e; + + const unsigned effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); + unsigned precisionSize = 64 - effectiveSignificandSize; + if (precisionSize + kUlpShift >= 64) { + unsigned scaleExp = (precisionSize + kUlpShift) - 63; + v.f >>= scaleExp; + v.e += scaleExp; + error = (error >> scaleExp) + 1 + static_cast(kUlp); + precisionSize -= scaleExp; + } + + DiyFp rounded(v.f >> precisionSize, v.e + static_cast(precisionSize)); + const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp; + const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp; + if (precisionBits >= halfWay + static_cast(error)) { + rounded.f++; + if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340) + rounded.f >>= 1; + rounded.e++; + } + } + + *result = rounded.ToDouble(); + + return halfWay - static_cast(error) >= precisionBits || precisionBits >= halfWay + static_cast(error); +} + +inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) { + const BigInteger dInt(decimals, length); + const int dExp = static_cast(decimalPosition) - static_cast(length) + exp; + Double a(approx); + int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp); + if (cmp < 0) + return a.Value(); // within half ULP + else if (cmp == 0) { + // Round towards even + if (a.Significand() & 1) + return a.NextPositiveDouble(); + else + return a.Value(); + } + else // adjustment + return a.NextPositiveDouble(); +} + +inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) { + RAPIDJSON_ASSERT(d >= 0.0); + RAPIDJSON_ASSERT(length >= 1); + + double result; + if (StrtodFast(d, p, &result)) + return result; + + // Trim leading zeros + while (*decimals == '0' && length > 1) { + length--; + decimals++; + decimalPosition--; + } + + // Trim trailing zeros + while (decimals[length - 1] == '0' && length > 1) { + length--; + decimalPosition--; + exp++; + } + + // Trim right-most digits + const int kMaxDecimalDigit = 780; + if (static_cast(length) > kMaxDecimalDigit) { + int delta = (static_cast(length) - kMaxDecimalDigit); + exp += delta; + decimalPosition -= static_cast(delta); + length = kMaxDecimalDigit; + } + + // If too small, underflow to zero + if (int(length) + exp < -324) + return 0.0; + + if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result)) + return result; + + // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison + return StrtodBigInteger(result, decimals, length, decimalPosition, exp); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STRTOD_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/swap.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/swap.h new file mode 100644 index 0000000000..666e49f97b --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/internal/swap.h @@ -0,0 +1,46 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_SWAP_H_ +#define RAPIDJSON_INTERNAL_SWAP_H_ + +#include "../rapidjson.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Custom swap() to avoid dependency on C++ header +/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. + \note This has the same semantics as std::swap(). +*/ +template +inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { + T tmp = a; + a = b; + b = tmp; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_SWAP_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/istreamwrapper.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/istreamwrapper.h new file mode 100644 index 0000000000..f5fe28977e --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/istreamwrapper.h @@ -0,0 +1,115 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ISTREAMWRAPPER_H_ +#define RAPIDJSON_ISTREAMWRAPPER_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of \c std::basic_istream into RapidJSON's Stream concept. +/*! + The classes can be wrapped including but not limited to: + + - \c std::istringstream + - \c std::stringstream + - \c std::wistringstream + - \c std::wstringstream + - \c std::ifstream + - \c std::fstream + - \c std::wifstream + - \c std::wfstream + + \tparam StreamType Class derived from \c std::basic_istream. +*/ + +template +class BasicIStreamWrapper { +public: + typedef typename StreamType::char_type Ch; + BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {} + + Ch Peek() const { + typename StreamType::int_type c = stream_.peek(); + return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast(c) : '\0'; + } + + Ch Take() { + typename StreamType::int_type c = stream_.get(); + if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) { + count_++; + return static_cast(c); + } + else + return '\0'; + } + + // tellg() may return -1 when failed. So we count by ourself. + size_t Tell() const { return count_; } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream. + int i; + bool hasError = false; + for (i = 0; i < 4; ++i) { + typename StreamType::int_type c = stream_.get(); + if (c == StreamType::traits_type::eof()) { + hasError = true; + stream_.clear(); + break; + } + peekBuffer_[i] = static_cast(c); + } + for (--i; i >= 0; --i) + stream_.putback(peekBuffer_[i]); + return !hasError ? peekBuffer_ : 0; + } + +private: + BasicIStreamWrapper(const BasicIStreamWrapper&); + BasicIStreamWrapper& operator=(const BasicIStreamWrapper&); + + StreamType& stream_; + size_t count_; //!< Number of characters read. Note: + mutable Ch peekBuffer_[4]; +}; + +typedef BasicIStreamWrapper IStreamWrapper; +typedef BasicIStreamWrapper WIStreamWrapper; + +#if defined(__clang__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ISTREAMWRAPPER_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/memorybuffer.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/memorybuffer.h new file mode 100644 index 0000000000..39bee1dec1 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/memorybuffer.h @@ -0,0 +1,70 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_MEMORYBUFFER_H_ +#define RAPIDJSON_MEMORYBUFFER_H_ + +#include "stream.h" +#include "internal/stack.h" + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory output byte stream. +/*! + This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. + + It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. + + Differences between MemoryBuffer and StringBuffer: + 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. + 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. + + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template +struct GenericMemoryBuffer { + typedef char Ch; // byte + + GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + + void Put(Ch c) { *stack_.template Push() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { stack_.ShrinkToFit(); } + Ch* Push(size_t count) { return stack_.template Push(count); } + void Pop(size_t count) { stack_.template Pop(count); } + + const Ch* GetBuffer() const { + return stack_.template Bottom(); + } + + size_t GetSize() const { return stack_.GetSize(); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; +}; + +typedef GenericMemoryBuffer<> MemoryBuffer; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { + std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); +} + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/memorystream.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/memorystream.h new file mode 100644 index 0000000000..1d71d8a4f0 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/memorystream.h @@ -0,0 +1,71 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_MEMORYSTREAM_H_ +#define RAPIDJSON_MEMORYSTREAM_H_ + +#include "stream.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(unreachable-code) +RAPIDJSON_DIAG_OFF(missing-noreturn) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory input byte stream. +/*! + This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. + + It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. + + Differences between MemoryStream and StringStream: + 1. StringStream has encoding but MemoryStream is a byte stream. + 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. + 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). + \note implements Stream concept +*/ +struct MemoryStream { + typedef char Ch; // byte + + MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} + + Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } + Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } + size_t Tell() const { return static_cast(src_ - begin_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return Tell() + 4 <= size_ ? src_ : 0; + } + + const Ch* src_; //!< Current read position. + const Ch* begin_; //!< Original head of the string. + const Ch* end_; //!< End of stream. + size_t size_; //!< Size of the stream. +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/msinttypes/inttypes.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/msinttypes/inttypes.h new file mode 100644 index 0000000000..18111286bf --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/msinttypes/inttypes.h @@ -0,0 +1,316 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +// The above software in this distribution may have been modified by +// THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// miloyip: VC supports inttypes.h since VC2013 +#if _MSC_VER >= 1800 +#include +#else + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + +#endif // _MSC_VER >= 1800 + +#endif // _MSC_INTTYPES_H_ ] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/msinttypes/stdint.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/msinttypes/stdint.h new file mode 100644 index 0000000000..3d4477b9a0 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/msinttypes/stdint.h @@ -0,0 +1,300 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +// The above software in this distribution may have been modified by +// THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010. +#if _MSC_VER >= 1600 // [ +#include + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +#undef INT8_C +#undef INT16_C +#undef INT32_C +#undef INT64_C +#undef UINT8_C +#undef UINT16_C +#undef UINT32_C +#undef UINT64_C + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#else // ] _MSC_VER >= 1700 [ + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we have to wrap include with 'extern "C++" {}' +// or compiler would give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#if defined(__cplusplus) && !defined(_M_ARM) +extern "C" { +#endif +# include +#if defined(__cplusplus) && !defined(_M_ARM) +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#endif // _MSC_VER >= 1600 ] + +#endif // _MSC_STDINT_H_ ] diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/ostreamwrapper.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/ostreamwrapper.h new file mode 100644 index 0000000000..6f4667c08a --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/ostreamwrapper.h @@ -0,0 +1,81 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_OSTREAMWRAPPER_H_ +#define RAPIDJSON_OSTREAMWRAPPER_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. +/*! + The classes can be wrapped including but not limited to: + + - \c std::ostringstream + - \c std::stringstream + - \c std::wpstringstream + - \c std::wstringstream + - \c std::ifstream + - \c std::fstream + - \c std::wofstream + - \c std::wfstream + + \tparam StreamType Class derived from \c std::basic_ostream. +*/ + +template +class BasicOStreamWrapper { +public: + typedef typename StreamType::char_type Ch; + BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} + + void Put(Ch c) { + stream_.put(c); + } + + void Flush() { + stream_.flush(); + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + BasicOStreamWrapper(const BasicOStreamWrapper&); + BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); + + StreamType& stream_; +}; + +typedef BasicOStreamWrapper OStreamWrapper; +typedef BasicOStreamWrapper WOStreamWrapper; + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_OSTREAMWRAPPER_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/pointer.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/pointer.h new file mode 100644 index 0000000000..0206ac1c8b --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/pointer.h @@ -0,0 +1,1358 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_POINTER_H_ +#define RAPIDJSON_POINTER_H_ + +#include "document.h" +#include "internal/itoa.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(switch-enum) +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token + +//! Error code of parsing. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode +*/ +enum PointerParseErrorCode { + kPointerParseErrorNone = 0, //!< The parse is successful + + kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/' + kPointerParseErrorInvalidEscape, //!< Invalid escape + kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment + kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericPointer + +//! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator. +/*! + This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer" + (https://tools.ietf.org/html/rfc6901). + + A JSON pointer is for identifying a specific value in a JSON document + (GenericDocument). It can simplify coding of DOM tree manipulation, because it + can access multiple-level depth of DOM tree with single API call. + + After it parses a string representation (e.g. "/foo/0" or URI fragment + representation (e.g. "#/foo/0") into its internal representation (tokens), + it can be used to resolve a specific value in multiple documents, or sub-tree + of documents. + + Contrary to GenericValue, Pointer can be copy constructed and copy assigned. + Apart from assignment, a Pointer cannot be modified after construction. + + Although Pointer is very convenient, please aware that constructing Pointer + involves parsing and dynamic memory allocation. A special constructor with user- + supplied tokens eliminates these. + + GenericPointer depends on GenericDocument and GenericValue. + + \tparam ValueType The value type of the DOM tree. E.g. GenericValue > + \tparam Allocator The allocator type for allocating memory for internal representation. + + \note GenericPointer uses same encoding of ValueType. + However, Allocator of GenericPointer is independent of Allocator of Value. +*/ +template +class GenericPointer { +public: + typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value + typedef typename ValueType::Ch Ch; //!< Character type from Value + + //! A token is the basic units of internal representation. + /*! + A JSON pointer string representation "/foo/123" is parsed to two tokens: + "foo" and 123. 123 will be represented in both numeric form and string form. + They are resolved according to the actual value type (object or array). + + For token that are not numbers, or the numeric value is out of bound + (greater than limits of SizeType), they are only treated as string form + (i.e. the token's index will be equal to kPointerInvalidIndex). + + This struct is public so that user can create a Pointer without parsing and + allocation, using a special constructor. + */ + struct Token { + const Ch* name; //!< Name of the token. It has null character at the end but it can contain null character. + SizeType length; //!< Length of the name. + SizeType index; //!< A valid array index, if it is not equal to kPointerInvalidIndex. + }; + + //!@name Constructors and destructor. + //@{ + + //! Default constructor. + GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} + + //! Constructor that parses a string or URI fragment representation. + /*! + \param source A null-terminated, string or URI fragment representation of JSON pointer. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + */ + explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source, internal::StrLen(source)); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Constructor that parses a string or URI fragment representation. + /*! + \param source A string or URI fragment representation of JSON pointer. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + explicit GenericPointer(const std::basic_string& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source.c_str(), source.size()); + } +#endif + + //! Constructor that parses a string or URI fragment representation, with length of the source string. + /*! + \param source A string or URI fragment representation of JSON pointer. + \param length Length of source. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + \note Slightly faster than the overload without length. + */ + GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source, length); + } + + //! Constructor with user-supplied tokens. + /*! + This constructor let user supplies const array of tokens. + This prevents the parsing process and eliminates allocation. + This is preferred for memory constrained environments. + + \param tokens An constant array of tokens representing the JSON pointer. + \param tokenCount Number of tokens. + + \b Example + \code + #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex } + #define INDEX(i) { #i, sizeof(#i) - 1, i } + + static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) }; + static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0])); + // Equivalent to static const Pointer p("/foo/123"); + + #undef NAME + #undef INDEX + \endcode + */ + GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} + + //! Copy constructor. + GenericPointer(const GenericPointer& rhs, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + *this = rhs; + } + + //! Destructor. + ~GenericPointer() { + if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated. + Allocator::Free(tokens_); + RAPIDJSON_DELETE(ownAllocator_); + } + + //! Assignment operator. + GenericPointer& operator=(const GenericPointer& rhs) { + if (this != &rhs) { + // Do not delete ownAllcator + if (nameBuffer_) + Allocator::Free(tokens_); + + tokenCount_ = rhs.tokenCount_; + parseErrorOffset_ = rhs.parseErrorOffset_; + parseErrorCode_ = rhs.parseErrorCode_; + + if (rhs.nameBuffer_) + CopyFromRaw(rhs); // Normally parsed tokens. + else { + tokens_ = rhs.tokens_; // User supplied const tokens. + nameBuffer_ = 0; + } + } + return *this; + } + + //@} + + //!@name Append token + //@{ + + //! Append a token and return a new Pointer + /*! + \param token Token to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const Token& token, Allocator* allocator = 0) const { + GenericPointer r; + r.allocator_ = allocator; + Ch *p = r.CopyFromRaw(*this, 1, token.length + 1); + std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch)); + r.tokens_[tokenCount_].name = p; + r.tokens_[tokenCount_].length = token.length; + r.tokens_[tokenCount_].index = token.index; + return r; + } + + //! Append a name token with length, and return a new Pointer + /*! + \param name Name to be appended. + \param length Length of name. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const { + Token token = { name, length, kPointerInvalidIndex }; + return Append(token, allocator); + } + + //! Append a name token without length, and return a new Pointer + /*! + \param name Name (const Ch*) to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >), (GenericPointer)) + Append(T* name, Allocator* allocator = 0) const { + return Append(name, StrLen(name), allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Append a name token, and return a new Pointer + /*! + \param name Name to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const std::basic_string& name, Allocator* allocator = 0) const { + return Append(name.c_str(), static_cast(name.size()), allocator); + } +#endif + + //! Append a index token, and return a new Pointer + /*! + \param index Index to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(SizeType index, Allocator* allocator = 0) const { + char buffer[21]; + char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer); + SizeType length = static_cast(end - buffer); + buffer[length] = '\0'; + + if (sizeof(Ch) == 1) { + Token token = { reinterpret_cast(buffer), length, index }; + return Append(token, allocator); + } + else { + Ch name[21]; + for (size_t i = 0; i <= length; i++) + name[i] = buffer[i]; + Token token = { name, length, index }; + return Append(token, allocator); + } + } + + //! Append a token by value, and return a new Pointer + /*! + \param token token to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const { + if (token.IsString()) + return Append(token.GetString(), token.GetStringLength(), allocator); + else { + RAPIDJSON_ASSERT(token.IsUint64()); + RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0)); + return Append(static_cast(token.GetUint64()), allocator); + } + } + + //!@name Handling Parse Error + //@{ + + //! Check whether this is a valid pointer. + bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; } + + //! Get the parsing error offset in code unit. + size_t GetParseErrorOffset() const { return parseErrorOffset_; } + + //! Get the parsing error code. + PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; } + + //@} + + //! Get the allocator of this pointer. + Allocator& GetAllocator() { return *allocator_; } + + //!@name Tokens + //@{ + + //! Get the token array (const version only). + const Token* GetTokens() const { return tokens_; } + + //! Get the number of tokens. + size_t GetTokenCount() const { return tokenCount_; } + + //@} + + //!@name Equality/inequality operators + //@{ + + //! Equality operator. + /*! + \note When any pointers are invalid, always returns false. + */ + bool operator==(const GenericPointer& rhs) const { + if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_) + return false; + + for (size_t i = 0; i < tokenCount_; i++) { + if (tokens_[i].index != rhs.tokens_[i].index || + tokens_[i].length != rhs.tokens_[i].length || + (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0)) + { + return false; + } + } + + return true; + } + + //! Inequality operator. + /*! + \note When any pointers are invalid, always returns true. + */ + bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); } + + //@} + + //!@name Stringify + //@{ + + //! Stringify the pointer into string representation. + /*! + \tparam OutputStream Type of output stream. + \param os The output stream. + */ + template + bool Stringify(OutputStream& os) const { + return Stringify(os); + } + + //! Stringify the pointer into URI fragment representation. + /*! + \tparam OutputStream Type of output stream. + \param os The output stream. + */ + template + bool StringifyUriFragment(OutputStream& os) const { + return Stringify(os); + } + + //@} + + //!@name Create value + //@{ + + //! Create a value in a subtree. + /*! + If the value is not exist, it creates all parent values and a JSON Null value. + So it always succeed and return the newly created or existing value. + + Remind that it may change types of parents according to tokens, so it + potentially removes previously stored values. For example, if a document + was an array, and "/foo" is used to create a value, then the document + will be changed to an object, and all existing array elements are lost. + + \param root Root value of a DOM subtree to be resolved. It can be any value other than document root. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \param alreadyExist If non-null, it stores whether the resolved value is already exist. + \return The resolved newly created (a JSON Null value), or already exists value. + */ + ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const { + RAPIDJSON_ASSERT(IsValid()); + ValueType* v = &root; + bool exist = true; + for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + if (v->IsArray() && t->name[0] == '-' && t->length == 1) { + v->PushBack(ValueType().Move(), allocator); + v = &((*v)[v->Size() - 1]); + exist = false; + } + else { + if (t->index == kPointerInvalidIndex) { // must be object name + if (!v->IsObject()) + v->SetObject(); // Change to Object + } + else { // object name or array index + if (!v->IsArray() && !v->IsObject()) + v->SetArray(); // Change to Array + } + + if (v->IsArray()) { + if (t->index >= v->Size()) { + v->Reserve(t->index + 1, allocator); + while (t->index >= v->Size()) + v->PushBack(ValueType().Move(), allocator); + exist = false; + } + v = &((*v)[t->index]); + } + else { + typename ValueType::MemberIterator m = v->FindMember(GenericStringRef(t->name, t->length)); + if (m == v->MemberEnd()) { + v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator); + v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end + exist = false; + } + else + v = &m->value; + } + } + } + + if (alreadyExist) + *alreadyExist = exist; + + return *v; + } + + //! Creates a value in a document. + /*! + \param document A document to be resolved. + \param alreadyExist If non-null, it stores whether the resolved value is already exist. + \return The resolved newly created, or already exists value. + */ + template + ValueType& Create(GenericDocument& document, bool* alreadyExist = 0) const { + return Create(document, document.GetAllocator(), alreadyExist); + } + + //@} + + //!@name Query value + //@{ + + //! Query a value in a subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token. + \return Pointer to the value if it can be resolved. Otherwise null. + + \note + There are only 3 situations when a value cannot be resolved: + 1. A value in the path is not an array nor object. + 2. An object value does not contain the token. + 3. A token is out of range of an array value. + + Use unresolvedTokenIndex to retrieve the token index. + */ + ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const { + RAPIDJSON_ASSERT(IsValid()); + ValueType* v = &root; + for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + switch (v->GetType()) { + case kObjectType: + { + typename ValueType::MemberIterator m = v->FindMember(GenericStringRef(t->name, t->length)); + if (m == v->MemberEnd()) + break; + v = &m->value; + } + continue; + case kArrayType: + if (t->index == kPointerInvalidIndex || t->index >= v->Size()) + break; + v = &((*v)[t->index]); + continue; + default: + break; + } + + // Error: unresolved token + if (unresolvedTokenIndex) + *unresolvedTokenIndex = static_cast(t - tokens_); + return 0; + } + return v; + } + + //! Query a const value in a const subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \return Pointer to the value if it can be resolved. Otherwise null. + */ + const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const { + return Get(const_cast(root), unresolvedTokenIndex); + } + + //@} + + //!@name Query a value with default + //@{ + + //! Query a value in a subtree with default value. + /*! + Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value. + So that this function always succeed. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param defaultValue Default value to be cloned if the value was not exists. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + Value& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.CopyFrom(defaultValue, allocator); + } + + //! Query a value in a subtree with default null-terminated string. + ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + Value& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.SetString(defaultValue, allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Query a value in a subtree with default std::basic_string. + ValueType& GetWithDefault(ValueType& root, const std::basic_string& defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + Value& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.SetString(defaultValue, allocator); + } +#endif + + //! Query a value in a subtree with default primitive value. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const { + return GetWithDefault(root, ValueType(defaultValue).Move(), allocator); + } + + //! Query a value in a document with default value. + template + ValueType& GetWithDefault(GenericDocument& document, const ValueType& defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + + //! Query a value in a document with default null-terminated string. + template + ValueType& GetWithDefault(GenericDocument& document, const Ch* defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Query a value in a document with default std::basic_string. + template + ValueType& GetWithDefault(GenericDocument& document, const std::basic_string& defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } +#endif + + //! Query a value in a document with default primitive value. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + GetWithDefault(GenericDocument& document, T defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + + //@} + + //!@name Set a value + //@{ + + //! Set a value in a subtree, with move semantics. + /*! + It creates all parents if they are not exist or types are different to the tokens. + So this function always succeeds but potentially remove existing values. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param value Value to be set. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = value; + } + + //! Set a value in a subtree, with copy semantics. + ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator).CopyFrom(value, allocator); + } + + //! Set a null-terminated string in a subtree. + ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value, allocator).Move(); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Set a std::basic_string in a subtree. + ValueType& Set(ValueType& root, const std::basic_string& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value, allocator).Move(); + } +#endif + + //! Set a primitive value in a subtree. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value).Move(); + } + + //! Set a value in a document, with move semantics. + template + ValueType& Set(GenericDocument& document, ValueType& value) const { + return Create(document) = value; + } + + //! Set a value in a document, with copy semantics. + template + ValueType& Set(GenericDocument& document, const ValueType& value) const { + return Create(document).CopyFrom(value, document.GetAllocator()); + } + + //! Set a null-terminated string in a document. + template + ValueType& Set(GenericDocument& document, const Ch* value) const { + return Create(document) = ValueType(value, document.GetAllocator()).Move(); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Sets a std::basic_string in a document. + template + ValueType& Set(GenericDocument& document, const std::basic_string& value) const { + return Create(document) = ValueType(value, document.GetAllocator()).Move(); + } +#endif + + //! Set a primitive value in a document. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + Set(GenericDocument& document, T value) const { + return Create(document) = value; + } + + //@} + + //!@name Swap a value + //@{ + + //! Swap a value with a value in a subtree. + /*! + It creates all parents if they are not exist or types are different to the tokens. + So this function always succeeds but potentially remove existing values. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param value Value to be swapped. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator).Swap(value); + } + + //! Swap a value with a value in a document. + template + ValueType& Swap(GenericDocument& document, ValueType& value) const { + return Create(document).Swap(value); + } + + //@} + + //! Erase a value in a subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \return Whether the resolved value is found and erased. + + \note Erasing with an empty pointer \c Pointer(""), i.e. the root, always fail and return false. + */ + bool Erase(ValueType& root) const { + RAPIDJSON_ASSERT(IsValid()); + if (tokenCount_ == 0) // Cannot erase the root + return false; + + ValueType* v = &root; + const Token* last = tokens_ + (tokenCount_ - 1); + for (const Token *t = tokens_; t != last; ++t) { + switch (v->GetType()) { + case kObjectType: + { + typename ValueType::MemberIterator m = v->FindMember(GenericStringRef(t->name, t->length)); + if (m == v->MemberEnd()) + return false; + v = &m->value; + } + break; + case kArrayType: + if (t->index == kPointerInvalidIndex || t->index >= v->Size()) + return false; + v = &((*v)[t->index]); + break; + default: + return false; + } + } + + switch (v->GetType()) { + case kObjectType: + return v->EraseMember(GenericStringRef(last->name, last->length)); + case kArrayType: + if (last->index == kPointerInvalidIndex || last->index >= v->Size()) + return false; + v->Erase(v->Begin() + last->index); + return true; + default: + return false; + } + } + +private: + //! Clone the content from rhs to this. + /*! + \param rhs Source pointer. + \param extraToken Extra tokens to be allocated. + \param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated. + \return Start of non-occupied name buffer, for storing extra names. + */ + Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) { + if (!allocator_) // allocator is independently owned. + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + + size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens + for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t) + nameBufferSize += t->length; + + tokenCount_ = rhs.tokenCount_ + extraToken; + tokens_ = static_cast(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch))); + nameBuffer_ = reinterpret_cast(tokens_ + tokenCount_); + if (rhs.tokenCount_ > 0) { + std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token)); + } + if (nameBufferSize > 0) { + std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch)); + } + + // Adjust pointers to name buffer + std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_; + for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t) + t->name += diff; + + return nameBuffer_ + nameBufferSize; + } + + //! Check whether a character should be percent-encoded. + /*! + According to RFC 3986 2.3 Unreserved Characters. + \param c The character (code unit) to be tested. + */ + bool NeedPercentEncode(Ch c) const { + return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~'); + } + + //! Parse a JSON String or its URI fragment representation into tokens. +#ifndef __clang__ // -Wdocumentation + /*! + \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated. + \param length Length of the source string. + \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped. + */ +#endif + void Parse(const Ch* source, size_t length) { + RAPIDJSON_ASSERT(source != NULL); + RAPIDJSON_ASSERT(nameBuffer_ == 0); + RAPIDJSON_ASSERT(tokens_ == 0); + + // Create own allocator if user did not supply. + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + + // Count number of '/' as tokenCount + tokenCount_ = 0; + for (const Ch* s = source; s != source + length; s++) + if (*s == '/') + tokenCount_++; + + Token* token = tokens_ = static_cast(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch))); + Ch* name = nameBuffer_ = reinterpret_cast(tokens_ + tokenCount_); + size_t i = 0; + + // Detect if it is a URI fragment + bool uriFragment = false; + if (source[i] == '#') { + uriFragment = true; + i++; + } + + if (i != length && source[i] != '/') { + parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus; + goto error; + } + + while (i < length) { + RAPIDJSON_ASSERT(source[i] == '/'); + i++; // consumes '/' + + token->name = name; + bool isNumber = true; + + while (i < length && source[i] != '/') { + Ch c = source[i]; + if (uriFragment) { + // Decoding percent-encoding for URI fragment + if (c == '%') { + PercentDecodeStream is(&source[i], source + length); + GenericInsituStringStream os(name); + Ch* begin = os.PutBegin(); + if (!Transcoder, EncodingType>().Validate(is, os) || !is.IsValid()) { + parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding; + goto error; + } + size_t len = os.PutEnd(begin); + i += is.Tell() - 1; + if (len == 1) + c = *name; + else { + name += len; + isNumber = false; + i++; + continue; + } + } + else if (NeedPercentEncode(c)) { + parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode; + goto error; + } + } + + i++; + + // Escaping "~0" -> '~', "~1" -> '/' + if (c == '~') { + if (i < length) { + c = source[i]; + if (c == '0') c = '~'; + else if (c == '1') c = '/'; + else { + parseErrorCode_ = kPointerParseErrorInvalidEscape; + goto error; + } + i++; + } + else { + parseErrorCode_ = kPointerParseErrorInvalidEscape; + goto error; + } + } + + // First check for index: all of characters are digit + if (c < '0' || c > '9') + isNumber = false; + + *name++ = c; + } + token->length = static_cast(name - token->name); + if (token->length == 0) + isNumber = false; + *name++ = '\0'; // Null terminator + + // Second check for index: more than one digit cannot have leading zero + if (isNumber && token->length > 1 && token->name[0] == '0') + isNumber = false; + + // String to SizeType conversion + SizeType n = 0; + if (isNumber) { + for (size_t j = 0; j < token->length; j++) { + SizeType m = n * 10 + static_cast(token->name[j] - '0'); + if (m < n) { // overflow detection + isNumber = false; + break; + } + n = m; + } + } + + token->index = isNumber ? n : kPointerInvalidIndex; + token++; + } + + RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer + parseErrorCode_ = kPointerParseErrorNone; + return; + + error: + Allocator::Free(tokens_); + nameBuffer_ = 0; + tokens_ = 0; + tokenCount_ = 0; + parseErrorOffset_ = i; + return; + } + + //! Stringify to string or URI fragment representation. + /*! + \tparam uriFragment True for stringifying to URI fragment representation. False for string representation. + \tparam OutputStream type of output stream. + \param os The output stream. + */ + template + bool Stringify(OutputStream& os) const { + RAPIDJSON_ASSERT(IsValid()); + + if (uriFragment) + os.Put('#'); + + for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + os.Put('/'); + for (size_t j = 0; j < t->length; j++) { + Ch c = t->name[j]; + if (c == '~') { + os.Put('~'); + os.Put('0'); + } + else if (c == '/') { + os.Put('~'); + os.Put('1'); + } + else if (uriFragment && NeedPercentEncode(c)) { + // Transcode to UTF8 sequence + GenericStringStream source(&t->name[j]); + PercentEncodeStream target(os); + if (!Transcoder >().Validate(source, target)) + return false; + j += source.Tell() - 1; + } + else + os.Put(c); + } + } + return true; + } + + //! A helper stream for decoding a percent-encoded sequence into code unit. + /*! + This stream decodes %XY triplet into code unit (0-255). + If it encounters invalid characters, it sets output code unit as 0 and + mark invalid, and to be checked by IsValid(). + */ + class PercentDecodeStream { + public: + typedef typename ValueType::Ch Ch; + + //! Constructor + /*! + \param source Start of the stream + \param end Past-the-end of the stream. + */ + PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {} + + Ch Take() { + if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet + valid_ = false; + return 0; + } + src_++; + Ch c = 0; + for (int j = 0; j < 2; j++) { + c = static_cast(c << 4); + Ch h = *src_; + if (h >= '0' && h <= '9') c = static_cast(c + h - '0'); + else if (h >= 'A' && h <= 'F') c = static_cast(c + h - 'A' + 10); + else if (h >= 'a' && h <= 'f') c = static_cast(c + h - 'a' + 10); + else { + valid_ = false; + return 0; + } + src_++; + } + return c; + } + + size_t Tell() const { return static_cast(src_ - head_); } + bool IsValid() const { return valid_; } + + private: + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. + const Ch* end_; //!< Past-the-end position. + bool valid_; //!< Whether the parsing is valid. + }; + + //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence. + template + class PercentEncodeStream { + public: + PercentEncodeStream(OutputStream& os) : os_(os) {} + void Put(char c) { // UTF-8 must be byte + unsigned char u = static_cast(c); + static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + os_.Put('%'); + os_.Put(hexDigits[u >> 4]); + os_.Put(hexDigits[u & 15]); + } + private: + OutputStream& os_; + }; + + Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_. + Allocator* ownAllocator_; //!< Allocator owned by this Pointer. + Ch* nameBuffer_; //!< A buffer containing all names in tokens. + Token* tokens_; //!< A list of tokens. + size_t tokenCount_; //!< Number of tokens in tokens_. + size_t parseErrorOffset_; //!< Offset in code unit when parsing fail. + PointerParseErrorCode parseErrorCode_; //!< Parsing error code. +}; + +//! GenericPointer for Value (UTF-8, default allocator). +typedef GenericPointer Pointer; + +//!@name Helper functions for GenericPointer +//@{ + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer& pointer, typename T::AllocatorType& a) { + return pointer.Create(root, a); +} + +template +typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Create(root, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer& pointer) { + return pointer.Create(document); +} + +template +typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) { + return GenericPointer(source, N - 1).Create(document); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType* GetValueByPointer(T& root, const GenericPointer& pointer, size_t* unresolvedTokenIndex = 0) { + return pointer.Get(root, unresolvedTokenIndex); +} + +template +const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer& pointer, size_t* unresolvedTokenIndex = 0) { + return pointer.Get(root, unresolvedTokenIndex); +} + +template +typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) { + return GenericPointer(source, N - 1).Get(root, unresolvedTokenIndex); +} + +template +const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) { + return GenericPointer(source, N - 1).Get(root, unresolvedTokenIndex); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const std::basic_string& defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, T2 defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string& defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::ValueType& defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::Ch* defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const std::basic_string& defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, T2 defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string& defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const typename T::Ch* value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const std::basic_string& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +SetValueByPointer(T& root, const GenericPointer& pointer, T2 value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, typename DocumentType::ValueType& value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::ValueType& value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::Ch* value) { + return pointer.Set(document, value); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const std::basic_string& value) { + return pointer.Set(document, value); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +SetValueByPointer(DocumentType& document, const GenericPointer& pointer, T2 value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string& value) { + return GenericPointer(source, N - 1).Set(document, value); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Swap(root, value, a); +} + +template +typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Swap(root, value, a); +} + +template +typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer& pointer, typename DocumentType::ValueType& value) { + return pointer.Swap(document, value); +} + +template +typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Swap(document, value); +} + +////////////////////////////////////////////////////////////////////////////// + +template +bool EraseValueByPointer(T& root, const GenericPointer& pointer) { + return pointer.Erase(root); +} + +template +bool EraseValueByPointer(T& root, const CharType(&source)[N]) { + return GenericPointer(source, N - 1).Erase(root); +} + +//@} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_POINTER_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/prettywriter.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/prettywriter.h new file mode 100644 index 0000000000..0dcb0fee92 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/prettywriter.h @@ -0,0 +1,255 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_PRETTYWRITER_H_ +#define RAPIDJSON_PRETTYWRITER_H_ + +#include "writer.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Combination of PrettyWriter format flags. +/*! \see PrettyWriter::SetFormatOptions + */ +enum PrettyFormatOptions { + kFormatDefault = 0, //!< Default pretty formatting. + kFormatSingleLineArray = 1 //!< Format arrays on a single line. +}; + +//! Writer with indentation and spacing. +/*! + \tparam OutputStream Type of ouptut os. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. +*/ +template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> +class PrettyWriter : public Writer { +public: + typedef Writer Base; + typedef typename Base::Ch Ch; + + //! Constructor + /*! \param os Output stream. + \param allocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} + + + explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} + + //! Set custom indentation. + /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r'). + \param indentCharCount Number of indent characters for each indentation level. + \note The default indentation is 4 spaces. + */ + PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { + RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); + indentChar_ = indentChar; + indentCharCount_ = indentCharCount; + return *this; + } + + //! Set pretty writer formatting options. + /*! \param options Formatting options. + */ + PrettyWriter& SetFormatOptions(PrettyFormatOptions options) { + formatOptions_ = options; + return *this; + } + + /*! @name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); } + bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); } + bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); } + bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); } + bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); } + bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); } + bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); } + + bool RawNumber(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + PrettyPrefix(kNumberType); + return Base::WriteString(str, length); + } + + bool String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + PrettyPrefix(kStringType); + return Base::WriteString(str, length); + } + +#if RAPIDJSON_HAS_STDSTRING + bool String(const std::basic_string& str) { + return String(str.data(), SizeType(str.size())); + } +#endif + + bool StartObject() { + PrettyPrefix(kObjectType); + new (Base::level_stack_.template Push()) typename Base::Level(false); + return Base::WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + +#if RAPIDJSON_HAS_STDSTRING + bool Key(const std::basic_string& str) { + return Key(str.data(), SizeType(str.size())); + } +#endif + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(!Base::level_stack_.template Top()->inArray); + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + + if (!empty) { + Base::os_->Put('\n'); + WriteIndent(); + } + bool ret = Base::WriteEndObject(); + (void)ret; + RAPIDJSON_ASSERT(ret == true); + if (Base::level_stack_.Empty()) // end of json text + Base::os_->Flush(); + return true; + } + + bool StartArray() { + PrettyPrefix(kArrayType); + new (Base::level_stack_.template Push()) typename Base::Level(true); + return Base::WriteStartArray(); + } + + bool EndArray(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + + if (!empty && !(formatOptions_ & kFormatSingleLineArray)) { + Base::os_->Put('\n'); + WriteIndent(); + } + bool ret = Base::WriteEndArray(); + (void)ret; + RAPIDJSON_ASSERT(ret == true); + if (Base::level_stack_.Empty()) // end of json text + Base::os_->Flush(); + return true; + } + + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } + + //@} + + //! Write a raw JSON value. + /*! + For user to write a stringified JSON as a value. + + \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. + \param length Length of the json. + \param type Type of the root of json. + \note When using PrettyWriter::RawValue(), the result json may not be indented correctly. + */ + bool RawValue(const Ch* json, size_t length, Type type) { PrettyPrefix(type); return Base::WriteRawValue(json, length); } + +protected: + void PrettyPrefix(Type type) { + (void)type; + if (Base::level_stack_.GetSize() != 0) { // this value is not at root + typename Base::Level* level = Base::level_stack_.template Top(); + + if (level->inArray) { + if (level->valueCount > 0) { + Base::os_->Put(','); // add comma if it is not the first element in array + if (formatOptions_ & kFormatSingleLineArray) + Base::os_->Put(' '); + } + + if (!(formatOptions_ & kFormatSingleLineArray)) { + Base::os_->Put('\n'); + WriteIndent(); + } + } + else { // in object + if (level->valueCount > 0) { + if (level->valueCount % 2 == 0) { + Base::os_->Put(','); + Base::os_->Put('\n'); + } + else { + Base::os_->Put(':'); + Base::os_->Put(' '); + } + } + else + Base::os_->Put('\n'); + + if (level->valueCount % 2 == 0) + WriteIndent(); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. + Base::hasRoot_ = true; + } + } + + void WriteIndent() { + size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; + PutN(*Base::os_, static_cast(indentChar_), count); + } + + Ch indentChar_; + unsigned indentCharCount_; + PrettyFormatOptions formatOptions_; + +private: + // Prohibit copy constructor & assignment operator. + PrettyWriter(const PrettyWriter&); + PrettyWriter& operator=(const PrettyWriter&); +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/rapidjson.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/rapidjson.h new file mode 100644 index 0000000000..053b2ce43f --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/rapidjson.h @@ -0,0 +1,615 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_RAPIDJSON_H_ +#define RAPIDJSON_RAPIDJSON_H_ + +/*!\file rapidjson.h + \brief common definitions and configuration + + \see RAPIDJSON_CONFIG + */ + +/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration + \brief Configuration macros for library features + + Some RapidJSON features are configurable to adapt the library to a wide + variety of platforms, environments and usage scenarios. Most of the + features can be configured in terms of overriden or predefined + preprocessor macros at compile-time. + + Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs. + + \note These macros should be given on the compiler command-line + (where applicable) to avoid inconsistent values when compiling + different translation units of a single application. + */ + +#include // malloc(), realloc(), free(), size_t +#include // memset(), memcpy(), memmove(), memcmp() + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_VERSION_STRING +// +// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt. +// + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +// token stringification +#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x) +#define RAPIDJSON_DO_STRINGIFY(x) #x +//!@endcond + +/*! \def RAPIDJSON_MAJOR_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Major version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_MINOR_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Minor version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_PATCH_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Patch version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_VERSION_STRING + \ingroup RAPIDJSON_CONFIG + \brief Version of RapidJSON in ".." string format. +*/ +#define RAPIDJSON_MAJOR_VERSION 1 +#define RAPIDJSON_MINOR_VERSION 1 +#define RAPIDJSON_PATCH_VERSION 0 +#define RAPIDJSON_VERSION_STRING \ + RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION) + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NAMESPACE_(BEGIN|END) +/*! \def RAPIDJSON_NAMESPACE + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace + + In order to avoid symbol clashes and/or "One Definition Rule" errors + between multiple inclusions of (different versions of) RapidJSON in + a single binary, users can customize the name of the main RapidJSON + namespace. + + In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE + to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple + levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref + RAPIDJSON_NAMESPACE_END need to be defined as well: + + \code + // in some .cpp file + #define RAPIDJSON_NAMESPACE my::rapidjson + #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson { + #define RAPIDJSON_NAMESPACE_END } } + #include "rapidjson/..." + \endcode + + \see rapidjson + */ +/*! \def RAPIDJSON_NAMESPACE_BEGIN + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace (opening expression) + \see RAPIDJSON_NAMESPACE +*/ +/*! \def RAPIDJSON_NAMESPACE_END + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace (closing expression) + \see RAPIDJSON_NAMESPACE +*/ +#ifndef RAPIDJSON_NAMESPACE +#define RAPIDJSON_NAMESPACE rapidjson +#endif +#ifndef RAPIDJSON_NAMESPACE_BEGIN +#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE { +#endif +#ifndef RAPIDJSON_NAMESPACE_END +#define RAPIDJSON_NAMESPACE_END } +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_HAS_STDSTRING + +#ifndef RAPIDJSON_HAS_STDSTRING +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation +#else +#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default +#endif +/*! \def RAPIDJSON_HAS_STDSTRING + \ingroup RAPIDJSON_CONFIG + \brief Enable RapidJSON support for \c std::string + + By defining this preprocessor symbol to \c 1, several convenience functions for using + \ref rapidjson::GenericValue with \c std::string are enabled, especially + for construction and comparison. + + \hideinitializer +*/ +#endif // !defined(RAPIDJSON_HAS_STDSTRING) + +#if RAPIDJSON_HAS_STDSTRING +#include +#endif // RAPIDJSON_HAS_STDSTRING + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_INT64DEFINE + +/*! \def RAPIDJSON_NO_INT64DEFINE + \ingroup RAPIDJSON_CONFIG + \brief Use external 64-bit integer types. + + RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types + to be available at global scope. + + If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to + prevent RapidJSON from defining its own types. +*/ +#ifndef RAPIDJSON_NO_INT64DEFINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013 +#include "msinttypes/stdint.h" +#include "msinttypes/inttypes.h" +#else +// Other compilers should have this. +#include +#include +#endif +//!@endcond +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_INT64DEFINE +#endif +#endif // RAPIDJSON_NO_INT64TYPEDEF + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_FORCEINLINE + +#ifndef RAPIDJSON_FORCEINLINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#if defined(_MSC_VER) && defined(NDEBUG) +#define RAPIDJSON_FORCEINLINE __forceinline +#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG) +#define RAPIDJSON_FORCEINLINE __attribute__((always_inline)) +#else +#define RAPIDJSON_FORCEINLINE +#endif +//!@endcond +#endif // RAPIDJSON_FORCEINLINE + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ENDIAN +#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine +#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine + +//! Endianness of the machine. +/*! + \def RAPIDJSON_ENDIAN + \ingroup RAPIDJSON_CONFIG + + GCC 4.6 provided macro for detecting endianness of the target machine. But other + compilers may not have this. User can define RAPIDJSON_ENDIAN to either + \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. + + Default detection implemented with reference to + \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html + \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp +*/ +#ifndef RAPIDJSON_ENDIAN +// Detect with GCC 4.6's macro +# ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __BYTE_ORDER__ +// Detect with GLIBC's endian.h +# elif defined(__GLIBC__) +# include +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif (__BYTE_ORDER == __BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __GLIBC__ +// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro +# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +// Detect with architecture macros +# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(_MSC_VER) && defined(_M_ARM) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(RAPIDJSON_DOXYGEN_RUNNING) +# define RAPIDJSON_ENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif +#endif // RAPIDJSON_ENDIAN + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_64BIT + +//! Whether using 64-bit architecture +#ifndef RAPIDJSON_64BIT +#if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__) +#define RAPIDJSON_64BIT 1 +#else +#define RAPIDJSON_64BIT 0 +#endif +#endif // RAPIDJSON_64BIT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ALIGN + +//! Data alignment of the machine. +/*! \ingroup RAPIDJSON_CONFIG + \param x pointer to align + + Some machines require strict data alignment. Currently the default uses 4 bytes + alignment on 32-bit platforms and 8 bytes alignment for 64-bit platforms. + User can customize by defining the RAPIDJSON_ALIGN function macro. +*/ +#ifndef RAPIDJSON_ALIGN +#if RAPIDJSON_64BIT == 1 +#define RAPIDJSON_ALIGN(x) (((x) + static_cast(7u)) & ~static_cast(7u)) +#else +#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u) +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_UINT64_C2 + +//! Construct a 64-bit literal by a pair of 32-bit integer. +/*! + 64-bit literal with or without ULL suffix is prone to compiler warnings. + UINT64_C() is C macro which cause compilation problems. + Use this macro to define 64-bit constants by a pair of 32-bit integer. +*/ +#ifndef RAPIDJSON_UINT64_C2 +#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast(high32) << 32) | static_cast(low32)) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_48BITPOINTER_OPTIMIZATION + +//! Use only lower 48-bit address for some pointers. +/*! + \ingroup RAPIDJSON_CONFIG + + This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address. + The higher 16-bit can be used for storing other data. + \c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture. +*/ +#ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION +#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) +#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1 +#else +#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0 +#endif +#endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION + +#if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1 +#if RAPIDJSON_64BIT != 1 +#error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1 +#endif +#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast((reinterpret_cast(p) & static_cast(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast(reinterpret_cast(x)))) +#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast(reinterpret_cast(p) & static_cast(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF)))) +#else +#define RAPIDJSON_SETPOINTER(type, p, x) (p = (x)) +#define RAPIDJSON_GETPOINTER(type, p) (p) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD + +/*! \def RAPIDJSON_SIMD + \ingroup RAPIDJSON_CONFIG + \brief Enable SSE2/SSE4.2 optimization. + + RapidJSON supports optimized implementations for some parsing operations + based on the SSE2 or SSE4.2 SIMD extensions on modern Intel-compatible + processors. + + To enable these optimizations, two different symbols can be defined; + \code + // Enable SSE2 optimization. + #define RAPIDJSON_SSE2 + + // Enable SSE4.2 optimization. + #define RAPIDJSON_SSE42 + \endcode + + \c RAPIDJSON_SSE42 takes precedence, if both are defined. + + If any of these symbols is defined, RapidJSON defines the macro + \c RAPIDJSON_SIMD to indicate the availability of the optimized code. +*/ +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \ + || defined(RAPIDJSON_DOXYGEN_RUNNING) +#define RAPIDJSON_SIMD +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_SIZETYPEDEFINE + +#ifndef RAPIDJSON_NO_SIZETYPEDEFINE +/*! \def RAPIDJSON_NO_SIZETYPEDEFINE + \ingroup RAPIDJSON_CONFIG + \brief User-provided \c SizeType definition. + + In order to avoid using 32-bit size types for indexing strings and arrays, + define this preprocessor symbol and provide the type rapidjson::SizeType + before including RapidJSON: + \code + #define RAPIDJSON_NO_SIZETYPEDEFINE + namespace rapidjson { typedef ::std::size_t SizeType; } + #include "rapidjson/..." + \endcode + + \see rapidjson::SizeType +*/ +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_SIZETYPEDEFINE +#endif +RAPIDJSON_NAMESPACE_BEGIN +//! Size type (for string lengths, array sizes, etc.) +/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms, + instead of using \c size_t. Users may override the SizeType by defining + \ref RAPIDJSON_NO_SIZETYPEDEFINE. +*/ +typedef unsigned SizeType; +RAPIDJSON_NAMESPACE_END +#endif + +// always import std::size_t to rapidjson namespace +RAPIDJSON_NAMESPACE_BEGIN +using std::size_t; +RAPIDJSON_NAMESPACE_END + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ASSERT + +//! Assertion. +/*! \ingroup RAPIDJSON_CONFIG + By default, rapidjson uses C \c assert() for internal assertions. + User can override it by defining RAPIDJSON_ASSERT(x) macro. + + \note Parsing errors are handled and can be customized by the + \ref RAPIDJSON_ERRORS APIs. +*/ +#ifndef RAPIDJSON_ASSERT +#include +#define RAPIDJSON_ASSERT(x) assert(x) +#endif // RAPIDJSON_ASSERT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_STATIC_ASSERT + +// Adopt from boost +#ifndef RAPIDJSON_STATIC_ASSERT +#ifndef __clang__ +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#endif +RAPIDJSON_NAMESPACE_BEGIN +template struct STATIC_ASSERTION_FAILURE; +template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; +template struct StaticAssertTest {}; +RAPIDJSON_NAMESPACE_END + +#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) +#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) +#define RAPIDJSON_DO_JOIN2(X, Y) X##Y + +#if defined(__GNUC__) +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) +#else +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif +#ifndef __clang__ +//!@endcond +#endif + +/*! \def RAPIDJSON_STATIC_ASSERT + \brief (Internal) macro to check for conditions at compile-time + \param x compile-time condition + \hideinitializer + */ +#define RAPIDJSON_STATIC_ASSERT(x) \ + typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \ + sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE)> \ + RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY + +//! Compiler branching hint for expression with high probability to be true. +/*! + \ingroup RAPIDJSON_CONFIG + \param x Boolean expression likely to be true. +*/ +#ifndef RAPIDJSON_LIKELY +#if defined(__GNUC__) || defined(__clang__) +#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1) +#else +#define RAPIDJSON_LIKELY(x) (x) +#endif +#endif + +//! Compiler branching hint for expression with low probability to be true. +/*! + \ingroup RAPIDJSON_CONFIG + \param x Boolean expression unlikely to be true. +*/ +#ifndef RAPIDJSON_UNLIKELY +#if defined(__GNUC__) || defined(__clang__) +#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define RAPIDJSON_UNLIKELY(x) (x) +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Helpers + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN + +#define RAPIDJSON_MULTILINEMACRO_BEGIN do { +#define RAPIDJSON_MULTILINEMACRO_END \ +} while((void)0, 0) + +// adopted from Boost +#define RAPIDJSON_VERSION_CODE(x,y,z) \ + (((x)*100000) + ((y)*100) + (z)) + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF + +#if defined(__GNUC__) +#define RAPIDJSON_GNUC \ + RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) +#endif + +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0)) + +#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x)) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x) +#define RAPIDJSON_DIAG_OFF(x) \ + RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x))) + +// push/pop support in Clang and GCC>=4.6 +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) +#else // GCC >= 4.2, < 4.6 +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ +#endif + +#elif defined(_MSC_VER) + +// pragma (MSVC specific) +#define RAPIDJSON_PRAGMA(x) __pragma(x) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x)) + +#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) + +#else + +#define RAPIDJSON_DIAG_OFF(x) /* ignored */ +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ + +#endif // RAPIDJSON_DIAG_* + +/////////////////////////////////////////////////////////////////////////////// +// C++11 features + +#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS +#if defined(__clang__) +#if __has_feature(cxx_rvalue_references) && \ + (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306) +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#else +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 +#endif +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1600) + +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#else +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 +#endif +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + +#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT +#if defined(__clang__) +#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) +// (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 +#else +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0 +#endif +#endif +#if RAPIDJSON_HAS_CXX11_NOEXCEPT +#define RAPIDJSON_NOEXCEPT noexcept +#else +#define RAPIDJSON_NOEXCEPT /* noexcept */ +#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT + +// no automatic detection, yet +#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS +#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 +#endif + +#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR +#if defined(__clang__) +#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1700) +#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1 +#else +#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0 +#endif +#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR + +//!@endcond + +/////////////////////////////////////////////////////////////////////////////// +// new/delete + +#ifndef RAPIDJSON_NEW +///! customization point for global \c new +#define RAPIDJSON_NEW(x) new x +#endif +#ifndef RAPIDJSON_DELETE +///! customization point for global \c delete +#define RAPIDJSON_DELETE(x) delete x +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Type + +/*! \namespace rapidjson + \brief main RapidJSON namespace + \see RAPIDJSON_NAMESPACE +*/ +RAPIDJSON_NAMESPACE_BEGIN + +//! Type of JSON value +enum Type { + kNullType = 0, //!< null + kFalseType = 1, //!< false + kTrueType = 2, //!< true + kObjectType = 3, //!< object + kArrayType = 4, //!< array + kStringType = 5, //!< string + kNumberType = 6 //!< number +}; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/reader.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/reader.h new file mode 100644 index 0000000000..19f8849b14 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/reader.h @@ -0,0 +1,1879 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_READER_H_ +#define RAPIDJSON_READER_H_ + +/*! \file reader.h */ + +#include "allocators.h" +#include "stream.h" +#include "encodedstream.h" +#include "internal/meta.h" +#include "internal/stack.h" +#include "internal/strtod.h" +#include + +#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) +#include +#pragma intrinsic(_BitScanForward) +#endif +#ifdef RAPIDJSON_SSE42 +#include +#elif defined(RAPIDJSON_SSE2) +#include +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(old-style-cast) +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define RAPIDJSON_NOTHING /* deliberately empty */ +#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \ + RAPIDJSON_MULTILINEMACRO_END +#endif +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING) +//!@endcond + +/*! \def RAPIDJSON_PARSE_ERROR_NORETURN + \ingroup RAPIDJSON_ERRORS + \brief Macro to indicate a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + This macros can be used as a customization point for the internal + error handling mechanism of RapidJSON. + + A common usage model is to throw an exception instead of requiring the + caller to explicitly check the \ref rapidjson::GenericReader::Parse's + return value: + + \code + #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \ + throw ParseException(parseErrorCode, #parseErrorCode, offset) + + #include // std::runtime_error + #include "rapidjson/error/error.h" // rapidjson::ParseResult + + struct ParseException : std::runtime_error, rapidjson::ParseResult { + ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset) + : std::runtime_error(msg), ParseResult(code, offset) {} + }; + + #include "rapidjson/reader.h" + \endcode + + \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse + */ +#ifndef RAPIDJSON_PARSE_ERROR_NORETURN +#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \ + SetParseError(parseErrorCode, offset); \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +/*! \def RAPIDJSON_PARSE_ERROR + \ingroup RAPIDJSON_ERRORS + \brief (Internal) macro to indicate and handle a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing. + + \see RAPIDJSON_PARSE_ERROR_NORETURN + \hideinitializer + */ +#ifndef RAPIDJSON_PARSE_ERROR +#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +#include "error/error.h" // ParseErrorCode, ParseResult + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// ParseFlag + +/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kParseDefaultFlags definition. + + User can define this as any \c ParseFlag combinations. +*/ +#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS +#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags +#endif + +//! Combination of parseFlags +/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream + */ +enum ParseFlag { + kParseNoFlags = 0, //!< No flags are set. + kParseInsituFlag = 1, //!< In-situ(destructive) parsing. + kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings. + kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing. + kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error. + kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower). + kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments. + kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings. + kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays. + kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles. + kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS +}; + +/////////////////////////////////////////////////////////////////////////////// +// Handler + +/*! \class rapidjson::Handler + \brief Concept for receiving events from GenericReader upon parsing. + The functions return true if no error occurs. If they return false, + the event publisher should terminate the process. +\code +concept Handler { + typename Ch; + + bool Null(); + bool Bool(bool b); + bool Int(int i); + bool Uint(unsigned i); + bool Int64(int64_t i); + bool Uint64(uint64_t i); + bool Double(double d); + /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) + bool RawNumber(const Ch* str, SizeType length, bool copy); + bool String(const Ch* str, SizeType length, bool copy); + bool StartObject(); + bool Key(const Ch* str, SizeType length, bool copy); + bool EndObject(SizeType memberCount); + bool StartArray(); + bool EndArray(SizeType elementCount); +}; +\endcode +*/ +/////////////////////////////////////////////////////////////////////////////// +// BaseReaderHandler + +//! Default implementation of Handler. +/*! This can be used as base class of any reader handler. + \note implements Handler concept +*/ +template, typename Derived = void> +struct BaseReaderHandler { + typedef typename Encoding::Ch Ch; + + typedef typename internal::SelectIf, BaseReaderHandler, Derived>::Type Override; + + bool Default() { return true; } + bool Null() { return static_cast(*this).Default(); } + bool Bool(bool) { return static_cast(*this).Default(); } + bool Int(int) { return static_cast(*this).Default(); } + bool Uint(unsigned) { return static_cast(*this).Default(); } + bool Int64(int64_t) { return static_cast(*this).Default(); } + bool Uint64(uint64_t) { return static_cast(*this).Default(); } + bool Double(double) { return static_cast(*this).Default(); } + /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) + bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } + bool String(const Ch*, SizeType, bool) { return static_cast(*this).Default(); } + bool StartObject() { return static_cast(*this).Default(); } + bool Key(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } + bool EndObject(SizeType) { return static_cast(*this).Default(); } + bool StartArray() { return static_cast(*this).Default(); } + bool EndArray(SizeType) { return static_cast(*this).Default(); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// StreamLocalCopy + +namespace internal { + +template::copyOptimization> +class StreamLocalCopy; + +//! Do copy optimization. +template +class StreamLocalCopy { +public: + StreamLocalCopy(Stream& original) : s(original), original_(original) {} + ~StreamLocalCopy() { original_ = s; } + + Stream s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; + + Stream& original_; +}; + +//! Keep reference. +template +class StreamLocalCopy { +public: + StreamLocalCopy(Stream& original) : s(original) {} + + Stream& s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; +}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// SkipWhitespace + +//! Skip the JSON white spaces in a stream. +/*! \param is A input stream for skipping white spaces. + \note This function has SSE2/SSE4.2 specialization. +*/ +template +void SkipWhitespace(InputStream& is) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + typename InputStream::Ch c; + while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t') + s.Take(); +} + +inline const char* SkipWhitespace(const char* p, const char* end) { + while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + return p; +} + +#ifdef RAPIDJSON_SSE42 +//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string using SIMD + static const char whitespace[16] = " \n\r\t"; + const __m128i w = _mm_loadu_si128(reinterpret_cast(&whitespace[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); + if (r != 0) { // some of characters is non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } +} + +inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { + // Fast return for single non-whitespace + if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + else + return p; + + // The middle of string using SIMD + static const char whitespace[16] = " \n\r\t"; + const __m128i w = _mm_loadu_si128(reinterpret_cast(&whitespace[0])); + + for (; p <= end - 16; p += 16) { + const __m128i s = _mm_loadu_si128(reinterpret_cast(p)); + const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); + if (r != 0) { // some of characters is non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } + + return SkipWhitespace(p, end); +} + +#elif defined(RAPIDJSON_SSE2) + +//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string + #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } + static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; + #undef C16 + + const __m128i w0 = _mm_loadu_si128(reinterpret_cast(&whitespaces[0][0])); + const __m128i w1 = _mm_loadu_si128(reinterpret_cast(&whitespaces[1][0])); + const __m128i w2 = _mm_loadu_si128(reinterpret_cast(&whitespaces[2][0])); + const __m128i w3 = _mm_loadu_si128(reinterpret_cast(&whitespaces[3][0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = static_cast(~_mm_movemask_epi8(x)); + if (r != 0) { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } +} + +inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { + // Fast return for single non-whitespace + if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + else + return p; + + // The rest of string + #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } + static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; + #undef C16 + + const __m128i w0 = _mm_loadu_si128(reinterpret_cast(&whitespaces[0][0])); + const __m128i w1 = _mm_loadu_si128(reinterpret_cast(&whitespaces[1][0])); + const __m128i w2 = _mm_loadu_si128(reinterpret_cast(&whitespaces[2][0])); + const __m128i w3 = _mm_loadu_si128(reinterpret_cast(&whitespaces[3][0])); + + for (; p <= end - 16; p += 16) { + const __m128i s = _mm_loadu_si128(reinterpret_cast(p)); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = static_cast(~_mm_movemask_epi8(x)); + if (r != 0) { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } + + return SkipWhitespace(p, end); +} + +#endif // RAPIDJSON_SSE2 + +#ifdef RAPIDJSON_SIMD +//! Template function specialization for InsituStringStream +template<> inline void SkipWhitespace(InsituStringStream& is) { + is.src_ = const_cast(SkipWhitespace_SIMD(is.src_)); +} + +//! Template function specialization for StringStream +template<> inline void SkipWhitespace(StringStream& is) { + is.src_ = SkipWhitespace_SIMD(is.src_); +} + +template<> inline void SkipWhitespace(EncodedInputStream, MemoryStream>& is) { + is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_); +} +#endif // RAPIDJSON_SIMD + +/////////////////////////////////////////////////////////////////////////////// +// GenericReader + +//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator. +/*! GenericReader parses JSON text from a stream, and send events synchronously to an + object implementing Handler concept. + + It needs to allocate a stack for storing a single decoded string during + non-destructive parsing. + + For in-situ parsing, the decoded string is directly written to the source + text string, no temporary buffer is required. + + A GenericReader object can be reused for parsing multiple JSON text. + + \tparam SourceEncoding Encoding of the input stream. + \tparam TargetEncoding Encoding of the parse output. + \tparam StackAllocator Allocator type for stack. +*/ +template +class GenericReader { +public: + typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type + + //! Constructor. + /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) + \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) + */ + GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {} + + //! Parse JSON text. + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept. + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + ParseResult Parse(InputStream& is, Handler& handler) { + if (parseFlags & kParseIterativeFlag) + return IterativeParse(is, handler); + + parseResult_.Clear(); + + ClearStackOnExit scope(*this); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + else { + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (!(parseFlags & kParseStopWhenDoneFlag)) { + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + } + } + + return parseResult_; + } + + //! Parse JSON text (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + ParseResult Parse(InputStream& is, Handler& handler) { + return Parse(is, handler); + } + + //! Whether a parse error has occured in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + +protected: + void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); } + +private: + // Prohibit copy constructor & assignment operator. + GenericReader(const GenericReader&); + GenericReader& operator=(const GenericReader&); + + void ClearStack() { stack_.Clear(); } + + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericReader& r) : r_(r) {} + ~ClearStackOnExit() { r_.ClearStack(); } + private: + GenericReader& r_; + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + }; + + template + void SkipWhitespaceAndComments(InputStream& is) { + SkipWhitespace(is); + + if (parseFlags & kParseCommentsFlag) { + while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) { + if (Consume(is, '*')) { + while (true) { + if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) + RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); + else if (Consume(is, '*')) { + if (Consume(is, '/')) + break; + } + else + is.Take(); + } + } + else if (RAPIDJSON_LIKELY(Consume(is, '/'))) + while (is.Peek() != '\0' && is.Take() != '\n'); + else + RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); + + SkipWhitespace(is); + } + } + } + + // Parse object: { string : value, ... } + template + void ParseObject(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '{'); + is.Take(); // Skip '{' + + if (RAPIDJSON_UNLIKELY(!handler.StartObject())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, '}')) { + if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType memberCount = 0;;) { + if (RAPIDJSON_UNLIKELY(is.Peek() != '"')) + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); + + ParseString(is, handler, true); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (RAPIDJSON_UNLIKELY(!Consume(is, ':'))) + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ++memberCount; + + switch (is.Peek()) { + case ',': + is.Take(); + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + break; + case '}': + is.Take(); + if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + default: + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy + } + + if (parseFlags & kParseTrailingCommasFlag) { + if (is.Peek() == '}') { + if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + is.Take(); + return; + } + } + } + } + + // Parse array: [ value, ... ] + template + void ParseArray(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '['); + is.Take(); // Skip '[' + + if (RAPIDJSON_UNLIKELY(!handler.StartArray())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, ']')) { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType elementCount = 0;;) { + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ++elementCount; + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, ',')) { + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + } + else if (Consume(is, ']')) { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); + + if (parseFlags & kParseTrailingCommasFlag) { + if (is.Peek() == ']') { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + is.Take(); + return; + } + } + } + } + + template + void ParseNull(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'n'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) { + if (RAPIDJSON_UNLIKELY(!handler.Null())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + void ParseTrue(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 't'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) { + if (RAPIDJSON_UNLIKELY(!handler.Bool(true))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + void ParseFalse(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'f'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) { + if (RAPIDJSON_UNLIKELY(!handler.Bool(false))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) { + if (RAPIDJSON_LIKELY(is.Peek() == expect)) { + is.Take(); + return true; + } + else + return false; + } + + // Helper function to parse four hexidecimal digits in \uXXXX in ParseString(). + template + unsigned ParseHex4(InputStream& is, size_t escapeOffset) { + unsigned codepoint = 0; + for (int i = 0; i < 4; i++) { + Ch c = is.Peek(); + codepoint <<= 4; + codepoint += static_cast(c); + if (c >= '0' && c <= '9') + codepoint -= '0'; + else if (c >= 'A' && c <= 'F') + codepoint -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + codepoint -= 'a' - 10; + else { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0); + } + is.Take(); + } + return codepoint; + } + + template + class StackStream { + public: + typedef CharType Ch; + + StackStream(internal::Stack& stack) : stack_(stack), length_(0) {} + RAPIDJSON_FORCEINLINE void Put(Ch c) { + *stack_.template Push() = c; + ++length_; + } + + RAPIDJSON_FORCEINLINE void* Push(SizeType count) { + length_ += count; + return stack_.template Push(count); + } + + size_t Length() const { return length_; } + + Ch* Pop() { + return stack_.template Pop(length_); + } + + private: + StackStream(const StackStream&); + StackStream& operator=(const StackStream&); + + internal::Stack& stack_; + SizeType length_; + }; + + // Parse string and generate String event. Different code paths for kParseInsituFlag. + template + void ParseString(InputStream& is, Handler& handler, bool isKey = false) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + RAPIDJSON_ASSERT(s.Peek() == '\"'); + s.Take(); // Skip '\"' + + bool success = false; + if (parseFlags & kParseInsituFlag) { + typename InputStream::Ch *head = s.PutBegin(); + ParseStringToStream(s, s); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + size_t length = s.PutEnd(head) - 1; + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + const typename TargetEncoding::Ch* const str = reinterpret_cast(head); + success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false)); + } + else { + StackStream stackStream(stack_); + ParseStringToStream(s, stackStream); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + SizeType length = static_cast(stackStream.Length()) - 1; + const typename TargetEncoding::Ch* const str = stackStream.Pop(); + success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true)); + } + if (RAPIDJSON_UNLIKELY(!success)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); + } + + // Parse string to an output is + // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. + template + RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) { +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + static const char escape[256] = { + Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', + Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, + 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, + 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 + }; +#undef Z16 +//!@endcond + + for (;;) { + // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation. + if (!(parseFlags & kParseValidateEncodingFlag)) + ScanCopyUnescapedString(is, os); + + Ch c = is.Peek(); + if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape + size_t escapeOffset = is.Tell(); // For invalid escaping, report the inital '\\' as error offset + is.Take(); + Ch e = is.Peek(); + if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast(e)])) { + is.Take(); + os.Put(static_cast(escape[static_cast(e)])); + } + else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode + is.Take(); + unsigned codepoint = ParseHex4(is, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) { + // Handle UTF-16 surrogate pair + if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u'))) + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); + unsigned codepoint2 = ParseHex4(is, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)) + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); + codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; + } + TEncoding::Encode(os, codepoint); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset); + } + else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote + is.Take(); + os.Put('\0'); // null-terminate the string + return; + } + else if (RAPIDJSON_UNLIKELY(static_cast(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF + if (c == '\0') + RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell()); + else + RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell()); + } + else { + size_t offset = is.Tell(); + if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ? + !Transcoder::Validate(is, os) : + !Transcoder::Transcode(is, os)))) + RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset); + } + } + } + + template + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) { + // Do nothing for generic version + } + +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) + // StringStream -> StackStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream& os) { + const char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + return; + } + else + os.Put(*p++); + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + SizeType length; + #ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; + #else + length = static_cast(__builtin_ffs(r) - 1); + #endif + char* q = reinterpret_cast(os.Push(length)); + for (size_t i = 0; i < length; i++) + q[i] = p[i]; + + p += length; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s); + } + + is.src_ = p; + } + + // InsituStringStream -> InsituStringStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) { + RAPIDJSON_ASSERT(&is == &os); + (void)os; + + if (is.src_ == is.dst_) { + SkipUnescapedString(is); + return; + } + + char* p = is.src_; + char *q = is.dst_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + is.dst_ = q; + return; + } + else + *q++ = *p++; + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16, q += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + size_t length; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; +#else + length = static_cast(__builtin_ffs(r) - 1); +#endif + for (const char* pend = p + length; p != pend; ) + *q++ = *p++; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s); + } + + is.src_ = p; + is.dst_ = q; + } + + // When read/write pointers are the same for insitu stream, just skip unescaped characters + static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) { + RAPIDJSON_ASSERT(is.src_ == is.dst_); + char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + for (; p != nextAligned; p++) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = is.dst_ = p; + return; + } + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + size_t length; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; +#else + length = static_cast(__builtin_ffs(r) - 1); +#endif + p += length; + break; + } + } + + is.src_ = is.dst_ = p; + } +#endif + + template + class NumberStream; + + template + class NumberStream { + public: + typedef typename InputStream::Ch Ch; + + NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; } + ~NumberStream() {} + + RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); } + RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); } + RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); } + RAPIDJSON_FORCEINLINE void Push(char) {} + + size_t Tell() { return is.Tell(); } + size_t Length() { return 0; } + const char* Pop() { return 0; } + + protected: + NumberStream& operator=(const NumberStream&); + + InputStream& is; + }; + + template + class NumberStream : public NumberStream { + typedef NumberStream Base; + public: + NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {} + ~NumberStream() {} + + RAPIDJSON_FORCEINLINE Ch TakePush() { + stackStream.Put(static_cast(Base::is.Peek())); + return Base::is.Take(); + } + + RAPIDJSON_FORCEINLINE void Push(char c) { + stackStream.Put(c); + } + + size_t Length() { return stackStream.Length(); } + + const char* Pop() { + stackStream.Put('\0'); + return stackStream.Pop(); + } + + private: + StackStream stackStream; + }; + + template + class NumberStream : public NumberStream { + typedef NumberStream Base; + public: + NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {} + ~NumberStream() {} + + RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); } + }; + + template + void ParseNumber(InputStream& is, Handler& handler) { + internal::StreamLocalCopy copy(is); + NumberStream s(*this, copy.s); + + size_t startOffset = s.Tell(); + double d = 0.0; + bool useNanOrInf = false; + + // Parse minus + bool minus = Consume(s, '-'); + + // Parse int: zero / ( digit1-9 *DIGIT ) + unsigned i = 0; + uint64_t i64 = 0; + bool use64bit = false; + int significandDigit = 0; + if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) { + i = 0; + s.TakePush(); + } + else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) { + i = static_cast(s.TakePush() - '0'); + + if (minus) + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648 + if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + else + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295 + if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + } + // Parse NaN or Infinity here + else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) { + useNanOrInf = true; + if (RAPIDJSON_LIKELY(Consume(s, 'N') && Consume(s, 'a') && Consume(s, 'N'))) { + d = std::numeric_limits::quiet_NaN(); + } + else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) { + d = (minus ? -std::numeric_limits::infinity() : std::numeric_limits::infinity()); + if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n') + && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + + // Parse 64bit int + bool useDouble = false; + if (use64bit) { + if (minus) + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808 + if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) { + d = static_cast(i64); + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + else + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615 + if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) { + d = static_cast(i64); + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + } + + // Force double for big integer + if (useDouble) { + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0 + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); + d = d * 10 + (s.TakePush() - '0'); + } + } + + // Parse frac = decimal-point 1*DIGIT + int expFrac = 0; + size_t decimalPosition; + if (Consume(s, '.')) { + decimalPosition = s.Length(); + + if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9'))) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell()); + + if (!useDouble) { +#if RAPIDJSON_64BIT + // Use i64 to store significand in 64-bit architecture + if (!use64bit) + i64 = i; + + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path + break; + else { + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + --expFrac; + if (i64 != 0) + significandDigit++; + } + } + + d = static_cast(i64); +#else + // Use double to store significand in 32-bit architecture + d = static_cast(use64bit ? i64 : i); +#endif + useDouble = true; + } + + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (significandDigit < 17) { + d = d * 10.0 + (s.TakePush() - '0'); + --expFrac; + if (RAPIDJSON_LIKELY(d > 0.0)) + significandDigit++; + } + else + s.TakePush(); + } + } + else + decimalPosition = s.Length(); // decimal position at the end of integer. + + // Parse exp = e [ minus / plus ] 1*DIGIT + int exp = 0; + if (Consume(s, 'e') || Consume(s, 'E')) { + if (!useDouble) { + d = static_cast(use64bit ? i64 : i); + useDouble = true; + } + + bool expMinus = false; + if (Consume(s, '+')) + ; + else if (Consume(s, '-')) + expMinus = true; + + if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = static_cast(s.Take() - '0'); + if (expMinus) { + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = exp * 10 + static_cast(s.Take() - '0'); + if (exp >= 214748364) { // Issue #313: prevent overflow exponent + while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent + s.Take(); + } + } + } + else { // positive exp + int maxExp = 308 - expFrac; + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = exp * 10 + static_cast(s.Take() - '0'); + if (RAPIDJSON_UNLIKELY(exp > maxExp)) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); + } + } + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell()); + + if (expMinus) + exp = -exp; + } + + // Finish parsing, call event according to the type of number. + bool cont = true; + + if (parseFlags & kParseNumbersAsStringsFlag) { + if (parseFlags & kParseInsituFlag) { + s.Pop(); // Pop stack no matter if it will be used or not. + typename InputStream::Ch* head = is.PutBegin(); + const size_t length = s.Tell() - startOffset; + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + // unable to insert the \0 character here, it will erase the comma after this number + const typename TargetEncoding::Ch* const str = reinterpret_cast(head); + cont = handler.RawNumber(str, SizeType(length), false); + } + else { + SizeType numCharsToCopy = static_cast(s.Length()); + StringStream srcStream(s.Pop()); + StackStream dstStream(stack_); + while (numCharsToCopy--) { + Transcoder, TargetEncoding>::Transcode(srcStream, dstStream); + } + dstStream.Put('\0'); + const typename TargetEncoding::Ch* str = dstStream.Pop(); + const SizeType length = static_cast(dstStream.Length()) - 1; + cont = handler.RawNumber(str, SizeType(length), true); + } + } + else { + size_t length = s.Length(); + const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not. + + if (useDouble) { + int p = exp + expFrac; + if (parseFlags & kParseFullPrecisionFlag) + d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp); + else + d = internal::StrtodNormalPrecision(d, p); + + cont = handler.Double(minus ? -d : d); + } + else if (useNanOrInf) { + cont = handler.Double(d); + } + else { + if (use64bit) { + if (minus) + cont = handler.Int64(static_cast(~i64 + 1)); + else + cont = handler.Uint64(i64); + } + else { + if (minus) + cont = handler.Int(static_cast(~i + 1)); + else + cont = handler.Uint(i); + } + } + } + if (RAPIDJSON_UNLIKELY(!cont)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset); + } + + // Parse any JSON value + template + void ParseValue(InputStream& is, Handler& handler) { + switch (is.Peek()) { + case 'n': ParseNull (is, handler); break; + case 't': ParseTrue (is, handler); break; + case 'f': ParseFalse (is, handler); break; + case '"': ParseString(is, handler); break; + case '{': ParseObject(is, handler); break; + case '[': ParseArray (is, handler); break; + default : + ParseNumber(is, handler); + break; + + } + } + + // Iterative Parsing + + // States + enum IterativeParsingState { + IterativeParsingStartState = 0, + IterativeParsingFinishState, + IterativeParsingErrorState, + + // Object states + IterativeParsingObjectInitialState, + IterativeParsingMemberKeyState, + IterativeParsingKeyValueDelimiterState, + IterativeParsingMemberValueState, + IterativeParsingMemberDelimiterState, + IterativeParsingObjectFinishState, + + // Array states + IterativeParsingArrayInitialState, + IterativeParsingElementState, + IterativeParsingElementDelimiterState, + IterativeParsingArrayFinishState, + + // Single value state + IterativeParsingValueState + }; + + enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 }; + + // Tokens + enum Token { + LeftBracketToken = 0, + RightBracketToken, + + LeftCurlyBracketToken, + RightCurlyBracketToken, + + CommaToken, + ColonToken, + + StringToken, + FalseToken, + TrueToken, + NullToken, + NumberToken, + + kTokenCount + }; + + RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) { + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define N NumberToken +#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N + // Maps from ASCII to Token + static const unsigned char tokenMap[256] = { + N16, // 00~0F + N16, // 10~1F + N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F + N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F + N16, // 40~4F + N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F + N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F + N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F + N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF + }; +#undef N +#undef N16 +//!@endcond + + if (sizeof(Ch) == 1 || static_cast(c) < 256) + return static_cast(tokenMap[static_cast(c)]); + else + return NumberToken; + } + + RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) { + // current state x one lookahead token -> new state + static const char G[cIterativeParsingStateCount][kTokenCount] = { + // Start + { + IterativeParsingArrayInitialState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingValueState, // String + IterativeParsingValueState, // False + IterativeParsingValueState, // True + IterativeParsingValueState, // Null + IterativeParsingValueState // Number + }, + // Finish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Error(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ObjectInitial + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberKey + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingKeyValueDelimiterState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // KeyValueDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push MemberValue state) + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberValueState, // String + IterativeParsingMemberValueState, // False + IterativeParsingMemberValueState, // True + IterativeParsingMemberValueState, // Null + IterativeParsingMemberValueState // Number + }, + // MemberValue + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingMemberDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberDelimiter + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ObjectFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ArrayInitial + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // Element + { + IterativeParsingErrorState, // Left bracket + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingElementDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ElementDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // ArrayFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Single Value (sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + } + }; // End of G + + return static_cast(G[state][token]); + } + + // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit(). + // May return a new state on state pop. + template + RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) { + (void)token; + + switch (dst) { + case IterativeParsingErrorState: + return dst; + + case IterativeParsingObjectInitialState: + case IterativeParsingArrayInitialState: + { + // Push the state(Element or MemeberValue) if we are nested in another array or value of member. + // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop. + IterativeParsingState n = src; + if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState) + n = IterativeParsingElementState; + else if (src == IterativeParsingKeyValueDelimiterState) + n = IterativeParsingMemberValueState; + // Push current state. + *stack_.template Push(1) = n; + // Initialize and push the member/element count. + *stack_.template Push(1) = 0; + // Call handler + bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray(); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return dst; + } + } + + case IterativeParsingMemberKeyState: + ParseString(is, handler, true); + if (HasParseError()) + return IterativeParsingErrorState; + else + return dst; + + case IterativeParsingKeyValueDelimiterState: + RAPIDJSON_ASSERT(token == ColonToken); + is.Take(); + return dst; + + case IterativeParsingMemberValueState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingElementState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingMemberDelimiterState: + case IterativeParsingElementDelimiterState: + is.Take(); + // Update member/element count. + *stack_.template Top() = *stack_.template Top() + 1; + return dst; + + case IterativeParsingObjectFinishState: + { + // Transit from delimiter is only allowed when trailing commas are enabled + if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell()); + return IterativeParsingErrorState; + } + // Get member count. + SizeType c = *stack_.template Pop(1); + // If the object is not empty, count the last member. + if (src == IterativeParsingMemberValueState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast(*stack_.template Pop(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndObject(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + case IterativeParsingArrayFinishState: + { + // Transit from delimiter is only allowed when trailing commas are enabled + if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell()); + return IterativeParsingErrorState; + } + // Get element count. + SizeType c = *stack_.template Pop(1); + // If the array is not empty, count the last element. + if (src == IterativeParsingElementState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast(*stack_.template Pop(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndArray(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + default: + // This branch is for IterativeParsingValueState actually. + // Use `default:` rather than + // `case IterativeParsingValueState:` is for code coverage. + + // The IterativeParsingStartState is not enumerated in this switch-case. + // It is impossible for that case. And it can be caught by following assertion. + + // The IterativeParsingFinishState is not enumerated in this switch-case either. + // It is a "derivative" state which cannot triggered from Predict() directly. + // Therefore it cannot happen here. And it can be caught by following assertion. + RAPIDJSON_ASSERT(dst == IterativeParsingValueState); + + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return IterativeParsingFinishState; + } + } + + template + void HandleError(IterativeParsingState src, InputStream& is) { + if (HasParseError()) { + // Error flag has been set. + return; + } + + switch (src) { + case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return; + case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return; + case IterativeParsingObjectInitialState: + case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return; + case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return; + case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return; + case IterativeParsingKeyValueDelimiterState: + case IterativeParsingArrayInitialState: + case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return; + default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return; + } + } + + template + ParseResult IterativeParse(InputStream& is, Handler& handler) { + parseResult_.Clear(); + ClearStackOnExit scope(*this); + IterativeParsingState state = IterativeParsingStartState; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + while (is.Peek() != '\0') { + Token t = Tokenize(is.Peek()); + IterativeParsingState n = Predict(state, t); + IterativeParsingState d = Transit(state, t, n, is, handler); + + if (d == IterativeParsingErrorState) { + HandleError(state, is); + break; + } + + state = d; + + // Do not further consume streams if a root JSON has been parsed. + if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState) + break; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + + // Handle the end of file. + if (state != IterativeParsingFinishState) + HandleError(state, is); + + return parseResult_; + } + + static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. + internal::Stack stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. + ParseResult parseResult_; +}; // class GenericReader + +//! Reader with UTF8 encoding and default allocator. +typedef GenericReader, UTF8<> > Reader; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_READER_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/schema.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/schema.h new file mode 100644 index 0000000000..b182aa27f0 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/schema.h @@ -0,0 +1,2006 @@ +// Tencent is pleased to support the open source community by making RapidJSON available-> +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip-> All rights reserved-> +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License-> You may obtain a copy of the License at +// +// http://opensource->org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied-> See the License for the +// specific language governing permissions and limitations under the License-> + +#ifndef RAPIDJSON_SCHEMA_H_ +#define RAPIDJSON_SCHEMA_H_ + +#include "document.h" +#include "pointer.h" +#include // abs, floor + +#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX) +#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1 +#else +#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0 +#endif + +#if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && !defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)) +#define RAPIDJSON_SCHEMA_USE_STDREGEX 1 +#else +#define RAPIDJSON_SCHEMA_USE_STDREGEX 0 +#endif + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX +#include "internal/regex.h" +#elif RAPIDJSON_SCHEMA_USE_STDREGEX +#include +#endif + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX +#define RAPIDJSON_SCHEMA_HAS_REGEX 1 +#else +#define RAPIDJSON_SCHEMA_HAS_REGEX 0 +#endif + +#ifndef RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_SCHEMA_VERBOSE 0 +#endif + +#if RAPIDJSON_SCHEMA_VERBOSE +#include "stringbuffer.h" +#endif + +RAPIDJSON_DIAG_PUSH + +#if defined(__GNUC__) +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_OFF(weak-vtables) +RAPIDJSON_DIAG_OFF(exit-time-destructors) +RAPIDJSON_DIAG_OFF(c++98-compat-pedantic) +RAPIDJSON_DIAG_OFF(variadic-macros) +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Verbose Utilities + +#if RAPIDJSON_SCHEMA_VERBOSE + +namespace internal { + +inline void PrintInvalidKeyword(const char* keyword) { + printf("Fail keyword: %s\n", keyword); +} + +inline void PrintInvalidKeyword(const wchar_t* keyword) { + wprintf(L"Fail keyword: %ls\n", keyword); +} + +inline void PrintInvalidDocument(const char* document) { + printf("Fail document: %s\n\n", document); +} + +inline void PrintInvalidDocument(const wchar_t* document) { + wprintf(L"Fail document: %ls\n\n", document); +} + +inline void PrintValidatorPointers(unsigned depth, const char* s, const char* d) { + printf("S: %*s%s\nD: %*s%s\n\n", depth * 4, " ", s, depth * 4, " ", d); +} + +inline void PrintValidatorPointers(unsigned depth, const wchar_t* s, const wchar_t* d) { + wprintf(L"S: %*ls%ls\nD: %*ls%ls\n\n", depth * 4, L" ", s, depth * 4, L" ", d); +} + +} // namespace internal + +#endif // RAPIDJSON_SCHEMA_VERBOSE + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_INVALID_KEYWORD_RETURN + +#if RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword) +#else +#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) +#endif + +#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\ +RAPIDJSON_MULTILINEMACRO_BEGIN\ + context.invalidKeyword = keyword.GetString();\ + RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\ + return false;\ +RAPIDJSON_MULTILINEMACRO_END + +/////////////////////////////////////////////////////////////////////////////// +// Forward declarations + +template +class GenericSchemaDocument; + +namespace internal { + +template +class Schema; + +/////////////////////////////////////////////////////////////////////////////// +// ISchemaValidator + +class ISchemaValidator { +public: + virtual ~ISchemaValidator() {} + virtual bool IsValid() const = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// ISchemaStateFactory + +template +class ISchemaStateFactory { +public: + virtual ~ISchemaStateFactory() {} + virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0; + virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0; + virtual void* CreateHasher() = 0; + virtual uint64_t GetHashCode(void* hasher) = 0; + virtual void DestroryHasher(void* hasher) = 0; + virtual void* MallocState(size_t size) = 0; + virtual void FreeState(void* p) = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Hasher + +// For comparison of compound value +template +class Hasher { +public: + typedef typename Encoding::Ch Ch; + + Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {} + + bool Null() { return WriteType(kNullType); } + bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); } + bool Int(int i) { Number n; n.u.i = i; n.d = static_cast(i); return WriteNumber(n); } + bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast(u); return WriteNumber(n); } + bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast(i); return WriteNumber(n); } + bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast(u); return WriteNumber(n); } + bool Double(double d) { + Number n; + if (d < 0) n.u.i = static_cast(d); + else n.u.u = static_cast(d); + n.d = d; + return WriteNumber(n); + } + + bool RawNumber(const Ch* str, SizeType len, bool) { + WriteBuffer(kNumberType, str, len * sizeof(Ch)); + return true; + } + + bool String(const Ch* str, SizeType len, bool) { + WriteBuffer(kStringType, str, len * sizeof(Ch)); + return true; + } + + bool StartObject() { return true; } + bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); } + bool EndObject(SizeType memberCount) { + uint64_t h = Hash(0, kObjectType); + uint64_t* kv = stack_.template Pop(memberCount * 2); + for (SizeType i = 0; i < memberCount; i++) + h ^= Hash(kv[i * 2], kv[i * 2 + 1]); // Use xor to achieve member order insensitive + *stack_.template Push() = h; + return true; + } + + bool StartArray() { return true; } + bool EndArray(SizeType elementCount) { + uint64_t h = Hash(0, kArrayType); + uint64_t* e = stack_.template Pop(elementCount); + for (SizeType i = 0; i < elementCount; i++) + h = Hash(h, e[i]); // Use hash to achieve element order sensitive + *stack_.template Push() = h; + return true; + } + + bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); } + + uint64_t GetHashCode() const { + RAPIDJSON_ASSERT(IsValid()); + return *stack_.template Top(); + } + +private: + static const size_t kDefaultSize = 256; + struct Number { + union U { + uint64_t u; + int64_t i; + }u; + double d; + }; + + bool WriteType(Type type) { return WriteBuffer(type, 0, 0); } + + bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); } + + bool WriteBuffer(Type type, const void* data, size_t len) { + // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/ + uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type); + const unsigned char* d = static_cast(data); + for (size_t i = 0; i < len; i++) + h = Hash(h, d[i]); + *stack_.template Push() = h; + return true; + } + + static uint64_t Hash(uint64_t h, uint64_t d) { + static const uint64_t kPrime = RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3); + h ^= d; + h *= kPrime; + return h; + } + + Stack stack_; +}; + +/////////////////////////////////////////////////////////////////////////////// +// SchemaValidationContext + +template +struct SchemaValidationContext { + typedef Schema SchemaType; + typedef ISchemaStateFactory SchemaValidatorFactoryType; + typedef typename SchemaType::ValueType ValueType; + typedef typename ValueType::Ch Ch; + + enum PatternValidatorType { + kPatternValidatorOnly, + kPatternValidatorWithProperty, + kPatternValidatorWithAdditionalProperty + }; + + SchemaValidationContext(SchemaValidatorFactoryType& f, const SchemaType* s) : + factory(f), + schema(s), + valueSchema(), + invalidKeyword(), + hasher(), + arrayElementHashCodes(), + validators(), + validatorCount(), + patternPropertiesValidators(), + patternPropertiesValidatorCount(), + patternPropertiesSchemas(), + patternPropertiesSchemaCount(), + valuePatternValidatorType(kPatternValidatorOnly), + propertyExist(), + inArray(false), + valueUniqueness(false), + arrayUniqueness(false) + { + } + + ~SchemaValidationContext() { + if (hasher) + factory.DestroryHasher(hasher); + if (validators) { + for (SizeType i = 0; i < validatorCount; i++) + factory.DestroySchemaValidator(validators[i]); + factory.FreeState(validators); + } + if (patternPropertiesValidators) { + for (SizeType i = 0; i < patternPropertiesValidatorCount; i++) + factory.DestroySchemaValidator(patternPropertiesValidators[i]); + factory.FreeState(patternPropertiesValidators); + } + if (patternPropertiesSchemas) + factory.FreeState(patternPropertiesSchemas); + if (propertyExist) + factory.FreeState(propertyExist); + } + + SchemaValidatorFactoryType& factory; + const SchemaType* schema; + const SchemaType* valueSchema; + const Ch* invalidKeyword; + void* hasher; // Only validator access + void* arrayElementHashCodes; // Only validator access this + ISchemaValidator** validators; + SizeType validatorCount; + ISchemaValidator** patternPropertiesValidators; + SizeType patternPropertiesValidatorCount; + const SchemaType** patternPropertiesSchemas; + SizeType patternPropertiesSchemaCount; + PatternValidatorType valuePatternValidatorType; + PatternValidatorType objectPatternValidatorType; + SizeType arrayElementIndex; + bool* propertyExist; + bool inArray; + bool valueUniqueness; + bool arrayUniqueness; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Schema + +template +class Schema { +public: + typedef typename SchemaDocumentType::ValueType ValueType; + typedef typename SchemaDocumentType::AllocatorType AllocatorType; + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + typedef SchemaValidationContext Context; + typedef Schema SchemaType; + typedef GenericValue SValue; + friend class GenericSchemaDocument; + + Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) : + allocator_(allocator), + enum_(), + enumCount_(), + not_(), + type_((1 << kTotalSchemaType) - 1), // typeless + validatorCount_(), + properties_(), + additionalPropertiesSchema_(), + patternProperties_(), + patternPropertyCount_(), + propertyCount_(), + minProperties_(), + maxProperties_(SizeType(~0)), + additionalProperties_(true), + hasDependencies_(), + hasRequired_(), + hasSchemaDependencies_(), + additionalItemsSchema_(), + itemsList_(), + itemsTuple_(), + itemsTupleCount_(), + minItems_(), + maxItems_(SizeType(~0)), + additionalItems_(true), + uniqueItems_(false), + pattern_(), + minLength_(0), + maxLength_(~SizeType(0)), + exclusiveMinimum_(false), + exclusiveMaximum_(false) + { + typedef typename SchemaDocumentType::ValueType ValueType; + typedef typename ValueType::ConstValueIterator ConstValueIterator; + typedef typename ValueType::ConstMemberIterator ConstMemberIterator; + + if (!value.IsObject()) + return; + + if (const ValueType* v = GetMember(value, GetTypeString())) { + type_ = 0; + if (v->IsString()) + AddType(*v); + else if (v->IsArray()) + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) + AddType(*itr); + } + + if (const ValueType* v = GetMember(value, GetEnumString())) + if (v->IsArray() && v->Size() > 0) { + enum_ = static_cast(allocator_->Malloc(sizeof(uint64_t) * v->Size())); + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) { + typedef Hasher > EnumHasherType; + char buffer[256 + 24]; + MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer)); + EnumHasherType h(&hasherAllocator, 256); + itr->Accept(h); + enum_[enumCount_++] = h.GetHashCode(); + } + } + + if (schemaDocument) { + AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document); + AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document); + AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document); + } + + if (const ValueType* v = GetMember(value, GetNotString())) { + schemaDocument->CreateSchema(¬_, p.Append(GetNotString(), allocator_), *v, document); + notValidatorIndex_ = validatorCount_; + validatorCount_++; + } + + // Object + + const ValueType* properties = GetMember(value, GetPropertiesString()); + const ValueType* required = GetMember(value, GetRequiredString()); + const ValueType* dependencies = GetMember(value, GetDependenciesString()); + { + // Gather properties from properties/required/dependencies + SValue allProperties(kArrayType); + + if (properties && properties->IsObject()) + for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) + AddUniqueElement(allProperties, itr->name); + + if (required && required->IsArray()) + for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) + if (itr->IsString()) + AddUniqueElement(allProperties, *itr); + + if (dependencies && dependencies->IsObject()) + for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { + AddUniqueElement(allProperties, itr->name); + if (itr->value.IsArray()) + for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i) + if (i->IsString()) + AddUniqueElement(allProperties, *i); + } + + if (allProperties.Size() > 0) { + propertyCount_ = allProperties.Size(); + properties_ = static_cast(allocator_->Malloc(sizeof(Property) * propertyCount_)); + for (SizeType i = 0; i < propertyCount_; i++) { + new (&properties_[i]) Property(); + properties_[i].name = allProperties[i]; + properties_[i].schema = GetTypeless(); + } + } + } + + if (properties && properties->IsObject()) { + PointerType q = p.Append(GetPropertiesString(), allocator_); + for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) { + SizeType index; + if (FindPropertyIndex(itr->name, &index)) + schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document); + } + } + + if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) { + PointerType q = p.Append(GetPatternPropertiesString(), allocator_); + patternProperties_ = static_cast(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount())); + patternPropertyCount_ = 0; + + for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) { + new (&patternProperties_[patternPropertyCount_]) PatternProperty(); + patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name); + schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name, allocator_), itr->value, document); + patternPropertyCount_++; + } + } + + if (required && required->IsArray()) + for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) + if (itr->IsString()) { + SizeType index; + if (FindPropertyIndex(*itr, &index)) { + properties_[index].required = true; + hasRequired_ = true; + } + } + + if (dependencies && dependencies->IsObject()) { + PointerType q = p.Append(GetDependenciesString(), allocator_); + hasDependencies_ = true; + for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { + SizeType sourceIndex; + if (FindPropertyIndex(itr->name, &sourceIndex)) { + if (itr->value.IsArray()) { + properties_[sourceIndex].dependencies = static_cast(allocator_->Malloc(sizeof(bool) * propertyCount_)); + std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_); + for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) { + SizeType targetIndex; + if (FindPropertyIndex(*targetItr, &targetIndex)) + properties_[sourceIndex].dependencies[targetIndex] = true; + } + } + else if (itr->value.IsObject()) { + hasSchemaDependencies_ = true; + schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document); + properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_; + validatorCount_++; + } + } + } + } + + if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) { + if (v->IsBool()) + additionalProperties_ = v->GetBool(); + else if (v->IsObject()) + schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document); + } + + AssignIfExist(minProperties_, value, GetMinPropertiesString()); + AssignIfExist(maxProperties_, value, GetMaxPropertiesString()); + + // Array + if (const ValueType* v = GetMember(value, GetItemsString())) { + PointerType q = p.Append(GetItemsString(), allocator_); + if (v->IsObject()) // List validation + schemaDocument->CreateSchema(&itemsList_, q, *v, document); + else if (v->IsArray()) { // Tuple validation + itemsTuple_ = static_cast(allocator_->Malloc(sizeof(const Schema*) * v->Size())); + SizeType index = 0; + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++) + schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document); + } + } + + AssignIfExist(minItems_, value, GetMinItemsString()); + AssignIfExist(maxItems_, value, GetMaxItemsString()); + + if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) { + if (v->IsBool()) + additionalItems_ = v->GetBool(); + else if (v->IsObject()) + schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document); + } + + AssignIfExist(uniqueItems_, value, GetUniqueItemsString()); + + // String + AssignIfExist(minLength_, value, GetMinLengthString()); + AssignIfExist(maxLength_, value, GetMaxLengthString()); + + if (const ValueType* v = GetMember(value, GetPatternString())) + pattern_ = CreatePattern(*v); + + // Number + if (const ValueType* v = GetMember(value, GetMinimumString())) + if (v->IsNumber()) + minimum_.CopyFrom(*v, *allocator_); + + if (const ValueType* v = GetMember(value, GetMaximumString())) + if (v->IsNumber()) + maximum_.CopyFrom(*v, *allocator_); + + AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString()); + AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString()); + + if (const ValueType* v = GetMember(value, GetMultipleOfString())) + if (v->IsNumber() && v->GetDouble() > 0.0) + multipleOf_.CopyFrom(*v, *allocator_); + } + + ~Schema() { + if (allocator_) { + allocator_->Free(enum_); + } + if (properties_) { + for (SizeType i = 0; i < propertyCount_; i++) + properties_[i].~Property(); + AllocatorType::Free(properties_); + } + if (patternProperties_) { + for (SizeType i = 0; i < patternPropertyCount_; i++) + patternProperties_[i].~PatternProperty(); + AllocatorType::Free(patternProperties_); + } + AllocatorType::Free(itemsTuple_); +#if RAPIDJSON_SCHEMA_HAS_REGEX + if (pattern_) { + pattern_->~RegexType(); + allocator_->Free(pattern_); + } +#endif + } + + bool BeginValue(Context& context) const { + if (context.inArray) { + if (uniqueItems_) + context.valueUniqueness = true; + + if (itemsList_) + context.valueSchema = itemsList_; + else if (itemsTuple_) { + if (context.arrayElementIndex < itemsTupleCount_) + context.valueSchema = itemsTuple_[context.arrayElementIndex]; + else if (additionalItemsSchema_) + context.valueSchema = additionalItemsSchema_; + else if (additionalItems_) + context.valueSchema = GetTypeless(); + else + RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString()); + } + else + context.valueSchema = GetTypeless(); + + context.arrayElementIndex++; + } + return true; + } + + RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const { + if (context.patternPropertiesValidatorCount > 0) { + bool otherValid = false; + SizeType count = context.patternPropertiesValidatorCount; + if (context.objectPatternValidatorType != Context::kPatternValidatorOnly) + otherValid = context.patternPropertiesValidators[--count]->IsValid(); + + bool patternValid = true; + for (SizeType i = 0; i < count; i++) + if (!context.patternPropertiesValidators[i]->IsValid()) { + patternValid = false; + break; + } + + if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) { + if (!patternValid) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); + } + else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) { + if (!patternValid || !otherValid) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); + } + else if (!patternValid && !otherValid) // kPatternValidatorWithAdditionalProperty) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); + } + + if (enum_) { + const uint64_t h = context.factory.GetHashCode(context.hasher); + for (SizeType i = 0; i < enumCount_; i++) + if (enum_[i] == h) + goto foundEnum; + RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString()); + foundEnum:; + } + + if (allOf_.schemas) + for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++) + if (!context.validators[i]->IsValid()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString()); + + if (anyOf_.schemas) { + for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++) + if (context.validators[i]->IsValid()) + goto foundAny; + RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString()); + foundAny:; + } + + if (oneOf_.schemas) { + bool oneValid = false; + for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++) + if (context.validators[i]->IsValid()) { + if (oneValid) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); + else + oneValid = true; + } + if (!oneValid) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); + } + + if (not_ && context.validators[notValidatorIndex_]->IsValid()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString()); + + return true; + } + + bool Null(Context& context) const { + if (!(type_ & (1 << kNullSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + return CreateParallelValidator(context); + } + + bool Bool(Context& context, bool) const { + if (!(type_ & (1 << kBooleanSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + return CreateParallelValidator(context); + } + + bool Int(Context& context, int i) const { + if (!CheckInt(context, i)) + return false; + return CreateParallelValidator(context); + } + + bool Uint(Context& context, unsigned u) const { + if (!CheckUint(context, u)) + return false; + return CreateParallelValidator(context); + } + + bool Int64(Context& context, int64_t i) const { + if (!CheckInt(context, i)) + return false; + return CreateParallelValidator(context); + } + + bool Uint64(Context& context, uint64_t u) const { + if (!CheckUint(context, u)) + return false; + return CreateParallelValidator(context); + } + + bool Double(Context& context, double d) const { + if (!(type_ & (1 << kNumberSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d)) + return false; + + if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d)) + return false; + + if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d)) + return false; + + return CreateParallelValidator(context); + } + + bool String(Context& context, const Ch* str, SizeType length, bool) const { + if (!(type_ & (1 << kStringSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (minLength_ != 0 || maxLength_ != SizeType(~0)) { + SizeType count; + if (internal::CountStringCodePoint(str, length, &count)) { + if (count < minLength_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString()); + if (count > maxLength_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString()); + } + } + + if (pattern_ && !IsPatternMatch(pattern_, str, length)) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString()); + + return CreateParallelValidator(context); + } + + bool StartObject(Context& context) const { + if (!(type_ & (1 << kObjectSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (hasDependencies_ || hasRequired_) { + context.propertyExist = static_cast(context.factory.MallocState(sizeof(bool) * propertyCount_)); + std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_); + } + + if (patternProperties_) { // pre-allocate schema array + SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType + context.patternPropertiesSchemas = static_cast(context.factory.MallocState(sizeof(const SchemaType*) * count)); + context.patternPropertiesSchemaCount = 0; + std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count); + } + + return CreateParallelValidator(context); + } + + bool Key(Context& context, const Ch* str, SizeType len, bool) const { + if (patternProperties_) { + context.patternPropertiesSchemaCount = 0; + for (SizeType i = 0; i < patternPropertyCount_; i++) + if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = patternProperties_[i].schema; + } + + SizeType index; + if (FindPropertyIndex(ValueType(str, len).Move(), &index)) { + if (context.patternPropertiesSchemaCount > 0) { + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema; + context.valueSchema = GetTypeless(); + context.valuePatternValidatorType = Context::kPatternValidatorWithProperty; + } + else + context.valueSchema = properties_[index].schema; + + if (context.propertyExist) + context.propertyExist[index] = true; + + return true; + } + + if (additionalPropertiesSchema_) { + if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) { + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_; + context.valueSchema = GetTypeless(); + context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty; + } + else + context.valueSchema = additionalPropertiesSchema_; + return true; + } + else if (additionalProperties_) { + context.valueSchema = GetTypeless(); + return true; + } + + if (context.patternPropertiesSchemaCount == 0) // patternProperties are not additional properties + RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString()); + + return true; + } + + bool EndObject(Context& context, SizeType memberCount) const { + if (hasRequired_) + for (SizeType index = 0; index < propertyCount_; index++) + if (properties_[index].required) + if (!context.propertyExist[index]) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString()); + + if (memberCount < minProperties_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString()); + + if (memberCount > maxProperties_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString()); + + if (hasDependencies_) { + for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) + if (context.propertyExist[sourceIndex]) { + if (properties_[sourceIndex].dependencies) { + for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++) + if (properties_[sourceIndex].dependencies[targetIndex] && !context.propertyExist[targetIndex]) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString()); + } + else if (properties_[sourceIndex].dependenciesSchema) + if (!context.validators[properties_[sourceIndex].dependenciesValidatorIndex]->IsValid()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString()); + } + } + + return true; + } + + bool StartArray(Context& context) const { + if (!(type_ & (1 << kArraySchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + context.arrayElementIndex = 0; + context.inArray = true; + + return CreateParallelValidator(context); + } + + bool EndArray(Context& context, SizeType elementCount) const { + context.inArray = false; + + if (elementCount < minItems_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString()); + + if (elementCount > maxItems_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString()); + + return true; + } + + // Generate functions for string literal according to Ch +#define RAPIDJSON_STRING_(name, ...) \ + static const ValueType& Get##name##String() {\ + static const Ch s[] = { __VA_ARGS__, '\0' };\ + static const ValueType v(s, sizeof(s) / sizeof(Ch) - 1);\ + return v;\ + } + + RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l') + RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n') + RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't') + RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y') + RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g') + RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r') + RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r') + RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e') + RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm') + RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f') + RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f') + RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f') + RAPIDJSON_STRING_(Not, 'n', 'o', 't') + RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd') + RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's') + RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h') + RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h') + RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n') + RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f') + +#undef RAPIDJSON_STRING_ + +private: + enum SchemaValueType { + kNullSchemaType, + kBooleanSchemaType, + kObjectSchemaType, + kArraySchemaType, + kStringSchemaType, + kNumberSchemaType, + kIntegerSchemaType, + kTotalSchemaType + }; + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX + typedef internal::GenericRegex RegexType; +#elif RAPIDJSON_SCHEMA_USE_STDREGEX + typedef std::basic_regex RegexType; +#else + typedef char RegexType; +#endif + + struct SchemaArray { + SchemaArray() : schemas(), count() {} + ~SchemaArray() { AllocatorType::Free(schemas); } + const SchemaType** schemas; + SizeType begin; // begin index of context.validators + SizeType count; + }; + + static const SchemaType* GetTypeless() { + static SchemaType typeless(0, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), 0); + return &typeless; + } + + template + void AddUniqueElement(V1& a, const V2& v) { + for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) + if (*itr == v) + return; + V1 c(v, *allocator_); + a.PushBack(c, *allocator_); + } + + static const ValueType* GetMember(const ValueType& value, const ValueType& name) { + typename ValueType::ConstMemberIterator itr = value.FindMember(name); + return itr != value.MemberEnd() ? &(itr->value) : 0; + } + + static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) { + if (const ValueType* v = GetMember(value, name)) + if (v->IsBool()) + out = v->GetBool(); + } + + static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) { + if (const ValueType* v = GetMember(value, name)) + if (v->IsUint64() && v->GetUint64() <= SizeType(~0)) + out = static_cast(v->GetUint64()); + } + + void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) { + if (const ValueType* v = GetMember(value, name)) { + if (v->IsArray() && v->Size() > 0) { + PointerType q = p.Append(name, allocator_); + out.count = v->Size(); + out.schemas = static_cast(allocator_->Malloc(out.count * sizeof(const Schema*))); + memset(out.schemas, 0, sizeof(Schema*)* out.count); + for (SizeType i = 0; i < out.count; i++) + schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document); + out.begin = validatorCount_; + validatorCount_ += out.count; + } + } + } + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX + template + RegexType* CreatePattern(const ValueType& value) { + if (value.IsString()) { + RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString()); + if (!r->IsValid()) { + r->~RegexType(); + AllocatorType::Free(r); + r = 0; + } + return r; + } + return 0; + } + + static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) { + return pattern->Search(str); + } +#elif RAPIDJSON_SCHEMA_USE_STDREGEX + template + RegexType* CreatePattern(const ValueType& value) { + if (value.IsString()) + try { + return new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript); + } + catch (const std::regex_error&) { + } + return 0; + } + + static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) { + std::match_results r; + return std::regex_search(str, str + length, r, *pattern); + } +#else + template + RegexType* CreatePattern(const ValueType&) { return 0; } + + static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; } +#endif // RAPIDJSON_SCHEMA_USE_STDREGEX + + void AddType(const ValueType& type) { + if (type == GetNullString() ) type_ |= 1 << kNullSchemaType; + else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType; + else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType; + else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType; + else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType; + else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType; + else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType); + } + + bool CreateParallelValidator(Context& context) const { + if (enum_ || context.arrayUniqueness) + context.hasher = context.factory.CreateHasher(); + + if (validatorCount_) { + RAPIDJSON_ASSERT(context.validators == 0); + context.validators = static_cast(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_)); + context.validatorCount = validatorCount_; + + if (allOf_.schemas) + CreateSchemaValidators(context, allOf_); + + if (anyOf_.schemas) + CreateSchemaValidators(context, anyOf_); + + if (oneOf_.schemas) + CreateSchemaValidators(context, oneOf_); + + if (not_) + context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_); + + if (hasSchemaDependencies_) { + for (SizeType i = 0; i < propertyCount_; i++) + if (properties_[i].dependenciesSchema) + context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema); + } + } + + return true; + } + + void CreateSchemaValidators(Context& context, const SchemaArray& schemas) const { + for (SizeType i = 0; i < schemas.count; i++) + context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i]); + } + + // O(n) + bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const { + SizeType len = name.GetStringLength(); + const Ch* str = name.GetString(); + for (SizeType index = 0; index < propertyCount_; index++) + if (properties_[index].name.GetStringLength() == len && + (std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0)) + { + *outIndex = index; + return true; + } + return false; + } + + bool CheckInt(Context& context, int64_t i) const { + if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (!minimum_.IsNull()) { + if (minimum_.IsInt64()) { + if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); + } + else if (minimum_.IsUint64()) { + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64() + } + else if (!CheckDoubleMinimum(context, static_cast(i))) + return false; + } + + if (!maximum_.IsNull()) { + if (maximum_.IsInt64()) { + if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); + } + else if (maximum_.IsUint64()) + /* do nothing */; // i <= max(int64_t) < maximum_.GetUint64() + else if (!CheckDoubleMaximum(context, static_cast(i))) + return false; + } + + if (!multipleOf_.IsNull()) { + if (multipleOf_.IsUint64()) { + if (static_cast(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); + } + else if (!CheckDoubleMultipleOf(context, static_cast(i))) + return false; + } + + return true; + } + + bool CheckUint(Context& context, uint64_t i) const { + if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (!minimum_.IsNull()) { + if (minimum_.IsUint64()) { + if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); + } + else if (minimum_.IsInt64()) + /* do nothing */; // i >= 0 > minimum.Getint64() + else if (!CheckDoubleMinimum(context, static_cast(i))) + return false; + } + + if (!maximum_.IsNull()) { + if (maximum_.IsUint64()) { + if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); + } + else if (maximum_.IsInt64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_ + else if (!CheckDoubleMaximum(context, static_cast(i))) + return false; + } + + if (!multipleOf_.IsNull()) { + if (multipleOf_.IsUint64()) { + if (i % multipleOf_.GetUint64() != 0) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); + } + else if (!CheckDoubleMultipleOf(context, static_cast(i))) + return false; + } + + return true; + } + + bool CheckDoubleMinimum(Context& context, double d) const { + if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); + return true; + } + + bool CheckDoubleMaximum(Context& context, double d) const { + if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); + return true; + } + + bool CheckDoubleMultipleOf(Context& context, double d) const { + double a = std::abs(d), b = std::abs(multipleOf_.GetDouble()); + double q = std::floor(a / b); + double r = a - q * b; + if (r > 0.0) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); + return true; + } + + struct Property { + Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {} + ~Property() { AllocatorType::Free(dependencies); } + SValue name; + const SchemaType* schema; + const SchemaType* dependenciesSchema; + SizeType dependenciesValidatorIndex; + bool* dependencies; + bool required; + }; + + struct PatternProperty { + PatternProperty() : schema(), pattern() {} + ~PatternProperty() { + if (pattern) { + pattern->~RegexType(); + AllocatorType::Free(pattern); + } + } + const SchemaType* schema; + RegexType* pattern; + }; + + AllocatorType* allocator_; + uint64_t* enum_; + SizeType enumCount_; + SchemaArray allOf_; + SchemaArray anyOf_; + SchemaArray oneOf_; + const SchemaType* not_; + unsigned type_; // bitmask of kSchemaType + SizeType validatorCount_; + SizeType notValidatorIndex_; + + Property* properties_; + const SchemaType* additionalPropertiesSchema_; + PatternProperty* patternProperties_; + SizeType patternPropertyCount_; + SizeType propertyCount_; + SizeType minProperties_; + SizeType maxProperties_; + bool additionalProperties_; + bool hasDependencies_; + bool hasRequired_; + bool hasSchemaDependencies_; + + const SchemaType* additionalItemsSchema_; + const SchemaType* itemsList_; + const SchemaType** itemsTuple_; + SizeType itemsTupleCount_; + SizeType minItems_; + SizeType maxItems_; + bool additionalItems_; + bool uniqueItems_; + + RegexType* pattern_; + SizeType minLength_; + SizeType maxLength_; + + SValue minimum_; + SValue maximum_; + SValue multipleOf_; + bool exclusiveMinimum_; + bool exclusiveMaximum_; +}; + +template +struct TokenHelper { + RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { + *documentStack.template Push() = '/'; + char buffer[21]; + size_t length = static_cast((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer); + for (size_t i = 0; i < length; i++) + *documentStack.template Push() = buffer[i]; + } +}; + +// Partial specialized version for char to prevent buffer copying. +template +struct TokenHelper { + RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { + if (sizeof(SizeType) == 4) { + char *buffer = documentStack.template Push(1 + 10); // '/' + uint + *buffer++ = '/'; + const char* end = internal::u32toa(index, buffer); + documentStack.template Pop(static_cast(10 - (end - buffer))); + } + else { + char *buffer = documentStack.template Push(1 + 20); // '/' + uint64 + *buffer++ = '/'; + const char* end = internal::u64toa(index, buffer); + documentStack.template Pop(static_cast(20 - (end - buffer))); + } + } +}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// IGenericRemoteSchemaDocumentProvider + +template +class IGenericRemoteSchemaDocumentProvider { +public: + typedef typename SchemaDocumentType::Ch Ch; + + virtual ~IGenericRemoteSchemaDocumentProvider() {} + virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericSchemaDocument + +//! JSON schema document. +/*! + A JSON schema document is a compiled version of a JSON schema. + It is basically a tree of internal::Schema. + + \note This is an immutable class (i.e. its instance cannot be modified after construction). + \tparam ValueT Type of JSON value (e.g. \c Value ), which also determine the encoding. + \tparam Allocator Allocator type for allocating memory of this document. +*/ +template +class GenericSchemaDocument { +public: + typedef ValueT ValueType; + typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProviderType; + typedef Allocator AllocatorType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + typedef internal::Schema SchemaType; + typedef GenericPointer PointerType; + friend class internal::Schema; + template + friend class GenericSchemaValidator; + + //! Constructor. + /*! + Compile a JSON document into schema document. + + \param document A JSON document as source. + \param remoteProvider An optional remote schema document provider for resolving remote reference. Can be null. + \param allocator An optional allocator instance for allocating memory. Can be null. + */ + explicit GenericSchemaDocument(const ValueType& document, IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) : + remoteProvider_(remoteProvider), + allocator_(allocator), + ownAllocator_(), + root_(), + schemaMap_(allocator, kInitialSchemaMapSize), + schemaRef_(allocator, kInitialSchemaRefSize) + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + + // Generate root schema, it will call CreateSchema() to create sub-schemas, + // And call AddRefSchema() if there are $ref. + CreateSchemaRecursive(&root_, PointerType(), document, document); + + // Resolve $ref + while (!schemaRef_.Empty()) { + SchemaRefEntry* refEntry = schemaRef_.template Pop(1); + if (const SchemaType* s = GetSchema(refEntry->target)) { + if (refEntry->schema) + *refEntry->schema = s; + + // Create entry in map if not exist + if (!GetSchema(refEntry->source)) { + new (schemaMap_.template Push()) SchemaEntry(refEntry->source, const_cast(s), false, allocator_); + } + } + refEntry->~SchemaRefEntry(); + } + + RAPIDJSON_ASSERT(root_ != 0); + + schemaRef_.ShrinkToFit(); // Deallocate all memory for ref + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT : + remoteProvider_(rhs.remoteProvider_), + allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + root_(rhs.root_), + schemaMap_(std::move(rhs.schemaMap_)), + schemaRef_(std::move(rhs.schemaRef_)) + { + rhs.remoteProvider_ = 0; + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + } +#endif + + //! Destructor + ~GenericSchemaDocument() { + while (!schemaMap_.Empty()) + schemaMap_.template Pop(1)->~SchemaEntry(); + + RAPIDJSON_DELETE(ownAllocator_); + } + + //! Get the root schema. + const SchemaType& GetRoot() const { return *root_; } + +private: + //! Prohibit copying + GenericSchemaDocument(const GenericSchemaDocument&); + //! Prohibit assignment + GenericSchemaDocument& operator=(const GenericSchemaDocument&); + + struct SchemaRefEntry { + SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema, Allocator *allocator) : source(s, allocator), target(t, allocator), schema(outSchema) {} + PointerType source; + PointerType target; + const SchemaType** schema; + }; + + struct SchemaEntry { + SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {} + ~SchemaEntry() { + if (owned) { + schema->~SchemaType(); + Allocator::Free(schema); + } + } + PointerType pointer; + SchemaType* schema; + bool owned; + }; + + void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) { + if (schema) + *schema = SchemaType::GetTypeless(); + + if (v.GetType() == kObjectType) { + const SchemaType* s = GetSchema(pointer); + if (!s) + CreateSchema(schema, pointer, v, document); + + for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) + CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document); + } + else if (v.GetType() == kArrayType) + for (SizeType i = 0; i < v.Size(); i++) + CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document); + } + + void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) { + RAPIDJSON_ASSERT(pointer.IsValid()); + if (v.IsObject()) { + if (!HandleRefSchema(pointer, schema, v, document)) { + SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_); + new (schemaMap_.template Push()) SchemaEntry(pointer, s, true, allocator_); + if (schema) + *schema = s; + } + } + } + + bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document) { + static const Ch kRefString[] = { '$', 'r', 'e', 'f', '\0' }; + static const ValueType kRefValue(kRefString, 4); + + typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue); + if (itr == v.MemberEnd()) + return false; + + if (itr->value.IsString()) { + SizeType len = itr->value.GetStringLength(); + if (len > 0) { + const Ch* s = itr->value.GetString(); + SizeType i = 0; + while (i < len && s[i] != '#') // Find the first # + i++; + + if (i > 0) { // Remote reference, resolve immediately + if (remoteProvider_) { + if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i - 1)) { + PointerType pointer(&s[i], len - i, allocator_); + if (pointer.IsValid()) { + if (const SchemaType* sc = remoteDocument->GetSchema(pointer)) { + if (schema) + *schema = sc; + return true; + } + } + } + } + } + else if (s[i] == '#') { // Local reference, defer resolution + PointerType pointer(&s[i], len - i, allocator_); + if (pointer.IsValid()) { + if (const ValueType* nv = pointer.Get(document)) + if (HandleRefSchema(source, schema, *nv, document)) + return true; + + new (schemaRef_.template Push()) SchemaRefEntry(source, pointer, schema, allocator_); + return true; + } + } + } + } + return false; + } + + const SchemaType* GetSchema(const PointerType& pointer) const { + for (const SchemaEntry* target = schemaMap_.template Bottom(); target != schemaMap_.template End(); ++target) + if (pointer == target->pointer) + return target->schema; + return 0; + } + + PointerType GetPointer(const SchemaType* schema) const { + for (const SchemaEntry* target = schemaMap_.template Bottom(); target != schemaMap_.template End(); ++target) + if (schema == target->schema) + return target->pointer; + return PointerType(); + } + + static const size_t kInitialSchemaMapSize = 64; + static const size_t kInitialSchemaRefSize = 64; + + IRemoteSchemaDocumentProviderType* remoteProvider_; + Allocator *allocator_; + Allocator *ownAllocator_; + const SchemaType* root_; //!< Root schema. + internal::Stack schemaMap_; // Stores created Pointer -> Schemas + internal::Stack schemaRef_; // Stores Pointer from $ref and schema which holds the $ref +}; + +//! GenericSchemaDocument using Value type. +typedef GenericSchemaDocument SchemaDocument; +//! IGenericRemoteSchemaDocumentProvider using SchemaDocument. +typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; + +/////////////////////////////////////////////////////////////////////////////// +// GenericSchemaValidator + +//! JSON Schema Validator. +/*! + A SAX style JSON schema validator. + It uses a \c GenericSchemaDocument to validate SAX events. + It delegates the incoming SAX events to an output handler. + The default output handler does nothing. + It can be reused multiple times by calling \c Reset(). + + \tparam SchemaDocumentType Type of schema document. + \tparam OutputHandler Type of output handler. Default handler does nothing. + \tparam StateAllocator Allocator for storing the internal validation states. +*/ +template < + typename SchemaDocumentType, + typename OutputHandler = BaseReaderHandler, + typename StateAllocator = CrtAllocator> +class GenericSchemaValidator : + public internal::ISchemaStateFactory, + public internal::ISchemaValidator +{ +public: + typedef typename SchemaDocumentType::SchemaType SchemaType; + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename SchemaType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + + //! Constructor without output handler. + /*! + \param schemaDocument The schema document to conform to. + \param allocator Optional allocator for storing internal validation states. + \param schemaStackCapacity Optional initial capacity of schema path stack. + \param documentStackCapacity Optional initial capacity of document path stack. + */ + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(schemaDocument.GetRoot()), + outputHandler_(GetNullHandler()), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + valid_(true) +#if RAPIDJSON_SCHEMA_VERBOSE + , depth_(0) +#endif + { + } + + //! Constructor with output handler. + /*! + \param schemaDocument The schema document to conform to. + \param allocator Optional allocator for storing internal validation states. + \param schemaStackCapacity Optional initial capacity of schema path stack. + \param documentStackCapacity Optional initial capacity of document path stack. + */ + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + OutputHandler& outputHandler, + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(schemaDocument.GetRoot()), + outputHandler_(outputHandler), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + valid_(true) +#if RAPIDJSON_SCHEMA_VERBOSE + , depth_(0) +#endif + { + } + + //! Destructor. + ~GenericSchemaValidator() { + Reset(); + RAPIDJSON_DELETE(ownStateAllocator_); + } + + //! Reset the internal states. + void Reset() { + while (!schemaStack_.Empty()) + PopSchema(); + documentStack_.Clear(); + valid_ = true; + } + + //! Checks whether the current state is valid. + // Implementation of ISchemaValidator + virtual bool IsValid() const { return valid_; } + + //! Gets the JSON pointer pointed to the invalid schema. + PointerType GetInvalidSchemaPointer() const { + return schemaStack_.Empty() ? PointerType() : schemaDocument_->GetPointer(&CurrentSchema()); + } + + //! Gets the keyword of invalid schema. + const Ch* GetInvalidSchemaKeyword() const { + return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword; + } + + //! Gets the JSON pointer pointed to the invalid value. + PointerType GetInvalidDocumentPointer() const { + return documentStack_.Empty() ? PointerType() : PointerType(documentStack_.template Bottom(), documentStack_.GetSize() / sizeof(Ch)); + } + +#if RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \ +RAPIDJSON_MULTILINEMACRO_BEGIN\ + *documentStack_.template Push() = '\0';\ + documentStack_.template Pop(1);\ + internal::PrintInvalidDocument(documentStack_.template Bottom());\ +RAPIDJSON_MULTILINEMACRO_END +#else +#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() +#endif + +#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\ + if (!valid_) return false; \ + if (!BeginValue() || !CurrentSchema().method arg1) {\ + RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\ + return valid_ = false;\ + } + +#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\ + for (Context* context = schemaStack_.template Bottom(); context != schemaStack_.template End(); context++) {\ + if (context->hasher)\ + static_cast(context->hasher)->method arg2;\ + if (context->validators)\ + for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\ + static_cast(context->validators[i_])->method arg2;\ + if (context->patternPropertiesValidators)\ + for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\ + static_cast(context->patternPropertiesValidators[i_])->method arg2;\ + } + +#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\ + return valid_ = EndValue() && outputHandler_.method arg2 + +#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ + RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\ + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\ + RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2) + + bool Null() { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null, (CurrentContext() ), ( )); } + bool Bool(bool b) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool, (CurrentContext(), b), (b)); } + bool Int(int i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int, (CurrentContext(), i), (i)); } + bool Uint(unsigned u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), u), (u)); } + bool Int64(int64_t i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), i), (i)); } + bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); } + bool Double(double d) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); } + bool RawNumber(const Ch* str, SizeType length, bool copy) + { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } + bool String(const Ch* str, SizeType length, bool copy) + { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } + + bool StartObject() { + RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext())); + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ()); + return valid_ = outputHandler_.StartObject(); + } + + bool Key(const Ch* str, SizeType len, bool copy) { + if (!valid_) return false; + AppendToken(str, len); + if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy)); + return valid_ = outputHandler_.Key(str, len, copy); + } + + bool EndObject(SizeType memberCount) { + if (!valid_) return false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount)); + if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false; + RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount)); + } + + bool StartArray() { + RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext())); + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ()); + return valid_ = outputHandler_.StartArray(); + } + + bool EndArray(SizeType elementCount) { + if (!valid_) return false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount)); + if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false; + RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount)); + } + +#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_ +#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_ +#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_ +#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_ + + // Implementation of ISchemaStateFactory + virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) { + return new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root, +#if RAPIDJSON_SCHEMA_VERBOSE + depth_ + 1, +#endif + &GetStateAllocator()); + } + + virtual void DestroySchemaValidator(ISchemaValidator* validator) { + GenericSchemaValidator* v = static_cast(validator); + v->~GenericSchemaValidator(); + StateAllocator::Free(v); + } + + virtual void* CreateHasher() { + return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator()); + } + + virtual uint64_t GetHashCode(void* hasher) { + return static_cast(hasher)->GetHashCode(); + } + + virtual void DestroryHasher(void* hasher) { + HasherType* h = static_cast(hasher); + h->~HasherType(); + StateAllocator::Free(h); + } + + virtual void* MallocState(size_t size) { + return GetStateAllocator().Malloc(size); + } + + virtual void FreeState(void* p) { + return StateAllocator::Free(p); + } + +private: + typedef typename SchemaType::Context Context; + typedef GenericValue, StateAllocator> HashCodeArray; + typedef internal::Hasher HasherType; + + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + const SchemaType& root, +#if RAPIDJSON_SCHEMA_VERBOSE + unsigned depth, +#endif + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(root), + outputHandler_(GetNullHandler()), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + valid_(true) +#if RAPIDJSON_SCHEMA_VERBOSE + , depth_(depth) +#endif + { + } + + StateAllocator& GetStateAllocator() { + if (!stateAllocator_) + stateAllocator_ = ownStateAllocator_ = RAPIDJSON_NEW(StateAllocator()); + return *stateAllocator_; + } + + bool BeginValue() { + if (schemaStack_.Empty()) + PushSchema(root_); + else { + if (CurrentContext().inArray) + internal::TokenHelper, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex); + + if (!CurrentSchema().BeginValue(CurrentContext())) + return false; + + SizeType count = CurrentContext().patternPropertiesSchemaCount; + const SchemaType** sa = CurrentContext().patternPropertiesSchemas; + typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType; + bool valueUniqueness = CurrentContext().valueUniqueness; + if (CurrentContext().valueSchema) + PushSchema(*CurrentContext().valueSchema); + + if (count > 0) { + CurrentContext().objectPatternValidatorType = patternValidatorType; + ISchemaValidator**& va = CurrentContext().patternPropertiesValidators; + SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount; + va = static_cast(MallocState(sizeof(ISchemaValidator*) * count)); + for (SizeType i = 0; i < count; i++) + va[validatorCount++] = CreateSchemaValidator(*sa[i]); + } + + CurrentContext().arrayUniqueness = valueUniqueness; + } + return true; + } + + bool EndValue() { + if (!CurrentSchema().EndValue(CurrentContext())) + return false; + +#if RAPIDJSON_SCHEMA_VERBOSE + GenericStringBuffer sb; + schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb); + + *documentStack_.template Push() = '\0'; + documentStack_.template Pop(1); + internal::PrintValidatorPointers(depth_, sb.GetString(), documentStack_.template Bottom()); +#endif + + uint64_t h = CurrentContext().arrayUniqueness ? static_cast(CurrentContext().hasher)->GetHashCode() : 0; + + PopSchema(); + + if (!schemaStack_.Empty()) { + Context& context = CurrentContext(); + if (context.valueUniqueness) { + HashCodeArray* a = static_cast(context.arrayElementHashCodes); + if (!a) + CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType); + for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr) + if (itr->GetUint64() == h) + RAPIDJSON_INVALID_KEYWORD_RETURN(SchemaType::GetUniqueItemsString()); + a->PushBack(h, GetStateAllocator()); + } + } + + // Remove the last token of document pointer + while (!documentStack_.Empty() && *documentStack_.template Pop(1) != '/') + ; + + return true; + } + + void AppendToken(const Ch* str, SizeType len) { + documentStack_.template Reserve(1 + len * 2); // worst case all characters are escaped as two characters + *documentStack_.template PushUnsafe() = '/'; + for (SizeType i = 0; i < len; i++) { + if (str[i] == '~') { + *documentStack_.template PushUnsafe() = '~'; + *documentStack_.template PushUnsafe() = '0'; + } + else if (str[i] == '/') { + *documentStack_.template PushUnsafe() = '~'; + *documentStack_.template PushUnsafe() = '1'; + } + else + *documentStack_.template PushUnsafe() = str[i]; + } + } + + RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push()) Context(*this, &schema); } + + RAPIDJSON_FORCEINLINE void PopSchema() { + Context* c = schemaStack_.template Pop(1); + if (HashCodeArray* a = static_cast(c->arrayElementHashCodes)) { + a->~HashCodeArray(); + StateAllocator::Free(a); + } + c->~Context(); + } + + const SchemaType& CurrentSchema() const { return *schemaStack_.template Top()->schema; } + Context& CurrentContext() { return *schemaStack_.template Top(); } + const Context& CurrentContext() const { return *schemaStack_.template Top(); } + + static OutputHandler& GetNullHandler() { + static OutputHandler nullHandler; + return nullHandler; + } + + static const size_t kDefaultSchemaStackCapacity = 1024; + static const size_t kDefaultDocumentStackCapacity = 256; + const SchemaDocumentType* schemaDocument_; + const SchemaType& root_; + OutputHandler& outputHandler_; + StateAllocator* stateAllocator_; + StateAllocator* ownStateAllocator_; + internal::Stack schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *) + internal::Stack documentStack_; //!< stack to store the current path of validating document (Ch) + bool valid_; +#if RAPIDJSON_SCHEMA_VERBOSE + unsigned depth_; +#endif +}; + +typedef GenericSchemaValidator SchemaValidator; + +/////////////////////////////////////////////////////////////////////////////// +// SchemaValidatingReader + +//! A helper class for parsing with validation. +/*! + This helper class is a functor, designed as a parameter of \ref GenericDocument::Populate(). + + \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept. + \tparam SourceEncoding Encoding of the input stream. + \tparam SchemaDocumentType Type of schema document. + \tparam StackAllocator Allocator type for stack. +*/ +template < + unsigned parseFlags, + typename InputStream, + typename SourceEncoding, + typename SchemaDocumentType = SchemaDocument, + typename StackAllocator = CrtAllocator> +class SchemaValidatingReader { +public: + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename InputStream::Ch Ch; + + //! Constructor + /*! + \param is Input stream. + \param sd Schema document. + */ + SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), isValid_(true) {} + + template + bool operator()(Handler& handler) { + GenericReader reader; + GenericSchemaValidator validator(sd_, handler); + parseResult_ = reader.template Parse(is_, validator); + + isValid_ = validator.IsValid(); + if (isValid_) { + invalidSchemaPointer_ = PointerType(); + invalidSchemaKeyword_ = 0; + invalidDocumentPointer_ = PointerType(); + } + else { + invalidSchemaPointer_ = validator.GetInvalidSchemaPointer(); + invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword(); + invalidDocumentPointer_ = validator.GetInvalidDocumentPointer(); + } + + return parseResult_; + } + + const ParseResult& GetParseResult() const { return parseResult_; } + bool IsValid() const { return isValid_; } + const PointerType& GetInvalidSchemaPointer() const { return invalidSchemaPointer_; } + const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; } + const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; } + +private: + InputStream& is_; + const SchemaDocumentType& sd_; + + ParseResult parseResult_; + PointerType invalidSchemaPointer_; + const Ch* invalidSchemaKeyword_; + PointerType invalidDocumentPointer_; + bool isValid_; +}; + +RAPIDJSON_NAMESPACE_END +RAPIDJSON_DIAG_POP + +#endif // RAPIDJSON_SCHEMA_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/stream.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/stream.h new file mode 100644 index 0000000000..fef82c252f --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/stream.h @@ -0,0 +1,179 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include "rapidjson.h" + +#ifndef RAPIDJSON_STREAM_H_ +#define RAPIDJSON_STREAM_H_ + +#include "encodings.h" + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Stream + +/*! \class rapidjson::Stream + \brief Concept for reading and writing characters. + + For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). + + For write-only stream, only need to implement Put() and Flush(). + +\code +concept Stream { + typename Ch; //!< Character type of the stream. + + //! Read the current character from stream without moving the read cursor. + Ch Peek() const; + + //! Read the current character from stream and moving the read cursor to next character. + Ch Take(); + + //! Get the current read cursor. + //! \return Number of characters read from start. + size_t Tell(); + + //! Begin writing operation at the current read pointer. + //! \return The begin writer pointer. + Ch* PutBegin(); + + //! Write a character. + void Put(Ch c); + + //! Flush the buffer. + void Flush(); + + //! End the writing operation. + //! \param begin The begin write pointer returned by PutBegin(). + //! \return Number of characters written. + size_t PutEnd(Ch* begin); +} +\endcode +*/ + +//! Provides additional information for stream. +/*! + By using traits pattern, this type provides a default configuration for stream. + For custom stream, this type can be specialized for other configuration. + See TEST(Reader, CustomStringStream) in readertest.cpp for example. +*/ +template +struct StreamTraits { + //! Whether to make local copy of stream for optimization during parsing. + /*! + By default, for safety, streams do not use local copy optimization. + Stream that can be copied fast should specialize this, like StreamTraits. + */ + enum { copyOptimization = 0 }; +}; + +//! Reserve n characters for writing to a stream. +template +inline void PutReserve(Stream& stream, size_t count) { + (void)stream; + (void)count; +} + +//! Write character to a stream, presuming buffer is reserved. +template +inline void PutUnsafe(Stream& stream, typename Stream::Ch c) { + stream.Put(c); +} + +//! Put N copies of a character to a stream. +template +inline void PutN(Stream& stream, Ch c, size_t n) { + PutReserve(stream, n); + for (size_t i = 0; i < n; i++) + PutUnsafe(stream, c); +} + +/////////////////////////////////////////////////////////////////////////////// +// StringStream + +//! Read-only string stream. +/*! \note implements Stream concept +*/ +template +struct GenericStringStream { + typedef typename Encoding::Ch Ch; + + GenericStringStream(const Ch *src) : src_(src), head_(src) {} + + Ch Peek() const { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() const { return static_cast(src_ - head_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. +}; + +template +struct StreamTraits > { + enum { copyOptimization = 1 }; +}; + +//! String stream with UTF8 encoding. +typedef GenericStringStream > StringStream; + +/////////////////////////////////////////////////////////////////////////////// +// InsituStringStream + +//! A read-write string stream. +/*! This string stream is particularly designed for in-situ parsing. + \note implements Stream concept +*/ +template +struct GenericInsituStringStream { + typedef typename Encoding::Ch Ch; + + GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} + + // Read + Ch Peek() { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() { return static_cast(src_ - head_); } + + // Write + void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } + + Ch* PutBegin() { return dst_ = src_; } + size_t PutEnd(Ch* begin) { return static_cast(dst_ - begin); } + void Flush() {} + + Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } + void Pop(size_t count) { dst_ -= count; } + + Ch* src_; + Ch* dst_; + Ch* head_; +}; + +template +struct StreamTraits > { + enum { copyOptimization = 1 }; +}; + +//! Insitu string stream with UTF8 encoding. +typedef GenericInsituStringStream > InsituStringStream; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STREAM_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/stringbuffer.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/stringbuffer.h new file mode 100644 index 0000000000..78f34d2098 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/stringbuffer.h @@ -0,0 +1,117 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_STRINGBUFFER_H_ +#define RAPIDJSON_STRINGBUFFER_H_ + +#include "stream.h" +#include "internal/stack.h" + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#include // std::move +#endif + +#include "internal/stack.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory output stream. +/*! + \tparam Encoding Encoding of the stream. + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template +class GenericStringBuffer { +public: + typedef typename Encoding::Ch Ch; + + GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} + GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { + if (&rhs != this) + stack_ = std::move(rhs.stack_); + return *this; + } +#endif + + void Put(Ch c) { *stack_.template Push() = c; } + void PutUnsafe(Ch c) { *stack_.template PushUnsafe() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.ShrinkToFit(); + stack_.template Pop(1); + } + + void Reserve(size_t count) { stack_.template Reserve(count); } + Ch* Push(size_t count) { return stack_.template Push(count); } + Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe(count); } + void Pop(size_t count) { stack_.template Pop(count); } + + const Ch* GetString() const { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.template Pop(1); + + return stack_.template Bottom(); + } + + size_t GetSize() const { return stack_.GetSize(); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; + +private: + // Prohibit copy constructor & assignment operator. + GenericStringBuffer(const GenericStringBuffer&); + GenericStringBuffer& operator=(const GenericStringBuffer&); +}; + +//! String buffer with UTF8 encoding +typedef GenericStringBuffer > StringBuffer; + +template +inline void PutReserve(GenericStringBuffer& stream, size_t count) { + stream.Reserve(count); +} + +template +inline void PutUnsafe(GenericStringBuffer& stream, typename Encoding::Ch c) { + stream.PutUnsafe(c); +} + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { + std::memset(stream.stack_.Push(n), c, n * sizeof(c)); +} + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_STRINGBUFFER_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/writer.h b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/writer.h new file mode 100644 index 0000000000..94f22dd5fc --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/include/rapidjson/writer.h @@ -0,0 +1,610 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_WRITER_H_ +#define RAPIDJSON_WRITER_H_ + +#include "stream.h" +#include "internal/stack.h" +#include "internal/strfunc.h" +#include "internal/dtoa.h" +#include "internal/itoa.h" +#include "stringbuffer.h" +#include // placement new + +#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) +#include +#pragma intrinsic(_BitScanForward) +#endif +#ifdef RAPIDJSON_SSE42 +#include +#elif defined(RAPIDJSON_SSE2) +#include +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(unreachable-code) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// WriteFlag + +/*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kWriteDefaultFlags definition. + + User can define this as any \c WriteFlag combinations. +*/ +#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS +#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags +#endif + +//! Combination of writeFlags +enum WriteFlag { + kWriteNoFlags = 0, //!< No flags are set. + kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings. + kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN. + kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS +}; + +//! JSON writer +/*! Writer implements the concept Handler. + It generates JSON text by events to an output os. + + User may programmatically calls the functions of a writer to generate JSON text. + + On the other side, a writer can also be passed to objects that generates events, + + for example Reader::Parse() and Document::Accept(). + + \tparam OutputStream Type of output stream. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. + \note implements Handler concept +*/ +template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> +class Writer { +public: + typedef typename SourceEncoding::Ch Ch; + + static const int kDefaultMaxDecimalPlaces = 324; + + //! Constructor + /*! \param os Output stream. + \param stackAllocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + explicit + Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} + + explicit + Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} + + //! Reset the writer with a new stream. + /*! + This function reset the writer with a new stream and default settings, + in order to make a Writer object reusable for output multiple JSONs. + + \param os New output stream. + \code + Writer writer(os1); + writer.StartObject(); + // ... + writer.EndObject(); + + writer.Reset(os2); + writer.StartObject(); + // ... + writer.EndObject(); + \endcode + */ + void Reset(OutputStream& os) { + os_ = &os; + hasRoot_ = false; + level_stack_.Clear(); + } + + //! Checks whether the output is a complete JSON. + /*! + A complete JSON has a complete root object or array. + */ + bool IsComplete() const { + return hasRoot_ && level_stack_.Empty(); + } + + int GetMaxDecimalPlaces() const { + return maxDecimalPlaces_; + } + + //! Sets the maximum number of decimal places for double output. + /*! + This setting truncates the output with specified number of decimal places. + + For example, + + \code + writer.SetMaxDecimalPlaces(3); + writer.StartArray(); + writer.Double(0.12345); // "0.123" + writer.Double(0.0001); // "0.0" + writer.Double(1.234567890123456e30); // "1.234567890123456e30" (do not truncate significand for positive exponent) + writer.Double(1.23e-4); // "0.0" (do truncate significand for negative exponent) + writer.EndArray(); + \endcode + + The default setting does not truncate any decimal places. You can restore to this setting by calling + \code + writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces); + \endcode + */ + void SetMaxDecimalPlaces(int maxDecimalPlaces) { + maxDecimalPlaces_ = maxDecimalPlaces; + } + + /*!@name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { Prefix(kNullType); return EndValue(WriteNull()); } + bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); } + bool Int(int i) { Prefix(kNumberType); return EndValue(WriteInt(i)); } + bool Uint(unsigned u) { Prefix(kNumberType); return EndValue(WriteUint(u)); } + bool Int64(int64_t i64) { Prefix(kNumberType); return EndValue(WriteInt64(i64)); } + bool Uint64(uint64_t u64) { Prefix(kNumberType); return EndValue(WriteUint64(u64)); } + + //! Writes the given \c double value to the stream + /*! + \param d The value to be written. + \return Whether it is succeed. + */ + bool Double(double d) { Prefix(kNumberType); return EndValue(WriteDouble(d)); } + + bool RawNumber(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + Prefix(kNumberType); + return EndValue(WriteString(str, length)); + } + + bool String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + Prefix(kStringType); + return EndValue(WriteString(str, length)); + } + +#if RAPIDJSON_HAS_STDSTRING + bool String(const std::basic_string& str) { + return String(str.data(), SizeType(str.size())); + } +#endif + + bool StartObject() { + Prefix(kObjectType); + new (level_stack_.template Push()) Level(false); + return WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + return EndValue(WriteEndObject()); + } + + bool StartArray() { + Prefix(kArrayType); + new (level_stack_.template Push()) Level(true); + return WriteStartArray(); + } + + bool EndArray(SizeType elementCount = 0) { + (void)elementCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + return EndValue(WriteEndArray()); + } + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } + + //@} + + //! Write a raw JSON value. + /*! + For user to write a stringified JSON as a value. + + \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. + \param length Length of the json. + \param type Type of the root of json. + */ + bool RawValue(const Ch* json, size_t length, Type type) { Prefix(type); return EndValue(WriteRawValue(json, length)); } + +protected: + //! Information for each nested level + struct Level { + Level(bool inArray_) : valueCount(0), inArray(inArray_) {} + size_t valueCount; //!< number of values in this level + bool inArray; //!< true if in array, otherwise in object + }; + + static const size_t kDefaultLevelDepth = 32; + + bool WriteNull() { + PutReserve(*os_, 4); + PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true; + } + + bool WriteBool(bool b) { + if (b) { + PutReserve(*os_, 4); + PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e'); + } + else { + PutReserve(*os_, 5); + PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e'); + } + return true; + } + + bool WriteInt(int i) { + char buffer[11]; + const char* end = internal::i32toa(i, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteUint(unsigned u) { + char buffer[10]; + const char* end = internal::u32toa(u, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteInt64(int64_t i64) { + char buffer[21]; + const char* end = internal::i64toa(i64, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteUint64(uint64_t u64) { + char buffer[20]; + char* end = internal::u64toa(u64, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteDouble(double d) { + if (internal::Double(d).IsNanOrInf()) { + if (!(writeFlags & kWriteNanAndInfFlag)) + return false; + if (internal::Double(d).IsNan()) { + PutReserve(*os_, 3); + PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); + return true; + } + if (internal::Double(d).Sign()) { + PutReserve(*os_, 9); + PutUnsafe(*os_, '-'); + } + else + PutReserve(*os_, 8); + PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); + PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); + return true; + } + + char buffer[25]; + char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); + PutReserve(*os_, static_cast(end - buffer)); + for (char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteString(const Ch* str, SizeType length) { + static const typename TargetEncoding::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + static const char escape[256] = { +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 + 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 + Z16, Z16, // 30~4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF +#undef Z16 + }; + + if (TargetEncoding::supportUnicode) + PutReserve(*os_, 2 + length * 6); // "\uxxxx..." + else + PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..." + + PutUnsafe(*os_, '\"'); + GenericStringStream is(str); + while (ScanWriteUnescapedString(is, length)) { + const Ch c = is.Peek(); + if (!TargetEncoding::supportUnicode && static_cast(c) >= 0x80) { + // Unicode escaping + unsigned codepoint; + if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint))) + return false; + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, 'u'); + if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) { + PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint ) & 15]); + } + else { + RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF); + // Surrogate pair + unsigned s = codepoint - 0x010000; + unsigned lead = (s >> 10) + 0xD800; + unsigned trail = (s & 0x3FF) + 0xDC00; + PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(lead ) & 15]); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, 'u'); + PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(trail ) & 15]); + } + } + else if ((sizeof(Ch) == 1 || static_cast(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast(c)])) { + is.Take(); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, static_cast(escape[static_cast(c)])); + if (escape[static_cast(c)] == 'u') { + PutUnsafe(*os_, '0'); + PutUnsafe(*os_, '0'); + PutUnsafe(*os_, hexDigits[static_cast(c) >> 4]); + PutUnsafe(*os_, hexDigits[static_cast(c) & 0xF]); + } + } + else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? + Transcoder::Validate(is, *os_) : + Transcoder::TranscodeUnsafe(is, *os_)))) + return false; + } + PutUnsafe(*os_, '\"'); + return true; + } + + bool ScanWriteUnescapedString(GenericStringStream& is, size_t length) { + return RAPIDJSON_LIKELY(is.Tell() < length); + } + + bool WriteStartObject() { os_->Put('{'); return true; } + bool WriteEndObject() { os_->Put('}'); return true; } + bool WriteStartArray() { os_->Put('['); return true; } + bool WriteEndArray() { os_->Put(']'); return true; } + + bool WriteRawValue(const Ch* json, size_t length) { + PutReserve(*os_, length); + for (size_t i = 0; i < length; i++) { + RAPIDJSON_ASSERT(json[i] != '\0'); + PutUnsafe(*os_, json[i]); + } + return true; + } + + void Prefix(Type type) { + (void)type; + if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root + Level* level = level_stack_.template Top(); + if (level->valueCount > 0) { + if (level->inArray) + os_->Put(','); // add comma if it is not the first element in array + else // in object + os_->Put((level->valueCount % 2 == 0) ? ',' : ':'); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root. + hasRoot_ = true; + } + } + + // Flush the value if it is the top level one. + bool EndValue(bool ret) { + if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text + os_->Flush(); + return ret; + } + + OutputStream* os_; + internal::Stack level_stack_; + int maxDecimalPlaces_; + bool hasRoot_; + +private: + // Prohibit copy constructor & assignment operator. + Writer(const Writer&); + Writer& operator=(const Writer&); +}; + +// Full specialization for StringStream to prevent memory copying + +template<> +inline bool Writer::WriteInt(int i) { + char *buffer = os_->Push(11); + const char* end = internal::i32toa(i, buffer); + os_->Pop(static_cast(11 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteUint(unsigned u) { + char *buffer = os_->Push(10); + const char* end = internal::u32toa(u, buffer); + os_->Pop(static_cast(10 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteInt64(int64_t i64) { + char *buffer = os_->Push(21); + const char* end = internal::i64toa(i64, buffer); + os_->Pop(static_cast(21 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteUint64(uint64_t u) { + char *buffer = os_->Push(20); + const char* end = internal::u64toa(u, buffer); + os_->Pop(static_cast(20 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteDouble(double d) { + if (internal::Double(d).IsNanOrInf()) { + // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag). + if (!(kWriteDefaultFlags & kWriteNanAndInfFlag)) + return false; + if (internal::Double(d).IsNan()) { + PutReserve(*os_, 3); + PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); + return true; + } + if (internal::Double(d).Sign()) { + PutReserve(*os_, 9); + PutUnsafe(*os_, '-'); + } + else + PutReserve(*os_, 8); + PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); + PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); + return true; + } + + char *buffer = os_->Push(25); + char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); + os_->Pop(static_cast(25 - (end - buffer))); + return true; +} + +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) +template<> +inline bool Writer::ScanWriteUnescapedString(StringStream& is, size_t length) { + if (length < 16) + return RAPIDJSON_LIKELY(is.Tell() < length); + + if (!RAPIDJSON_LIKELY(is.Tell() < length)) + return false; + + const char* p = is.src_; + const char* end = is.head_ + length; + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + const char* endAligned = reinterpret_cast(reinterpret_cast(end) & static_cast(~15)); + if (nextAligned > end) + return true; + + while (p != nextAligned) + if (*p < 0x20 || *p == '\"' || *p == '\\') { + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); + } + else + os_->PutUnsafe(*p++); + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (; p != endAligned; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + SizeType len; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + len = offset; +#else + len = static_cast(__builtin_ffs(r) - 1); +#endif + char* q = reinterpret_cast(os_->PushUnsafe(len)); + for (size_t i = 0; i < len; i++) + q[i] = p[i]; + + p += len; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s); + } + + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); +} +#endif // defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) + +RAPIDJSON_NAMESPACE_END + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/license.txt b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/license.txt new file mode 100644 index 0000000000..7ccc161c84 --- /dev/null +++ b/third-party/discord-rpc/thirdparty/rapidjson-1.1.0/license.txt @@ -0,0 +1,57 @@ +Tencent is pleased to support the open source community by making RapidJSON available. + +Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. + +If you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License. +If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON. To avoid the problematic JSON license in your own projects, it's sufficient to exclude the bin/jsonchecker/ directory, as it's the only code under the JSON license. +A copy of the MIT License is included in this file. + +Other dependencies and licenses: + +Open Source Software Licensed Under the BSD License: +-------------------------------------------------------------------- + +The msinttypes r29 +Copyright (c) 2006-2013 Alexander Chemeris +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* Neither the name of copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Open Source Software Licensed Under the JSON License: +-------------------------------------------------------------------- + +json.org +Copyright (c) 2002 JSON.org +All Rights Reserved. + +JSON_checker +Copyright (c) 2002 JSON.org +All Rights Reserved. + + +Terms of the JSON License: +--------------------------------------------------- + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Terms of the MIT License: +-------------------------------------------------------------------- + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/third-party/draco/.clang-format b/third-party/draco/.clang-format new file mode 100644 index 0000000000..533d35e6d8 --- /dev/null +++ b/third-party/draco/.clang-format @@ -0,0 +1,5 @@ +--- +Language: Cpp +BasedOnStyle: Google +PointerAlignment: Right +... diff --git a/third-party/draco/.cmake-format.py b/third-party/draco/.cmake-format.py new file mode 100644 index 0000000000..5b36f67aa0 --- /dev/null +++ b/third-party/draco/.cmake-format.py @@ -0,0 +1,137 @@ +with section('parse'): + # Specify structure for custom cmake functions + additional_commands = { + 'draco_add_emscripten_executable': { + 'kwargs': { + 'NAME': '*', + 'SOURCES': '*', + 'OUTPUT_NAME': '*', + 'DEFINES': '*', + 'INCLUDES': '*', + 'COMPILE_FLAGS': '*', + 'LINK_FLAGS': '*', + 'OBJLIB_DEPS': '*', + 'LIB_DEPS': '*', + 'GLUE_PATH': '*', + 'PRE_LINK_JS_SOURCES': '*', + 'POST_LINK_JS_SOURCES': '*', + 'FEATURES': '*', + }, + 'pargs': 0, + }, + 'draco_add_executable': { + 'kwargs': { + 'NAME': '*', + 'SOURCES': '*', + 'OUTPUT_NAME': '*', + 'TEST': 0, + 'DEFINES': '*', + 'INCLUDES': '*', + 'COMPILE_FLAGS': '*', + 'LINK_FLAGS': '*', + 'OBJLIB_DEPS': '*', + 'LIB_DEPS': '*', + }, + 'pargs': 0, + }, + 'draco_add_library': { + 'kwargs': { + 'NAME': '*', + 'TYPE': '*', + 'SOURCES': '*', + 'TEST': 0, + 'OUTPUT_NAME': '*', + 'DEFINES': '*', + 'INCLUDES': '*', + 'COMPILE_FLAGS': '*', + 'LINK_FLAGS': '*', + 'OBJLIB_DEPS': '*', + 'LIB_DEPS': '*', + 'PUBLIC_INCLUDES': '*', + }, + 'pargs': 0, + }, + 'draco_generate_emscripten_glue': { + 'kwargs': { + 'INPUT_IDL': '*', + 'OUTPUT_PATH': '*', + }, + 'pargs': 0, + }, + 'draco_get_required_emscripten_flags': { + 'kwargs': { + 'FLAG_LIST_VAR_COMPILER': '*', + 'FLAG_LIST_VAR_LINKER': '*', + }, + 'pargs': 0, + }, + 'draco_option': { + 'kwargs': { + 'NAME': '*', + 'HELPSTRING': '*', + 'VALUE': '*', + }, + 'pargs': 0, + }, + # Rules for built in CMake commands and those from dependencies. + 'list': { + 'kwargs': { + 'APPEND': '*', + 'FILTER': '*', + 'FIND': '*', + 'GET': '*', + 'INSERT': '*', + 'JOIN': '*', + 'LENGTH': '*', + 'POP_BACK': '*', + 'POP_FRONT': '*', + 'PREPEND': '*', + 'REMOVE_DUPLICATES': '*', + 'REMOVE_ITEM': '*', + 'REVERSE': '*', + 'SORT': '*', + 'SUBLIST': '*', + 'TRANSFORM': '*', + }, + }, + 'protobuf_generate': { + 'kwargs': { + 'IMPORT_DIRS': '*', + 'LANGUAGE': '*', + 'OUT_VAR': '*', + 'PROTOC_OUT_DIR': '*', + 'PROTOS': '*', + }, + }, + } + +with section('format'): + # Formatting options. + + # How wide to allow formatted cmake files + line_width = 80 + + # How many spaces to tab for indent + tab_size = 2 + + # If true, separate flow control names from their parentheses with a space + separate_ctrl_name_with_space = False + + # If true, separate function names from parentheses with a space + separate_fn_name_with_space = False + + # If a statement is wrapped to more than one line, than dangle the closing + # parenthesis on its own line. + dangle_parens = False + + # Do not sort argument lists. + enable_sort = False + + # What style line endings to use in the output. + line_ending = 'unix' + + # Format command names consistently as 'lower' or 'upper' case + command_case = 'canonical' + + # Format keywords consistently as 'lower' or 'upper' case + keyword_case = 'upper' diff --git a/third-party/draco/.gitattributes b/third-party/draco/.gitattributes new file mode 100644 index 0000000000..96acfc6120 --- /dev/null +++ b/third-party/draco/.gitattributes @@ -0,0 +1 @@ +*.obj eol=lf \ No newline at end of file diff --git a/third-party/draco/.github/dependabot.yml b/third-party/draco/.github/dependabot.yml new file mode 100644 index 0000000000..ad95b4a6b4 --- /dev/null +++ b/third-party/draco/.github/dependabot.yml @@ -0,0 +1,13 @@ +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "bundler" + directory: "/docs" + schedule: + interval: "monthly" + groups: + doc-gems-security: + applies-to: "security-updates" + patterns: + - "*" diff --git a/third-party/draco/.github/workflows/ci.yml b/third-party/draco/.github/workflows/ci.yml new file mode 100644 index 0000000000..23f943f6d6 --- /dev/null +++ b/third-party/draco/.github/workflows/ci.yml @@ -0,0 +1,318 @@ +on: + pull_request: + # Run on all pull requests. + + push: + # Run on merges/pushes to main. + branches: + - main + + schedule: + # Run nightly, at midnight. + - cron: '8 0 * * *' + +name: draco-ci + +jobs: + # Main build and test job. + draco-tests: + strategy: + matrix: + include: + - test_name: macos-make-release-shared + os: macos-latest + cmake_configure_command: |- + cmake .. -G "Unix Makefiles" \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DDRACO_TESTS=ON + cmake_build_command: cmake --build . -- -j2 + draco_test_command: ./draco_tests + - test_name: macos-make-release-shared-with-transcoder + os: macos-latest + cmake_configure_command: |- + cmake .. -G "Unix Makefiles" \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DDRACO_TESTS=ON \ + -DDRACO_TRANSCODER_SUPPORTED=ON + cmake_build_command: cmake --build . -- -j2 + draco_test_command: ./draco_tests + + - test_name: macos-make-release-static + os: macos-latest + cmake_configure_command: |- + cmake .. -G "Unix Makefiles" \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DDRACO_TESTS=ON + cmake_build_command: cmake --build . -- -j2 + draco_test_command: ./draco_tests + - test_name: macos-make-release-static-with-transcoder + os: macos-latest + cmake_configure_command: |- + cmake .. -G "Unix Makefiles" \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DDRACO_TESTS=ON \ + -DDRACO_TRANSCODER_SUPPORTED=ON + cmake_build_command: cmake --build . -- -j2 + draco_test_command: ./draco_tests + + - test_name: macos-xcode-release-shared + os: macos-latest + cmake_configure_command: |- + cmake .. -G Xcode \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_CONFIGURATION_TYPES=Release \ + -DDRACO_TESTS=ON + cmake_build_command: cmake --build . --config Release + draco_test_command: Release/draco_tests + - test_name: macos-xcode-release-shared-with-transcoder + os: macos-latest + cmake_configure_command: |- + cmake .. -G Xcode \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_CONFIGURATION_TYPES=Release \ + -DDRACO_TESTS=ON \ + -DDRACO_TRANSCODER_SUPPORTED=ON + cmake_build_command: cmake --build . --config Release + draco_test_command: Release/draco_tests + + - test_name: macos-xcode-release-static + os: macos-latest + cmake_configure_command: |- + cmake .. -G Xcode \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_CONFIGURATION_TYPES=Release \ + -DDRACO_TESTS=ON + cmake_build_command: cmake --build . --config Release + draco_test_command: Release/draco_tests + - test_name: macos-xcode-release-static-with-transcoder + os: macos-latest + cmake_configure_command: |- + cmake .. -G Xcode \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_CONFIGURATION_TYPES=Release \ + -DDRACO_TESTS=ON \ + -DDRACO_TRANSCODER_SUPPORTED=ON + cmake_build_command: cmake --build . --config Release + draco_test_command: Release/draco_tests + + - test_name: ubuntu-make-release-shared + os: ubuntu-latest + cmake_configure_command: |- + cmake .. -G "Unix Makefiles" \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=gcc-10 \ + -DCMAKE_CXX_COMPILER=g++-10 \ + -DDRACO_TESTS=ON + cmake_build_command: cmake --build . -- -j2 + draco_test_command: ./draco_tests + - test_name: ubuntu-make-release-shared-with-transcoder + os: ubuntu-latest + cmake_configure_command: |- + cmake .. -G "Unix Makefiles" \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=gcc-10 \ + -DCMAKE_CXX_COMPILER=g++-10 \ + -DDRACO_TESTS=ON \ + -DDRACO_TRANSCODER_SUPPORTED=ON + cmake_build_command: cmake --build . -- -j2 + draco_test_command: ./draco_tests + + - test_name: ubuntu-make-release-static + os: ubuntu-latest + cmake_configure_command: |- + cmake .. -G "Unix Makefiles" \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=gcc-10 \ + -DCMAKE_CXX_COMPILER=g++-10 \ + -DDRACO_TESTS=ON + cmake_build_command: cmake --build . -- -j2 + draco_test_command: ./draco_tests + - test_name: ubuntu-make-release-static-with-transcoder + os: ubuntu-latest + cmake_configure_command: |- + cmake .. -G "Unix Makefiles" \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=gcc-10 \ + -DCMAKE_CXX_COMPILER=g++-10 \ + -DDRACO_TESTS=ON \ + -DDRACO_TRANSCODER_SUPPORTED=ON + cmake_build_command: cmake --build . -- -j2 + draco_test_command: ./draco_tests + + - test_name: windows-msvc-release-shared + os: windows-2019 + cmake_configure_command: |- + cmake .. -G "Visual Studio 16 2019" \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_CONFIGURATION_TYPES=Release \ + -DDRACO_TESTS=ON + cmake_build_command: cmake --build . --config Release -- -m:2 + draco_test_command: Release/draco_tests + - test_name: windows-msvc-release-shared-with-transcoder + os: windows-2019 + cmake_configure_command: |- + cmake .. -G "Visual Studio 16 2019" \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_CONFIGURATION_TYPES=Release \ + -DDRACO_TESTS=ON \ + -DDRACO_TRANSCODER_SUPPORTED=ON + cmake_build_command: cmake --build . --config Release -- -m:2 + draco_test_command: Release/draco_tests + + - test_name: windows-msvc-release-static + os: windows-2019 + cmake_configure_command: |- + cmake .. -G "Visual Studio 16 2019" \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_CONFIGURATION_TYPES=Release \ + -DDRACO_TESTS=ON + cmake_build_command: cmake --build . --config Release -- -m:2 + draco_test_command: Release/draco_tests + - test_name: windows-msvc-release-static-with-transcoder + os: windows-2019 + cmake_configure_command: |- + cmake .. -G "Visual Studio 16 2019" \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_CONFIGURATION_TYPES=Release \ + -DDRACO_TESTS=ON \ + -DDRACO_TRANSCODER_SUPPORTED=ON + cmake_build_command: cmake --build . --config Release -- -m:2 + draco_test_command: Release/draco_tests + + - test_name: windows-make-release-shared + os: windows-2019 + cmake_configure_command: |- + cmake .. -G "MinGW Makefiles" \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \ + -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ \ + -DDRACO_TESTS=ON + cmake_build_command: cmake --build . -- -j2 + draco_test_command: ./draco_tests + - test_name: windows-make-release-shared-with-transcoder + os: windows-2019 + cmake_configure_command: |- + cmake .. -G "MinGW Makefiles" \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \ + -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ \ + -DDRACO_TESTS=ON \ + -DDRACO_TRANSCODER_SUPPORTED=ON + cmake_build_command: cmake --build . -- -j2 + draco_test_command: ./draco_tests + + - test_name: windows-make-release-static + os: windows-2019 + cmake_configure_command: |- + cmake .. -G "MinGW Makefiles" \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \ + -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ \ + -DDRACO_TESTS=ON + cmake_build_command: cmake --build . -- -j2 + draco_test_command: ./draco_tests + - test_name: windows-make-release-static-with-transcoder + os: windows-2019 + cmake_configure_command: |- + cmake .. -G "MinGW Makefiles" \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \ + -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ \ + -DDRACO_TESTS=ON \ + -DDRACO_TRANSCODER_SUPPORTED=ON + cmake_build_command: cmake --build . -- -j2 + draco_test_command: ./draco_tests + + name: test-${{ matrix.test_name }} + runs-on: ${{ matrix.os }} + + steps: + - name: Clone Draco with Submodules. + uses: actions/checkout@v2 + with: + submodules: true + + - name: Create build directory + shell: bash + run: mkdir _gh_build + + - name: Configure CMake build + shell: bash + run: ${{ matrix.cmake_configure_command }} + working-directory: ./_gh_build + + - name: Build with CMake + shell: bash + run: ${{ matrix.cmake_build_command }} + working-directory: ./_gh_build + + - name: Run tests + shell: bash + run: ${{ matrix.draco_test_command }} + working-directory: ./_gh_build + + # Runs src/draco/tools/install_test. + draco-install-tests: + strategy: + matrix: + include: + - test_name: ubuntu-make + os: ubuntu-latest + test_command: python3 test.py -v -G "Unix Makefiles" + - test_name: ubuntu-make-with-transcoder + os: ubuntu-latest + test_command: python3 test.py -v -t -G "Unix Makefiles" + + - test_name: macos-make + os: macos-latest + test_command: python3 test.py -v -G "Unix Makefiles" + - test_name: macos-make-with-transcoder + os: macos-latest + test_command: python3 test.py -v -t -G "Unix Makefiles" + + - test_name: macos-xcode + os: macos-latest + test_command: python3 test.py -v -G Xcode + - test_name: macos-xcode-with-transcoder + os: macos-latest + test_command: python3 test.py -v -t -G Xcode + + - test_name: windows-make + os: windows-2019 + test_command: python3 test.py -v -G "MinGW Makefiles" + - test_name: windows-make-with-transcoder + os: windows-2019 + test_command: python3 test.py -v -t -G "MinGW Makefiles" + + - test_name: windows-msvc + os: windows-2019 + test_command: python3 test.py -v -G "Visual Studio 16 2019" + - test_name: windows-msvc-with-transcoder + os: windows-2019 + test_command: python3 test.py -v -t -G "Visual Studio 16 2019" + + name: install-test-${{ matrix.test_name }} + runs-on: ${{ matrix.os }} + + steps: + - name: Clone Draco with Submodules + uses: actions/checkout@v2 + with: + submodules: true + + - name: Run src/draco/tools/install_test/test.py + shell: bash + run: ${{ matrix.test_command }} + working-directory: ./src/draco/tools/install_test diff --git a/third-party/draco/.gitignore b/third-party/draco/.gitignore new file mode 100644 index 0000000000..5409cebd8d --- /dev/null +++ b/third-party/draco/.gitignore @@ -0,0 +1,2 @@ +docs/_site +src/draco/draco_features.h diff --git a/third-party/draco/.gitmodules b/third-party/draco/.gitmodules new file mode 100644 index 0000000000..25f0a1c032 --- /dev/null +++ b/third-party/draco/.gitmodules @@ -0,0 +1,12 @@ +[submodule "third_party/googletest"] + path = third_party/googletest + url = https://github.com/google/googletest.git +[submodule "third_party/eigen"] + path = third_party/eigen + url = https://gitlab.com/libeigen/eigen.git +[submodule "third_party/tinygltf"] + path = third_party/tinygltf + url = https://github.com/syoyo/tinygltf.git +[submodule "third_party/filesystem"] + path = third_party/filesystem + url = https://github.com/gulrak/filesystem diff --git a/third-party/draco/AUTHORS b/third-party/draco/AUTHORS new file mode 100644 index 0000000000..67f63a6712 --- /dev/null +++ b/third-party/draco/AUTHORS @@ -0,0 +1,7 @@ +# This is the list of Draco authors for copyright purposes. +# +# This does not necessarily list everyone who has contributed code, since in +# some cases, their employer may be the copyright holder. To see the full list +# of contributors, see the revision history in source control. +Google Inc. +and other contributors diff --git a/third-party/draco/BUILDING.md b/third-party/draco/BUILDING.md new file mode 100644 index 0000000000..340b2b83b8 --- /dev/null +++ b/third-party/draco/BUILDING.md @@ -0,0 +1,375 @@ +_**Contents**_ + + * [CMake Basics](#cmake-basics) + * [Mac OS X](#mac-os-x) + * [Windows](#windows) + * [CMake Build Configuration](#cmake-build-configuration) + * [Transcoder](#transcoder) + * [Debugging and Optimization](#debugging-and-optimization) + * [Googletest Integration](#googletest-integration) + * [Third Party Libraries](#third-party-libraries) + * [Javascript Encoder/Decoder](#javascript-encoderdecoder) + * [WebAssembly Decoder](#webassembly-decoder) + * [WebAssembly Mesh Only Decoder](#webassembly-mesh-only-decoder) + * [WebAssembly Point Cloud Only Decoder](#webassembly-point-cloud-only-decoder) + * [iOS Builds](#ios-builds) + * [Android Studio Project Integration](#android-studio-project-integration) + * [Native Android Builds](#native-android-builds) + * [vcpkg](#vcpkg) + +Building +======== +For all platforms, you must first generate the project/make files and then +compile the examples. + +CMake Basics +------------ + +To generate project/make files for the default toolchain on your system, run +`cmake` from a directory where you would like to generate build files, and pass +it the path to your Draco repository. + +E.g. Starting from Draco root. + +~~~~~ bash +$ mkdir build_dir && cd build_dir +$ cmake ../ +~~~~~ + +On Windows, the above command will produce Visual Studio project files for the +newest Visual Studio detected on the system. On Mac OS X and Linux systems, +the above command will produce a `makefile`. + +To control what types of projects are generated, add the `-G` parameter to the +`cmake` command. This argument must be followed by the name of a generator. +Running `cmake` with the `--help` argument will list the available +generators for your system. + +Mac OS X +--------- + +On Mac OS X, run the following command to generate Xcode projects: + +~~~~~ bash +$ cmake ../ -G Xcode +~~~~~ + +Windows +------- + +On a Windows box you would run the following command to generate Visual Studio +2019 projects: + +~~~~~ bash +C:\Users\nobody> cmake ../ -G "Visual Studio 16 2019" -A Win32 +~~~~~ + +To generate 64-bit Windows Visual Studio 2019 projects: + +~~~~~ bash +C:\Users\nobody> cmake ../ -G "Visual Studio 16 2019" -A x64 +~~~~~ + + +CMake Build Configuration +------------------------- + +Transcoder +---------- + +Before attempting to build Draco with transcoding support you must run an +additional Git command to obtain the submodules: + +~~~~~ bash +# Run this command from within your Draco clone. +$ git submodule update --init +# See below if you prefer to use existing versions of Draco dependencies. +~~~~~ + +In order to build the `draco_transcoder` target, the transcoding support needs +to be explicitly enabled when you run `cmake`, for example: + +~~~~~ bash +$ cmake ../ -DDRACO_TRANSCODER_SUPPORTED=ON +~~~~~ + +The above option is currently not compatible with our Javascript or WebAssembly +builds but all other use cases are supported. Note that binaries and libraries +built with the transcoder support may result in increased binary sizes of the +produced libraries and executables compared to the default CMake settings. + +The following CMake variables can be used to configure Draco to use local +copies of third party dependencies instead of git submodules. + +- `DRACO_EIGEN_PATH`: this path must contain an Eigen directory that includes + the Eigen sources. +- `DRACO_FILESYSTEM_PATH`: this path must contain the ghc directory where the + filesystem includes are located. +- `DRACO_TINYGLTF_PATH`: this path must contain tiny_gltf.h and its + dependencies. + +When not specified the Draco build requires the presence of the submodules that +are stored within `draco/third_party`. + +Debugging and Optimization +-------------------------- + +Unlike Visual Studio and Xcode projects, the build configuration for make +builds is controlled when you run `cmake`. The following examples demonstrate +various build configurations. + +Omitting the build type produces makefiles that use release build flags +by default: + +~~~~~ bash +$ cmake ../ +~~~~~ + +A makefile using release (optimized) flags is produced like this: + +~~~~~ bash +$ cmake ../ -DCMAKE_BUILD_TYPE=Release +~~~~~ + +A release build with debug info can be produced as well: + +~~~~~ bash +$ cmake ../ -DCMAKE_BUILD_TYPE=RelWithDebInfo +~~~~~ + +And your standard debug build will be produced using: + +~~~~~ bash +$ cmake ../ -DCMAKE_BUILD_TYPE=Debug +~~~~~ + +To enable the use of sanitizers when the compiler in use supports them, set the +sanitizer type when running CMake: + +~~~~~ bash +$ cmake ../ -DDRACO_SANITIZE=address +~~~~~ + +Googletest Integration +---------------------- + +Draco includes testing support built using Googletest. The Googletest repository +is included as a submodule of the Draco git repository. Run the following +command to clone the Googletest repository: + +~~~~~ bash +$ git submodule update --init +~~~~~ + +To enable Googletest unit test support the DRACO_TESTS cmake variable must be +turned on at cmake generation time: + +~~~~~ bash +$ cmake ../ -DDRACO_TESTS=ON +~~~~~ + +To run the tests execute `draco_tests` from your build output directory: + +~~~~~ bash +$ ./draco_tests +~~~~~ + +Draco can be configured to use a local Googletest installation. The +`DRACO_GOOGLETEST_PATH` variable overrides the behavior described above and +configures Draco to use the Googletest at the specified path. + +Third Party Libraries +--------------------- + +When Draco is built with transcoding and/or testing support enabled the project +has dependencies on third party libraries: + +- [Eigen](https://eigen.tuxfamily.org/) + - Provides various math utilites. +- [Googletest](https://github.com/google/googletest) + - Provides testing support. +- [Gulrak/filesystem](https://github.com/gulrak/filesystem) + - Provides C++17 std::filesystem emulation for pre-C++17 environments. +- [TinyGLTF](https://github.com/syoyo/tinygltf) + - Provides GLTF I/O support. + +These dependencies are managed as Git submodules. To obtain the dependencies +run the following command in your Draco repository: + +~~~~~ bash +$ git submodule update --init +~~~~~ + +WebAssembly Decoder +------------------- + +The WebAssembly decoder can be built using the existing cmake build file by +passing the path the Emscripten's cmake toolchain file at cmake generation time +in the CMAKE_TOOLCHAIN_FILE variable and enabling the WASM build option. +In addition, the EMSCRIPTEN environment variable must be set to the local path +of the parent directory of the Emscripten tools directory. + +~~~~~ bash +# Make the path to emscripten available to cmake. +$ export EMSCRIPTEN=/path/to/emscripten/tools/parent + +# Emscripten.cmake can be found within your Emscripten installation directory, +# it should be the subdir: cmake/Modules/Platform/Emscripten.cmake +$ cmake ../ -DCMAKE_TOOLCHAIN_FILE=/path/to/Emscripten.cmake -DDRACO_WASM=ON + +# Build the WebAssembly decoder. +$ make + +# Run the Javascript wrapper through Closure. +$ java -jar closure.jar --compilation_level SIMPLE --js draco_decoder.js --js_output_file draco_wasm_wrapper.js + +~~~~~ + +WebAssembly Mesh Only Decoder +----------------------------- + +~~~~~ bash + +# cmake command line for mesh only WebAssembly decoder. +$ cmake ../ -DCMAKE_TOOLCHAIN_FILE=/path/to/Emscripten.cmake -DDRACO_WASM=ON -DDRACO_POINT_CLOUD_COMPRESSION=OFF + +~~~~~ + +WebAssembly Point Cloud Only Decoder +----------------------------- + +~~~~~ bash + +# cmake command line for point cloud only WebAssembly decoder. +$ cmake ../ -DCMAKE_TOOLCHAIN_FILE=/path/to/Emscripten.cmake -DDRACO_WASM=ON -DDRACO_MESH_COMPRESSION=OFF + +~~~~~ + +Javascript Encoder/Decoder +------------------ + +The javascript encoder and decoder can be built using the existing cmake build +file by passing the path the Emscripten's cmake toolchain file at cmake +generation time in the CMAKE_TOOLCHAIN_FILE variable. +In addition, the EMSCRIPTEN environment variable must be set to the local path +of the parent directory of the Emscripten tools directory. + +*Note* The WebAssembly decoder should be favored over the JavaScript decoder. + +~~~~~ bash +# Make the path to emscripten available to cmake. +$ export EMSCRIPTEN=/path/to/emscripten/tools/parent + +# Emscripten.cmake can be found within your Emscripten installation directory, +# it should be the subdir: cmake/Modules/Platform/Emscripten.cmake +$ cmake ../ -DCMAKE_TOOLCHAIN_FILE=/path/to/Emscripten.cmake + +# Build the Javascript encoder and decoder. +$ make +~~~~~ + +iOS Builds +--------------------- +These are the basic commands needed to build Draco for iOS targets. +~~~~~ bash + +#arm64 +$ cmake ../ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/arm64-ios.cmake +$ make + +#x86_64 +$ cmake ../ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/x86_64-ios.cmake +$ make + +#armv7 +$ cmake ../ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/armv7-ios.cmake +$ make + +#i386 +$ cmake ../ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/i386-ios.cmake +$ make +~~~~~~ + +After building for each target the libraries can be merged into a single +universal/fat library using lipo, and then used in iOS applications. + + +Native Android Builds +--------------------- + +It's sometimes useful to build Draco command line tools and run them directly on +Android devices via adb. + +~~~~~ bash +# This example is for armeabi-v7a. +$ cmake ../ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/android.cmake \ + -DDRACO_ANDROID_NDK_PATH=path/to/ndk -DANDROID_ABI=armeabi-v7a +$ make + +# See the android.cmake toolchain file for additional ANDROID_ABI options and +# other configurable Android variables. +~~~~~ + +After building the tools they can be moved to an android device via the use of +`adb push`, and then run within an `adb shell` instance. + + +Android Studio Project Integration +---------------------------------- + +Tested on Android Studio 3.5.3. + + +Draco - Static Library +---------------------- + +To include Draco in an existing or new Android Studio project, reference it +from the `cmake` file of an existing native project that has a minimum SDK +version of 18 or higher. The project must support C++11. +To add Draco to your project: + + 1. Create a new "Native C++" project. + + 2. Add the following somewhere within the `CMakeLists.txt` for your project + before the `add_library()` for your project's native-lib: + + ~~~~~ cmake + # Note "/path/to/draco" must be changed to the path where you have cloned + # the Draco sources. + + add_subdirectory(/path/to/draco + ${CMAKE_BINARY_DIR}/draco_build) + include_directories("${CMAKE_BINARY_DIR}" /path/to/draco) + ~~~~~ + + 3. Add the library target "draco" to the `target_link_libraries()` call for + your project's native-lib. The `target_link_libraries()` call for an + empty activity native project looks like this after the addition of + Draco: + + ~~~~~ cmake + target_link_libraries( # Specifies the target library. + native-lib + + # Tells cmake this build depends on libdraco. + draco + + # Links the target library to the log library + # included in the NDK. + ${log-lib} ) + +vcpkg +--------------------- +You can download and install Draco using the +[vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager: + + git clone https://github.com/Microsoft/vcpkg.git + cd vcpkg + ./bootstrap-vcpkg.sh + ./vcpkg integrate install + vcpkg install draco + +The Draco port in vcpkg is kept up to date by Microsoft team members and +community contributors. If the version is out of date, please +[create an issue or pull request](https://github.com/Microsoft/vcpkg) on the +vcpkg repository. diff --git a/third-party/draco/CMAKE.md b/third-party/draco/CMAKE.md new file mode 100644 index 0000000000..392c6ce401 --- /dev/null +++ b/third-party/draco/CMAKE.md @@ -0,0 +1,106 @@ +# CMake Build System Overview + +[TOC] + +This document provides a general layout of the Draco CMake build system. + +## Core Build System Files + +These files are listed in order of interest to maintainers of the build system. + +- `CMakeLists.txt` is the main driver of the build system. It's responsible + for defining targets and source lists, surfacing build system options, and + tying the components of the build system together. + +- `cmake/draco_build_definitions.cmake` defines the macro + `draco_set_build_definitions()`, which is called from `CMakeLists.txt` to + configure include paths, compiler and linker flags, library settings, + platform speficic configuration, and other build system settings that + depend on optional build configurations. + +- `cmake/draco_targets.cmake` defines the macros `draco_add_library()` and + `draco_add_executable()` which are used to create all targets in the CMake + build. These macros attempt to behave in a manner that loosely mirrors the + blaze `cc_library()` and `cc_binary()` commands. Note that + `draco_add_executable()` is also used for tests. + +- `cmake/draco_emscripten.cmake` handles Emscripten SDK integration. It + defines several Emscripten specific macros that are required to build the + Emscripten specific targets defined in `CMakeLists.txt`. + +- `cmake/draco_flags.cmake` defines macros related to compiler and linker + flags. Testing macros, macros for isolating flags to specific source files, + and the main flag configuration function for the library are defined here. + +- `cmake/draco_options.cmake` defines macros that control optional features + of draco, and help track draco library and build system options. + +- `cmake/draco_install.cmake` defines the draco install target. + +- `cmake/draco_cpu_detection.cmake` determines the optimization types to + enable based on target system processor as reported by CMake. + +- `cmake/draco_intrinsics.cmake` manages flags for source files that use + intrinsics. It handles detection of whether flags are necessary, and the + application of the flags to the sources that need them when they are + required. + +## Helper and Utility Files + +- `.cmake-format.py` Defines coding style for cmake-format. + +- `cmake/draco_helpers.cmake` defines utility macros. + +- `cmake/draco_sanitizer.cmake` defines the `draco_configure_sanitizer()` + macro, which implements support for `DRACO_SANITIZE`. It handles the + compiler and linker flags necessary for using sanitizers like asan and msan. + +- `cmake/draco_variables.cmake` defines macros for tracking and control of + draco build system variables. + +## Toolchain Files + +These files help facilitate cross compiling of draco for various targets. + +- `cmake/toolchains/aarch64-linux-gnu.cmake` provides cross compilation + support for arm64 targets. + +- `cmake/toolchains/android.cmake` provides cross compilation support for + Android targets. + +- `cmake/toolchains/arm-linux-gnueabihf.cmake` provides cross compilation + support for armv7 targets. + +- `cmake/toolchains/arm64-ios.cmake`, `cmake/toolchains/armv7-ios.cmake`, + and `cmake/toolchains/armv7s-ios.cmake` provide support for iOS. + +- `cmake/toolchains/arm64-linux-gcc.cmake` and + `cmake/toolchains/armv7-linux-gcc.cmake` are deprecated, but remain for + compatibility. `cmake/toolchains/android.cmake` should be used instead. + +- `cmake/toolchains/arm64-android-ndk-libcpp.cmake`, + `cmake/toolchains/armv7-android-ndk-libcpp.cmake`, + `cmake/toolchains/x86-android-ndk-libcpp.cmake`, and + `cmake/toolchains/x86_64-android-ndk-libcpp.cmake` are deprecated, but + remain for compatibility. `cmake/toolchains/android.cmake` should be used + instead. + +- `cmake/toolchains/i386-ios.cmake` and `cmake/toolchains/x86_64-ios.cmake` + provide support for the iOS simulator. + +- `cmake/toolchains/android-ndk-common.cmake` and + `cmake/toolchains/arm-ios-common.cmake` are support files used by other + toolchain files. + +## Template Files + +These files are inputs to the CMake build and are used to generate inputs to the +build system output by CMake. + +- `cmake/draco-config.cmake.template` is used to produce + draco-config.cmake. draco-config.cmake can be used by CMake to find draco + when another CMake project depends on draco. + +- `cmake/draco.pc.template` is used to produce draco's pkg-config file. + Some build systems use pkg-config to configure include and library paths + when they depend upon third party libraries like draco. diff --git a/third-party/draco/CMakeLists.txt b/third-party/draco/CMakeLists.txt new file mode 100644 index 0000000000..af3c5946ed --- /dev/null +++ b/third-party/draco/CMakeLists.txt @@ -0,0 +1,1156 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) +if(DRACO_TRANSCODER_SUPPORTED) + set(CMAKE_CXX_STANDARD 17) +endif() +project(draco C CXX) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +set(draco_root "${CMAKE_CURRENT_SOURCE_DIR}") +set(draco_src_root "${draco_root}/src/draco") +set(draco_build "${CMAKE_BINARY_DIR}") + +if("${draco_root}" STREQUAL "${draco_build}") + message( + FATAL_ERROR + "Building from within the Draco source tree is not supported.\n" + "Hint: Run these commands\n" + "$ rm -rf CMakeCache.txt CMakeFiles\n" + "$ mkdir -p ../draco_build\n" + "$ cd ../draco_build\n" + "And re-run CMake from the draco_build directory.") +endif() + +include(FindPythonInterp) +include("${draco_root}/cmake/draco_build_definitions.cmake") +include("${draco_root}/cmake/draco_cpu_detection.cmake") +include("${draco_root}/cmake/draco_dependencies.cmake") +include("${draco_root}/cmake/draco_emscripten.cmake") +include("${draco_root}/cmake/draco_flags.cmake") +include("${draco_root}/cmake/draco_helpers.cmake") +include("${draco_root}/cmake/draco_install.cmake") +include("${draco_root}/cmake/draco_intrinsics.cmake") +include("${draco_root}/cmake/draco_options.cmake") +include("${draco_root}/cmake/draco_sanitizer.cmake") +include("${draco_root}/cmake/draco_targets.cmake") +include("${draco_root}/cmake/draco_tests.cmake") +include("${draco_root}/cmake/draco_variables.cmake") + +# C++ and linker flags. +draco_track_configuration_variable(DRACO_CXX_FLAGS) +draco_track_configuration_variable(DRACO_EXE_LINKER_FLAGS) + +# Sanitizer integration. +draco_track_configuration_variable(DRACO_SANITIZE) + +# Generated source file directory. +draco_track_configuration_variable(DRACO_GENERATED_SOURCES_DIRECTORY) + +# Controls use of std::mutex and absl::Mutex in ThreadPool. +draco_track_configuration_variable(DRACO_THREADPOOL_USE_STD_MUTEX) + + +if(DRACO_VERBOSE) + draco_dump_cmake_flag_variables() + draco_dump_tracked_configuration_variables() + draco_dump_options() +endif() + +# Compiler/linker flags must be lists, but come in from the environment as +# strings. Break them up: +if(NOT "${DRACO_CXX_FLAGS}" STREQUAL "") + separate_arguments(DRACO_CXX_FLAGS) +endif() +if(NOT "${DRACO_EXE_LINKER_FLAGS}" STREQUAL "") + separate_arguments(DRACO_EXE_LINKER_FLAGS) +endif() + +draco_reset_target_lists() +draco_setup_options() +draco_set_build_definitions() +draco_set_cxx_flags() +draco_set_exe_linker_flags() +draco_generate_features_h() + +# Draco source file listing variables. +list( + APPEND draco_attributes_sources + "${draco_src_root}/attributes/attribute_octahedron_transform.cc" + "${draco_src_root}/attributes/attribute_octahedron_transform.h" + "${draco_src_root}/attributes/attribute_quantization_transform.cc" + "${draco_src_root}/attributes/attribute_quantization_transform.h" + "${draco_src_root}/attributes/attribute_transform.cc" + "${draco_src_root}/attributes/attribute_transform.h" + "${draco_src_root}/attributes/attribute_transform_data.h" + "${draco_src_root}/attributes/attribute_transform_type.h" + "${draco_src_root}/attributes/geometry_attribute.cc" + "${draco_src_root}/attributes/geometry_attribute.h" + "${draco_src_root}/attributes/geometry_indices.h" + "${draco_src_root}/attributes/point_attribute.cc" + "${draco_src_root}/attributes/point_attribute.h") + +list( + APPEND + draco_compression_attributes_dec_sources + "${draco_src_root}/compression/attributes/attributes_decoder.cc" + "${draco_src_root}/compression/attributes/attributes_decoder.h" + "${draco_src_root}/compression/attributes/attributes_decoder_interface.h" + "${draco_src_root}/compression/attributes/kd_tree_attributes_decoder.cc" + "${draco_src_root}/compression/attributes/kd_tree_attributes_decoder.h" + "${draco_src_root}/compression/attributes/kd_tree_attributes_shared.h" + "${draco_src_root}/compression/attributes/mesh_attribute_indices_encoding_data.h" + "${draco_src_root}/compression/attributes/normal_compression_utils.h" + "${draco_src_root}/compression/attributes/point_d_vector.h" + "${draco_src_root}/compression/attributes/sequential_attribute_decoder.cc" + "${draco_src_root}/compression/attributes/sequential_attribute_decoder.h" + "${draco_src_root}/compression/attributes/sequential_attribute_decoders_controller.cc" + "${draco_src_root}/compression/attributes/sequential_attribute_decoders_controller.h" + "${draco_src_root}/compression/attributes/sequential_integer_attribute_decoder.cc" + "${draco_src_root}/compression/attributes/sequential_integer_attribute_decoder.h" + "${draco_src_root}/compression/attributes/sequential_normal_attribute_decoder.cc" + "${draco_src_root}/compression/attributes/sequential_normal_attribute_decoder.h" + "${draco_src_root}/compression/attributes/sequential_quantization_attribute_decoder.cc" + "${draco_src_root}/compression/attributes/sequential_quantization_attribute_decoder.h" +) + +list( + APPEND + draco_compression_attributes_enc_sources + "${draco_src_root}/compression/attributes/attributes_encoder.cc" + "${draco_src_root}/compression/attributes/attributes_encoder.h" + "${draco_src_root}/compression/attributes/kd_tree_attributes_encoder.cc" + "${draco_src_root}/compression/attributes/kd_tree_attributes_encoder.h" + "${draco_src_root}/compression/attributes/linear_sequencer.h" + "${draco_src_root}/compression/attributes/points_sequencer.h" + "${draco_src_root}/compression/attributes/sequential_attribute_encoder.cc" + "${draco_src_root}/compression/attributes/sequential_attribute_encoder.h" + "${draco_src_root}/compression/attributes/sequential_attribute_encoders_controller.cc" + "${draco_src_root}/compression/attributes/sequential_attribute_encoders_controller.h" + "${draco_src_root}/compression/attributes/sequential_integer_attribute_encoder.cc" + "${draco_src_root}/compression/attributes/sequential_integer_attribute_encoder.h" + "${draco_src_root}/compression/attributes/sequential_normal_attribute_encoder.cc" + "${draco_src_root}/compression/attributes/sequential_normal_attribute_encoder.h" + "${draco_src_root}/compression/attributes/sequential_quantization_attribute_encoder.cc" + "${draco_src_root}/compression/attributes/sequential_quantization_attribute_encoder.h" +) + + +list( + APPEND + draco_compression_attributes_pred_schemes_dec_sources + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_decoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_factory.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_interface.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h" +) + +list( + APPEND + draco_compression_attributes_pred_schemes_enc_sources + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_encoder.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_factory.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_interface.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h" +) + +list( + APPEND + draco_compression_bit_coders_sources + "${draco_src_root}/compression/bit_coders/adaptive_rans_bit_coding_shared.h" + "${draco_src_root}/compression/bit_coders/adaptive_rans_bit_decoder.cc" + "${draco_src_root}/compression/bit_coders/adaptive_rans_bit_decoder.h" + "${draco_src_root}/compression/bit_coders/adaptive_rans_bit_encoder.cc" + "${draco_src_root}/compression/bit_coders/adaptive_rans_bit_encoder.h" + "${draco_src_root}/compression/bit_coders/direct_bit_decoder.cc" + "${draco_src_root}/compression/bit_coders/direct_bit_decoder.h" + "${draco_src_root}/compression/bit_coders/direct_bit_encoder.cc" + "${draco_src_root}/compression/bit_coders/direct_bit_encoder.h" + "${draco_src_root}/compression/bit_coders/folded_integer_bit_decoder.h" + "${draco_src_root}/compression/bit_coders/folded_integer_bit_encoder.h" + "${draco_src_root}/compression/bit_coders/rans_bit_decoder.cc" + "${draco_src_root}/compression/bit_coders/rans_bit_decoder.h" + "${draco_src_root}/compression/bit_coders/rans_bit_encoder.cc" + "${draco_src_root}/compression/bit_coders/rans_bit_encoder.h" + "${draco_src_root}/compression/bit_coders/symbol_bit_decoder.cc" + "${draco_src_root}/compression/bit_coders/symbol_bit_decoder.h" + "${draco_src_root}/compression/bit_coders/symbol_bit_encoder.cc" + "${draco_src_root}/compression/bit_coders/symbol_bit_encoder.h") + +list( + APPEND draco_enc_config_sources + "${draco_src_root}/compression/config/compression_shared.h" + "${draco_src_root}/compression/config/draco_options.h" + "${draco_src_root}/compression/config/encoder_options.h" + "${draco_src_root}/compression/config/encoding_features.h") + +list( + APPEND draco_dec_config_sources + "${draco_src_root}/compression/config/compression_shared.h" + "${draco_src_root}/compression/config/decoder_options.h" + "${draco_src_root}/compression/config/draco_options.h") + +list(APPEND draco_compression_options_sources + "${draco_src_root}/compression/draco_compression_options.cc" + "${draco_src_root}/compression/draco_compression_options.h") + +list(APPEND draco_compression_decode_sources + "${draco_src_root}/compression/decode.cc" + "${draco_src_root}/compression/decode.h") + +list( + APPEND draco_compression_encode_sources + "${draco_src_root}/compression/encode.cc" + "${draco_src_root}/compression/encode.h" + "${draco_src_root}/compression/encode_base.h" + "${draco_src_root}/compression/expert_encode.cc" + "${draco_src_root}/compression/expert_encode.h") + +list( + APPEND + draco_compression_mesh_traverser_sources + "${draco_src_root}/compression/mesh/traverser/depth_first_traverser.h" + "${draco_src_root}/compression/mesh/traverser/max_prediction_degree_traverser.h" + "${draco_src_root}/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h" + "${draco_src_root}/compression/mesh/traverser/mesh_traversal_sequencer.h" + "${draco_src_root}/compression/mesh/traverser/traverser_base.h") + +list( + APPEND + draco_compression_mesh_dec_sources + "${draco_src_root}/compression/mesh/mesh_decoder.cc" + "${draco_src_root}/compression/mesh/mesh_decoder.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_decoder.cc" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_decoder.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_decoder_impl.cc" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_decoder_impl.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_shared.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_traversal_decoder.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h" + "${draco_src_root}/compression/mesh/mesh_sequential_decoder.cc" + "${draco_src_root}/compression/mesh/mesh_sequential_decoder.h") + +list( + APPEND + draco_compression_mesh_enc_sources + "${draco_src_root}/compression/mesh/mesh_edgebreaker_encoder.cc" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_encoder.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_encoder_impl.cc" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_encoder_impl.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_shared.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_traversal_encoder.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h" + "${draco_src_root}/compression/mesh/mesh_encoder.cc" + "${draco_src_root}/compression/mesh/mesh_encoder.h" + "${draco_src_root}/compression/mesh/mesh_sequential_encoder.cc" + "${draco_src_root}/compression/mesh/mesh_sequential_encoder.h") + +list( + APPEND + draco_compression_point_cloud_dec_sources + "${draco_src_root}/compression/point_cloud/point_cloud_decoder.cc" + "${draco_src_root}/compression/point_cloud/point_cloud_decoder.h" + "${draco_src_root}/compression/point_cloud/point_cloud_kd_tree_decoder.cc" + "${draco_src_root}/compression/point_cloud/point_cloud_kd_tree_decoder.h" + "${draco_src_root}/compression/point_cloud/point_cloud_sequential_decoder.cc" + "${draco_src_root}/compression/point_cloud/point_cloud_sequential_decoder.h" +) + +list( + APPEND + draco_compression_point_cloud_enc_sources + "${draco_src_root}/compression/point_cloud/point_cloud_encoder.cc" + "${draco_src_root}/compression/point_cloud/point_cloud_encoder.h" + "${draco_src_root}/compression/point_cloud/point_cloud_kd_tree_encoder.cc" + "${draco_src_root}/compression/point_cloud/point_cloud_kd_tree_encoder.h" + "${draco_src_root}/compression/point_cloud/point_cloud_sequential_encoder.cc" + "${draco_src_root}/compression/point_cloud/point_cloud_sequential_encoder.h" +) + +list( + APPEND draco_compression_entropy_sources + "${draco_src_root}/compression/entropy/ans.h" + "${draco_src_root}/compression/entropy/rans_symbol_coding.h" + "${draco_src_root}/compression/entropy/rans_symbol_decoder.h" + "${draco_src_root}/compression/entropy/rans_symbol_encoder.h" + "${draco_src_root}/compression/entropy/shannon_entropy.cc" + "${draco_src_root}/compression/entropy/shannon_entropy.h" + "${draco_src_root}/compression/entropy/symbol_decoding.cc" + "${draco_src_root}/compression/entropy/symbol_decoding.h" + "${draco_src_root}/compression/entropy/symbol_encoding.cc" + "${draco_src_root}/compression/entropy/symbol_encoding.h") + +list( + APPEND draco_core_sources + "${draco_src_root}/core/bit_utils.cc" + "${draco_src_root}/core/bit_utils.h" + "${draco_src_root}/core/bounding_box.cc" + "${draco_src_root}/core/bounding_box.h" + "${draco_src_root}/core/constants.h" + "${draco_src_root}/core/cycle_timer.cc" + "${draco_src_root}/core/cycle_timer.h" + "${draco_src_root}/core/data_buffer.cc" + "${draco_src_root}/core/data_buffer.h" + "${draco_src_root}/core/decoder_buffer.cc" + "${draco_src_root}/core/decoder_buffer.h" + "${draco_src_root}/core/divide.cc" + "${draco_src_root}/core/divide.h" + "${draco_src_root}/core/draco_index_type.h" + "${draco_src_root}/core/draco_index_type_vector.h" + "${draco_src_root}/core/draco_types.cc" + "${draco_src_root}/core/draco_types.h" + "${draco_src_root}/core/draco_version.h" + "${draco_src_root}/core/encoder_buffer.cc" + "${draco_src_root}/core/encoder_buffer.h" + "${draco_src_root}/core/hash_utils.cc" + "${draco_src_root}/core/hash_utils.h" + "${draco_src_root}/core/macros.h" + "${draco_src_root}/core/math_utils.h" + "${draco_src_root}/core/options.cc" + "${draco_src_root}/core/options.h" + "${draco_src_root}/core/quantization_utils.cc" + "${draco_src_root}/core/quantization_utils.h" + "${draco_src_root}/core/status.h" + "${draco_src_root}/core/status_or.h" + "${draco_src_root}/core/varint_decoding.h" + "${draco_src_root}/core/varint_encoding.h" + "${draco_src_root}/core/vector_d.h") + +list( + APPEND draco_io_sources + "${draco_src_root}/io/file_reader_factory.cc" + "${draco_src_root}/io/file_reader_factory.h" + "${draco_src_root}/io/file_reader_interface.h" + "${draco_src_root}/io/file_utils.cc" + "${draco_src_root}/io/file_utils.h" + "${draco_src_root}/io/file_writer_factory.cc" + "${draco_src_root}/io/file_writer_factory.h" + "${draco_src_root}/io/file_writer_interface.h" + "${draco_src_root}/io/file_writer_utils.h" + "${draco_src_root}/io/file_writer_utils.cc" + "${draco_src_root}/io/mesh_io.cc" + "${draco_src_root}/io/mesh_io.h" + "${draco_src_root}/io/obj_decoder.cc" + "${draco_src_root}/io/obj_decoder.h" + "${draco_src_root}/io/obj_encoder.cc" + "${draco_src_root}/io/obj_encoder.h" + "${draco_src_root}/io/parser_utils.cc" + "${draco_src_root}/io/parser_utils.h" + "${draco_src_root}/io/ply_decoder.cc" + "${draco_src_root}/io/ply_decoder.h" + "${draco_src_root}/io/ply_encoder.cc" + "${draco_src_root}/io/ply_encoder.h" + "${draco_src_root}/io/ply_property_reader.h" + "${draco_src_root}/io/ply_property_writer.h" + "${draco_src_root}/io/ply_reader.cc" + "${draco_src_root}/io/ply_reader.h" + "${draco_src_root}/io/stl_decoder.cc" + "${draco_src_root}/io/stl_decoder.h" + "${draco_src_root}/io/stl_encoder.cc" + "${draco_src_root}/io/stl_encoder.h" + "${draco_src_root}/io/point_cloud_io.cc" + "${draco_src_root}/io/point_cloud_io.h" + "${draco_src_root}/io/stdio_file_reader.cc" + "${draco_src_root}/io/stdio_file_reader.h" + "${draco_src_root}/io/stdio_file_writer.cc" + "${draco_src_root}/io/stdio_file_writer.h") + +list( + APPEND draco_mesh_sources + "${draco_src_root}/mesh/corner_table.cc" + "${draco_src_root}/mesh/corner_table.h" + "${draco_src_root}/mesh/corner_table_iterators.h" + "${draco_src_root}/mesh/mesh.cc" + "${draco_src_root}/mesh/mesh.h" + "${draco_src_root}/mesh/mesh_are_equivalent.cc" + "${draco_src_root}/mesh/mesh_are_equivalent.h" + "${draco_src_root}/mesh/mesh_attribute_corner_table.cc" + "${draco_src_root}/mesh/mesh_attribute_corner_table.h" + "${draco_src_root}/mesh/mesh_cleanup.cc" + "${draco_src_root}/mesh/mesh_cleanup.h" + "${draco_src_root}/mesh/mesh_features.cc" + "${draco_src_root}/mesh/mesh_features.h" + "${draco_src_root}/mesh/mesh_indices.h" + "${draco_src_root}/mesh/mesh_misc_functions.cc" + "${draco_src_root}/mesh/mesh_misc_functions.h" + "${draco_src_root}/mesh/mesh_stripifier.cc" + "${draco_src_root}/mesh/mesh_stripifier.h" + "${draco_src_root}/mesh/triangle_soup_mesh_builder.cc" + "${draco_src_root}/mesh/triangle_soup_mesh_builder.h" + "${draco_src_root}/mesh/valence_cache.h") + +list( + APPEND draco_point_cloud_sources + "${draco_src_root}/point_cloud/point_cloud.cc" + "${draco_src_root}/point_cloud/point_cloud.h" + "${draco_src_root}/point_cloud/point_cloud_builder.cc" + "${draco_src_root}/point_cloud/point_cloud_builder.h") + +list( + APPEND + draco_points_common_sources + "${draco_src_root}/compression/point_cloud/algorithms/point_cloud_compression_method.h" + "${draco_src_root}/compression/point_cloud/algorithms/point_cloud_types.h" + "${draco_src_root}/compression/point_cloud/algorithms/quantize_points_3.h" + "${draco_src_root}/compression/point_cloud/algorithms/queuing_policy.h") + +list( + APPEND + draco_points_dec_sources + "${draco_src_root}/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.cc" + "${draco_src_root}/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h" + "${draco_src_root}/compression/point_cloud/algorithms/float_points_tree_decoder.cc" + "${draco_src_root}/compression/point_cloud/algorithms/float_points_tree_decoder.h" +) + +list( + APPEND + draco_points_enc_sources + "${draco_src_root}/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.cc" + "${draco_src_root}/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h" + "${draco_src_root}/compression/point_cloud/algorithms/float_points_tree_encoder.cc" + "${draco_src_root}/compression/point_cloud/algorithms/float_points_tree_encoder.h" +) + +list( + APPEND draco_metadata_sources + "${draco_src_root}/metadata/geometry_metadata.cc" + "${draco_src_root}/metadata/geometry_metadata.h" + "${draco_src_root}/metadata/metadata.cc" + "${draco_src_root}/metadata/metadata.h" + "${draco_src_root}/metadata/property_attribute.cc" + "${draco_src_root}/metadata/property_attribute.h" + "${draco_src_root}/metadata/property_table.cc" + "${draco_src_root}/metadata/property_table.h" + "${draco_src_root}/metadata/structural_metadata.cc" + "${draco_src_root}/metadata/structural_metadata.h" + "${draco_src_root}/metadata/structural_metadata_schema.cc" + "${draco_src_root}/metadata/structural_metadata_schema.h") + +list(APPEND draco_metadata_enc_sources + "${draco_src_root}/metadata/metadata_encoder.cc" + "${draco_src_root}/metadata/metadata_encoder.h") + +list(APPEND draco_metadata_dec_sources + "${draco_src_root}/metadata/metadata_decoder.cc" + "${draco_src_root}/metadata/metadata_decoder.h") + +list(APPEND draco_animation_sources + "${draco_src_root}/animation/keyframe_animation.cc" + "${draco_src_root}/animation/keyframe_animation.h") + +list(APPEND draco_animation_enc_sources + "${draco_src_root}/animation/keyframe_animation_encoder.cc" + "${draco_src_root}/animation/keyframe_animation_encoder.h") + +list(APPEND draco_animation_dec_sources + "${draco_src_root}/animation/keyframe_animation_decoder.cc" + "${draco_src_root}/animation/keyframe_animation_decoder.h") + +list( + APPEND draco_js_dec_sources + "${draco_src_root}/javascript/emscripten/decoder_webidl_wrapper.cc" + "${draco_src_root}/javascript/emscripten/draco_decoder_glue_wrapper.cc" +) + +list( + APPEND draco_js_enc_sources + "${draco_src_root}/javascript/emscripten/draco_encoder_glue_wrapper.cc" + "${draco_src_root}/javascript/emscripten/encoder_webidl_wrapper.cc") + +list( + APPEND + draco_animation_js_dec_sources + "${draco_src_root}/javascript/emscripten/animation_decoder_webidl_wrapper.cc" + "${draco_src_root}/javascript/emscripten/draco_animation_decoder_glue_wrapper.cc" +) + +list( + APPEND + draco_animation_js_enc_sources + "${draco_src_root}/javascript/emscripten/animation_encoder_webidl_wrapper.cc" + "${draco_src_root}/javascript/emscripten/draco_animation_encoder_glue_wrapper.cc" +) + +list(APPEND draco_unity_plug_sources + "${draco_src_root}/unity/draco_unity_plugin.cc" + "${draco_src_root}/unity/draco_unity_plugin.h") + +list(APPEND draco_maya_plug_sources + "${draco_src_root}/maya/draco_maya_plugin.cc" + "${draco_src_root}/maya/draco_maya_plugin.h") + +if(DRACO_TRANSCODER_SUPPORTED) + list( + APPEND draco_animation_sources + "${draco_src_root}/animation/animation.cc" + "${draco_src_root}/animation/animation.h" + "${draco_src_root}/animation/node_animation_data.h" + "${draco_src_root}/animation/skin.cc" + "${draco_src_root}/animation/skin.h") + + list( + APPEND draco_io_sources + "${draco_src_root}/io/gltf_decoder.cc" + "${draco_src_root}/io/gltf_decoder.h" + "${draco_src_root}/io/gltf_encoder.cc" + "${draco_src_root}/io/gltf_encoder.h" + "${draco_src_root}/io/gltf_utils.cc" + "${draco_src_root}/io/gltf_utils.h" + "${draco_src_root}/io/image_compression_options.h" + "${draco_src_root}/io/scene_io.cc" + "${draco_src_root}/io/scene_io.h" + "${draco_src_root}/io/texture_io.cc" + "${draco_src_root}/io/texture_io.h" + "${draco_src_root}/io/tiny_gltf_utils.cc" + "${draco_src_root}/io/tiny_gltf_utils.h") + + list( + APPEND draco_material_sources + "${draco_src_root}/material/material.cc" + "${draco_src_root}/material/material.h" + "${draco_src_root}/material/material_library.cc" + "${draco_src_root}/material/material_library.h") + + list( + APPEND draco_mesh_sources + "${draco_src_root}/mesh/mesh_connected_components.h" + "${draco_src_root}/mesh/mesh_splitter.cc" + "${draco_src_root}/mesh/mesh_splitter.h" + "${draco_src_root}/mesh/mesh_utils.cc" + "${draco_src_root}/mesh/mesh_utils.h") + + list( + APPEND draco_scene_sources + "${draco_src_root}/scene/instance_array.cc" + "${draco_src_root}/scene/instance_array.h" + "${draco_src_root}/scene/light.cc" + "${draco_src_root}/scene/light.h" + "${draco_src_root}/scene/mesh_group.h" + "${draco_src_root}/scene/scene.cc" + "${draco_src_root}/scene/scene.h" + "${draco_src_root}/scene/scene_are_equivalent.cc" + "${draco_src_root}/scene/scene_are_equivalent.h" + "${draco_src_root}/scene/scene_indices.h" + "${draco_src_root}/scene/scene_node.h" + "${draco_src_root}/scene/scene_utils.cc" + "${draco_src_root}/scene/scene_utils.h" + "${draco_src_root}/scene/trs_matrix.cc" + "${draco_src_root}/scene/trs_matrix.h") + + list( + APPEND draco_texture_sources + "${draco_src_root}/texture/source_image.cc" + "${draco_src_root}/texture/source_image.h" + "${draco_src_root}/texture/texture.h" + "${draco_src_root}/texture/texture_library.cc" + "${draco_src_root}/texture/texture_library.h" + "${draco_src_root}/texture/texture_map.cc" + "${draco_src_root}/texture/texture_map.h" + "${draco_src_root}/texture/texture_transform.cc" + "${draco_src_root}/texture/texture_transform.h" + "${draco_src_root}/texture/texture_utils.cc" + "${draco_src_root}/texture/texture_utils.h") + + +endif() + +# +# Draco targets. +# +if(EMSCRIPTEN AND DRACO_JS_GLUE) + # Draco decoder and encoder "executable" targets in various flavors for + # Emscripten. + + if(DRACO_TRANSCODER_SUPPORTED) + message(FATAL_ERROR "The transcoder is not supported in Emscripten.") + endif() + + list( + APPEND draco_decoder_src + ${draco_attributes_sources} + ${draco_compression_attributes_dec_sources} + ${draco_compression_attributes_pred_schemes_dec_sources} + ${draco_compression_bit_coders_sources} + ${draco_compression_decode_sources} + ${draco_compression_entropy_sources} + ${draco_compression_mesh_traverser_sources} + ${draco_compression_mesh_dec_sources} + ${draco_compression_options_sources} + ${draco_compression_point_cloud_dec_sources} + ${draco_core_sources} + ${draco_dec_config_sources} + ${draco_js_dec_sources} + ${draco_mesh_sources} + ${draco_metadata_dec_sources} + ${draco_metadata_sources} + ${draco_point_cloud_sources} + ${draco_points_dec_sources}) + + list( + APPEND draco_encoder_src + ${draco_attributes_sources} + ${draco_compression_attributes_enc_sources} + ${draco_compression_attributes_pred_schemes_enc_sources} + ${draco_compression_bit_coders_sources} + ${draco_compression_encode_sources} + ${draco_compression_entropy_sources} + ${draco_compression_mesh_traverser_sources} + ${draco_compression_mesh_enc_sources} + ${draco_compression_options_sources} + ${draco_compression_point_cloud_enc_sources} + ${draco_core_sources} + ${draco_enc_config_sources} + ${draco_js_enc_sources} + ${draco_mesh_sources} + ${draco_metadata_enc_sources} + ${draco_metadata_sources} + ${draco_point_cloud_sources} + ${draco_points_enc_sources}) + + list(APPEND draco_js_dec_idl + "${draco_src_root}/javascript/emscripten/draco_web_decoder.idl") + list(APPEND draco_js_enc_idl + "${draco_src_root}/javascript/emscripten/draco_web_encoder.idl") + list( + APPEND + draco_animation_js_dec_idl + "${draco_src_root}/javascript/emscripten/draco_animation_web_decoder.idl") + list( + APPEND + draco_animation_js_enc_idl + "${draco_src_root}/javascript/emscripten/draco_animation_web_encoder.idl") + list(APPEND draco_pre_link_js_sources + "${draco_src_root}/javascript/emscripten/prepareCallbacks.js" + "${draco_src_root}/javascript/emscripten/version.js") + list(APPEND draco_post_link_js_sources + "${draco_src_root}/javascript/emscripten/finalize.js") + list(APPEND draco_post_link_js_decoder_sources ${draco_post_link_js_sources} + "${draco_src_root}/javascript/emscripten/decoder_functions.js") + + set(draco_decoder_glue_path "${draco_build}/glue_decoder") + set(draco_encoder_glue_path "${draco_build}/glue_encoder") + + draco_generate_emscripten_glue(INPUT_IDL ${draco_js_dec_idl} + OUTPUT_PATH ${draco_decoder_glue_path}) + draco_generate_emscripten_glue(INPUT_IDL ${draco_js_enc_idl} + OUTPUT_PATH ${draco_encoder_glue_path}) + + if(DRACO_DECODER_ATTRIBUTE_DEDUPLICATION) + list(APPEND draco_decoder_features + "DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED" + "DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED") + endif() + + draco_add_emscripten_executable( + NAME draco_decoder + SOURCES ${draco_decoder_src} + DEFINES ${draco_defines} + FEATURES ${draco_decoder_features} + INCLUDES ${draco_include_paths} + LINK_FLAGS "-sEXPORT_NAME=\"DracoDecoderModule\"" + GLUE_PATH ${draco_decoder_glue_path} + PRE_LINK_JS_SOURCES ${draco_pre_link_js_sources} + POST_LINK_JS_SOURCES ${draco_post_link_js_decoder_sources}) + + draco_add_emscripten_executable( + NAME draco_encoder + SOURCES ${draco_encoder_src} + DEFINES ${draco_defines} + FEATURES DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED + DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED + INCLUDES ${draco_include_paths} + LINK_FLAGS "-sEXPORT_NAME=\"DracoEncoderModule\"" + GLUE_PATH ${draco_encoder_glue_path} + PRE_LINK_JS_SOURCES ${draco_pre_link_js_sources} + POST_LINK_JS_SOURCES ${draco_post_link_js_sources}) + + if(DRACO_ANIMATION_ENCODING) + set(draco_anim_decoder_glue_path "${draco_build}/glue_animation_decoder") + set(draco_anim_encoder_glue_path "${draco_build}/glue_animation_encoder") + + draco_generate_emscripten_glue(INPUT_IDL ${draco_animation_js_dec_idl} + OUTPUT_PATH ${draco_anim_decoder_glue_path}) + draco_generate_emscripten_glue(INPUT_IDL ${draco_animation_js_enc_idl} + OUTPUT_PATH ${draco_anim_encoder_glue_path}) + + draco_add_emscripten_executable( + NAME draco_animation_decoder + SOURCES ${draco_animation_dec_sources} ${draco_animation_js_dec_sources} + ${draco_animation_sources} ${draco_decoder_src} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths} + LINK_FLAGS "-sEXPORT_NAME=\"DracoAnimationDecoderModule\"" + GLUE_PATH ${draco_anim_decoder_glue_path} + PRE_LINK_JS_SOURCES ${draco_pre_link_js_sources} + POST_LINK_JS_SOURCES ${draco_post_link_js_decoder_sources}) + + draco_add_emscripten_executable( + NAME draco_animation_encoder + SOURCES ${draco_animation_enc_sources} ${draco_animation_js_enc_sources} + ${draco_animation_sources} ${draco_encoder_src} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths} + LINK_FLAGS "-sEXPORT_NAME=\"DracoAnimationEncoderModule\"" + GLUE_PATH ${draco_anim_encoder_glue_path} + PRE_LINK_JS_SOURCES ${draco_pre_link_js_sources} + POST_LINK_JS_SOURCES ${draco_post_link_js_sources}) + endif() +else() + # Standard Draco libs, encoder and decoder. Object collections that mirror the + # Draco directory structure. + draco_add_library( + NAME draco_attributes + TYPE OBJECT + SOURCES ${draco_attributes_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_attributes_dec OBJECT + ${draco_compression_attributes_dec_sources} + TYPE OBJECT + SOURCES ${draco_compression_attributes_dec_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_attributes_enc + TYPE OBJECT + SOURCES ${draco_compression_attributes_enc_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_attributes_pred_schemes_dec + TYPE OBJECT + SOURCES ${draco_compression_attributes_pred_schemes_dec_sources}) + draco_add_library( + NAME draco_compression_attributes_pred_schemes_enc + TYPE OBJECT + SOURCES ${draco_compression_attributes_pred_schemes_enc_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_bit_coders + TYPE OBJECT + SOURCES ${draco_compression_bit_coders_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_enc_config + TYPE OBJECT + SOURCES ${draco_enc_config_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_dec_config + TYPE OBJECT + SOURCES ${draco_dec_config_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_decode + TYPE OBJECT + SOURCES ${draco_compression_decode_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_encode + TYPE OBJECT + SOURCES ${draco_compression_encode_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_entropy + TYPE OBJECT + SOURCES ${draco_compression_entropy_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_mesh_traverser + TYPE OBJECT + SOURCES ${draco_compression_mesh_traverser_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_mesh_dec + TYPE OBJECT + SOURCES ${draco_compression_mesh_dec_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_mesh_enc + TYPE OBJECT + SOURCES ${draco_compression_mesh_enc_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_options + TYPE OBJECT + SOURCES ${draco_compression_options_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_point_cloud_dec + TYPE OBJECT + SOURCES ${draco_compression_point_cloud_dec_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_compression_point_cloud_enc + TYPE OBJECT + SOURCES ${draco_compression_point_cloud_enc_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_core + TYPE OBJECT + SOURCES ${draco_core_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_io + TYPE OBJECT + SOURCES ${draco_io_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_mesh + TYPE OBJECT + SOURCES ${draco_mesh_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_metadata_dec + TYPE OBJECT + SOURCES ${draco_metadata_dec_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_metadata_enc + TYPE OBJECT + SOURCES ${draco_metadata_enc_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_metadata + TYPE OBJECT + SOURCES ${draco_metadata_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_animation_dec + TYPE OBJECT + SOURCES ${draco_animation_dec_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_animation_enc + TYPE OBJECT + SOURCES ${draco_animation_enc_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_animation + TYPE OBJECT + SOURCES ${draco_animation_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_point_cloud + TYPE OBJECT + SOURCES ${draco_point_cloud_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_points_dec + TYPE OBJECT + SOURCES ${draco_points_common_sources} ${draco_points_dec_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + draco_add_library( + NAME draco_points_enc + TYPE OBJECT + SOURCES ${draco_points_common_sources} ${draco_points_enc_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + + if(DRACO_TRANSCODER_SUPPORTED) + if(MSVC) + # TODO(https://github.com/google/draco/issues/826) + set_source_files_properties("${draco_src_root}/io/gltf_decoder.cc" + PROPERTIES COMPILE_OPTIONS "/Od") + endif() + + draco_add_library( + NAME draco_material + TYPE OBJECT + SOURCES ${draco_material_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + + draco_add_library( + NAME draco_scene + TYPE OBJECT + SOURCES ${draco_scene_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + + draco_add_library( + NAME draco_texture + TYPE OBJECT + SOURCES ${draco_texture_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + + endif() + + list( + APPEND draco_object_library_deps + draco_attributes + draco_compression_attributes_dec + draco_compression_attributes_enc + draco_compression_attributes_pred_schemes_dec + draco_compression_attributes_pred_schemes_enc + draco_compression_bit_coders + draco_compression_decode + draco_compression_encode + draco_compression_entropy + draco_compression_mesh_dec + draco_compression_mesh_enc + draco_compression_options + draco_compression_point_cloud_dec + draco_compression_point_cloud_enc + draco_core + draco_dec_config + draco_enc_config + draco_io + draco_mesh + draco_metadata + draco_metadata_dec + draco_metadata_enc + draco_animation + draco_animation_dec + draco_animation_enc + draco_point_cloud + draco_points_dec + draco_points_enc) + + if(DRACO_TRANSCODER_SUPPORTED) + list(APPEND draco_object_library_deps draco_material draco_scene + draco_texture) + + endif() + + # Library targets that consume the object collections. + if(WIN32) + # In order to produce a DLL and import library the Windows tools require + # that the exported symbols are part of the DLL target. The unfortunate side + # effect of this is that a single configuration cannot output both the + # static library and the DLL: This results in an either/or situation. + # Windows users of the draco build can have a DLL and an import library, or + # they can have a static library; they cannot have both from a single + # configuration of the build. + if(BUILD_SHARED_LIBS) + set(draco_lib_type SHARED) + else() + set(draco_lib_type STATIC) + endif() + draco_add_library( + NAME draco + OUTPUT_NAME draco + TYPE ${draco_lib_type} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths} + OBJLIB_DEPS ${draco_object_library_deps} + LIB_DEPS ${draco_lib_deps}) + add_library(draco::draco ALIAS draco) + + else() + draco_add_library( + NAME draco_static + OUTPUT_NAME draco + TYPE STATIC + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths} + OBJLIB_DEPS ${draco_object_library_deps} + LIB_DEPS ${draco_lib_deps}) + + if(BUILD_SHARED_LIBS) + draco_add_library( + NAME draco_shared + SOURCES "${draco_src_root}/core/draco_version.h" + OUTPUT_NAME draco + TYPE SHARED + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths} + LIB_DEPS draco_static) + add_library(draco::draco ALIAS draco_shared) + set_target_properties(draco_shared PROPERTIES EXPORT_NAME draco) + else() + add_library(draco::draco ALIAS draco_static) + set_target_properties(draco_static PROPERTIES EXPORT_NAME draco) + endif() + endif() + + if(DRACO_UNITY_PLUGIN) + if(IOS) + set(unity_decoder_lib_type STATIC) + else() + set(unity_decoder_lib_type MODULE) + endif() + + draco_add_library( + NAME draco_unity_plugin + TYPE OBJECT + SOURCES ${draco_unity_plug_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + + draco_add_library( + NAME dracodec_unity + TYPE ${unity_decoder_lib_type} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths} + OBJLIB_DEPS draco_unity_plugin + LIB_DEPS ${draco_plugin_dependency}) + + # For Mac, we need to build a .bundle for the unity plugin. + if(APPLE) + set_target_properties(dracodec_unity PROPERTIES BUNDLE true) + endif() + endif() + + if(DRACO_MAYA_PLUGIN) + draco_add_library( + NAME draco_maya_plugin + TYPE OBJECT + SOURCES ${draco_maya_plug_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths}) + + draco_add_library( + NAME draco_maya_wrapper + TYPE MODULE + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths} + OBJLIB_DEPS draco_maya_plugin + LIB_DEPS ${draco_plugin_dependency}) + + # For Mac, we need to build a .bundle for the plugin. + if(APPLE) + set_target_properties(draco_maya_wrapper PROPERTIES BUNDLE true) + endif() + endif() + + # Draco app targets. + draco_add_executable( + NAME draco_decoder + SOURCES "${draco_src_root}/tools/draco_decoder.cc" ${draco_io_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths} + LIB_DEPS ${draco_dependency}) + + draco_add_executable( + NAME draco_encoder + SOURCES "${draco_src_root}/tools/draco_encoder.cc" ${draco_io_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths} + LIB_DEPS ${draco_dependency}) + + if(DRACO_TRANSCODER_SUPPORTED) + draco_add_executable( + NAME draco_transcoder + SOURCES "${draco_src_root}/tools/draco_transcoder.cc" + "${draco_src_root}/tools/draco_transcoder_lib.cc" + "${draco_src_root}/tools/draco_transcoder_lib.h" + ${draco_io_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths} + LIB_DEPS ${draco_dependency}) + + if(DRACO_SIMPLIFIER_SUPPORTED) + draco_add_executable( + NAME draco_simplifier + SOURCES ${draco_pipeline_proto_header} + "${draco_src_root}/tools/draco_simplifier.cc" + "${draco_src_root}/tools/draco_simplifier_lib.cc" + "${draco_src_root}/tools/draco_simplifier_lib.h" + ${draco_io_sources} + DEFINES ${draco_defines} + INCLUDES ${draco_include_paths} + LIB_DEPS ${draco_dependency}) + endif() + endif() + + draco_setup_install_target() + draco_setup_test_targets() +endif() + +if(DRACO_VERBOSE) + draco_dump_cmake_flag_variables() + draco_dump_tracked_configuration_variables() + draco_dump_options() +endif() diff --git a/third-party/draco/CONTRIBUTING.md b/third-party/draco/CONTRIBUTING.md new file mode 100644 index 0000000000..b7bab34475 --- /dev/null +++ b/third-party/draco/CONTRIBUTING.md @@ -0,0 +1,27 @@ +Want to contribute? Great! First, read this page (including the small print at the end). + +### Before you contribute +Before we can use your code, you must sign the +[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual) +(CLA), which you can do online. The CLA is necessary mainly because you own the +copyright to your changes, even after your contribution becomes part of our +codebase, so we need your permission to use and distribute your code. We also +need to be sure of various other things—for instance that you'll tell us if you +know that your code infringes on other people's patents. You don't have to sign +the CLA until after you've submitted your code for review and a member has +approved it, but you must do it before we can put your code into our codebase. +Before you start working on a larger contribution, you should get in touch with +us first through the issue tracker with your idea so that we can help out and +possibly guide you. Coordinating up front makes it much easier to avoid +frustration later on. + +### Code reviews +All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. +Please make sure that your code conforms with our +[coding style guidelines](https://google.github.io/styleguide/cppguide.html). + +### The small print +Contributions made by corporations are covered by a different agreement than +the one above, the +[Software Grant and Corporate Contributor License Agreement](https://cla.developers.google.com/about/google-corporate). diff --git a/third-party/draco/LICENSE b/third-party/draco/LICENSE new file mode 100644 index 0000000000..3010954548 --- /dev/null +++ b/third-party/draco/LICENSE @@ -0,0 +1,252 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +-------------------------------------------------------------------------------- +Files: docs/assets/js/ASCIIMathML.js + +Copyright (c) 2014 Peter Jipsen and other ASCIIMathML.js contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +-------------------------------------------------------------------------------- +Files: docs/assets/css/pygments/* + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/third-party/draco/README.md b/third-party/draco/README.md new file mode 100644 index 0000000000..fc2c69426d --- /dev/null +++ b/third-party/draco/README.md @@ -0,0 +1,616 @@ +

+ +

+ +[![draco-ci](https://github.com/google/draco/workflows/draco-ci/badge.svg?branch=main)](https://github.com/google/draco/actions/workflows/ci.yml) + +News +======= + +Attention GStatic users: the Draco team strongly recommends using the versioned +URLs for accessing Draco GStatic content. If you are using the URLs that include +the `v1/decoders` substring within the URL, edge caching and GStatic propagation +delays can result in transient errors that can be difficult to diagnose when +new Draco releases are launched. To avoid the issue pin your sites to a +versioned release. + +### Version 1.5.7 release: +* Using the versioned www.gstatic.com WASM and Javascript decoders continues + to be recommended. To use v1.5.7, use this URL: + * https://www.gstatic.com/draco/versioned/decoders/1.5.7/* +* Added support for normalized attributes to Emscripten encoder API. +* Bug fixes. +* Security fixes. + +### Version 1.5.6 release: +* Using the versioned www.gstatic.com WASM and Javascript decoders continues + to be recommended. To use v1.5.6, use this URL: + * https://www.gstatic.com/draco/versioned/decoders/1.5.6/* +* The CMake flag DRACO_DEBUG_MSVC_WARNINGS has been replaced with + DRACO_DEBUG_COMPILER_WARNINGS, and the behavior has changed. It is now a + boolean flag defined in draco_options.cmake. +* Bug fixes. +* Security fixes. + +### Version 1.5.5 release: +* Using the versioned www.gstatic.com WASM and Javascript decoders continues + to be recommended. To use v1.5.5, use this URL: + * https://www.gstatic.com/draco/versioned/decoders/1.5.5/* +* Bug fix: https://github.com/google/draco/issues/935 + +### Version 1.5.4 release: +* Using the versioned www.gstatic.com WASM and Javascript decoders continues + to be recommended. To use v1.5.4, use this URL: + * https://www.gstatic.com/draco/versioned/decoders/1.5.4/* +* Added partial support for glTF extensions EXT_mesh_features and + EXT_structural_metadata. +* Bug fixes. +* Security fixes. + +### Version 1.5.3 release: +* Using the versioned www.gstatic.com WASM and Javascript decoders continues + to be recommended. To use v1.5.3, use this URL: + * https://www.gstatic.com/draco/versioned/decoders/1.5.3/* +* Bug fixes. + +### Version 1.5.2 release +* This is the same as v1.5.1 with the following two bug fixes: + * Fixes DRACO_TRANSCODER_SUPPORTED enabled builds. + * ABI version updated. + +### Version 1.5.1 release +* Adds assertion enabled Emscripten builds to the release, and a subset of the + assertion enabled builds to GStatic. See the file listing below. +* Custom paths to third party dependencies are now supported. See BUILDING.md + for more information. +* The CMake configuration file draco-config.cmake is now tested and known to + work for using Draco in Linux, MacOS, and Windows CMake projects. See the + `install_test` subdirectory of `src/draco/tools` for more information. +* Bug fixes. + +### Version 1.5.0 release +* Adds the draco_transcoder tool. See the section below on the glTF transcoding + tool, and BUILDING.md for build and dependency information. +* Some changes to configuration variables have been made for this release: + - The DRACO_GLTF flag has been renamed to DRACO_GLTF_BITSTREAM to help + increase understanding of its purpose, which is to limit Draco features to + those included in the Draco glTF specification. + - Variables exported in CMake via draco-config.cmake and find-draco.cmake + (formerly FindDraco.cmake) have been renamed. It's unlikely that this + impacts any existing projects as the aforementioned files were not formed + correctly. See [PR775](https://github.com/google/draco/pull/775) for full + details of the changes. +* A CMake version file has been added. +* The CMake install target now uses absolute paths direct from CMake instead + of building them using CMAKE_INSTALL_PREFIX. This was done to make Draco + easier to use for downstream packagers and should have little to no impact on + users picking up Draco from source. +* Certain MSVC warnings have had their levels changed via compiler flag to + reduce the amount of noise output by the MSVC compilers. Set MSVC warning + level to 4, or define DRACO_DEBUG_MSVC_WARNINGS at CMake configuration time + to restore previous behavior. +* Bug fixes. + +### Version 1.4.3 release +* Using the versioned www.gstatic.com WASM and Javascript decoders continues + to be recommended. To use v1.4.3, use this URL: + * https://www.gstatic.com/draco/versioned/decoders/1.4.3/* +* Bug fixes + +### Version 1.4.1 release +* Using the versioned www.gstatic.com WASM and Javascript decoders is now + recommended. To use v1.4.1, use this URL: + * https://www.gstatic.com/draco/versioned/decoders/1.4.1/* + * Replace the * with the files to load. E.g. + * https://www.gstatic.com/draco/versioned/decoders/1.4.1/draco_decoder.js + * This works with the v1.3.6 and v1.4.0 releases, and will work with future + Draco releases. +* Bug fixes + +### Version 1.4.0 release +* WASM and JavaScript decoders are hosted from a static URL. + * It is recommended to always pull your Draco WASM and JavaScript decoders from this URL: + * https://www.gstatic.com/draco/v1/decoders/* + * Replace * with the files to load. E.g. + * https://www.gstatic.com/draco/v1/decoders/draco_decoder_gltf.wasm + * Users will benefit from having the Draco decoder in cache as more sites start using the static URL +* Changed npm modules to use WASM, which increased performance by ~200%. +* Updated Emscripten to 2.0. + * This causes the Draco codec modules to return a promise instead of the module directly. + * Please see the example code on how to handle the promise. +* Changed NORMAL quantization default to 8. +* Added new array API to decoder and deprecated DecoderBuffer. + * See PR https://github.com/google/draco/issues/513 for more information. +* Changed WASM/JavaScript behavior of catching exceptions. + * See issue https://github.com/google/draco/issues/629 for more information. +* Code cleanup. +* Emscripten builds now disable NODEJS_CATCH_EXIT and NODEJS_CATCH_REJECTION. + * Authors of a CLI tool might want to add their own error handlers. +* Added Maya plugin builds. +* Unity plugin builds updated. + * Builds are now stored as archives. + * Added iOS build. + * Unity users may want to look into https://github.com/atteneder/DracoUnity. +* Bug fixes. + +### Version 1.3.6 release +* WASM and JavaScript decoders are now hosted from a static URL + * It is recommended to always pull your Draco WASM and JavaScript decoders from this URL: + * https://www.gstatic.com/draco/v1/decoders/* + * Replace * with the files to load. E.g. + * https://www.gstatic.com/draco/v1/decoders/draco_decoder_gltf.wasm + * Users will benefit from having the Draco decoder in cache as more sites start using the static URL +* Changed web examples to pull Draco decoders from static URL +* Added new API to Draco WASM decoder, which increased performance by ~15% +* Decreased Draco WASM decoder size by ~20% +* Added support for generic and multiple attributes to Draco Unity plug-ins +* Added new API to Draco Unity, which increased decoder performance by ~15% +* Changed quantization defaults: + * POSITION: 11 + * NORMAL: 7 + * TEX_COORD: 10 + * COLOR: 8 + * GENERIC: 8 +* Code cleanup +* Bug fixes + +### Version 1.3.5 release +* Added option to build Draco for Universal Scene Description +* Code cleanup +* Bug fixes + +### Version 1.3.4 release +* Released Draco Animation code +* Fixes for Unity +* Various file location and name changes + +### Version 1.3.3 release +* Added ExpertEncoder to the Javascript API + * Allows developers to set quantization options per attribute id +* Bug fixes + +### Version 1.3.2 release +* Bug fixes + +### Version 1.3.1 release +* Fix issue with multiple attributes when skipping an attribute transform + +### Version 1.3.0 release +* Improved kD-tree based point cloud encoding + * Now applicable to point clouds with any number of attributes + * Support for all integer attribute types and quantized floating point types +* Improved mesh compression up to 10% (on average ~2%) + * For meshes, the 1.3.0 bitstream is fully compatible with 1.2.x decoders +* Improved Javascript API + * Added support for all signed and unsigned integer types + * Added support for point clouds to our Javascript encoder API +* Added support for integer properties to the PLY decoder +* Bug fixes + +### Previous releases +https://github.com/google/draco/releases + +Description +=========== + +Draco is a library for compressing and decompressing 3D geometric [meshes] and +[point clouds]. It is intended to improve the storage and transmission of 3D +graphics. + +Draco was designed and built for compression efficiency and speed. The code +supports compressing points, connectivity information, texture coordinates, +color information, normals, and any other generic attributes associated with +geometry. With Draco, applications using 3D graphics can be significantly +smaller without compromising visual fidelity. For users, this means apps can +now be downloaded faster, 3D graphics in the browser can load quicker, and VR +and AR scenes can now be transmitted with a fraction of the bandwidth and +rendered quickly. + +Draco is released as C++ source code that can be used to compress 3D graphics +as well as C++ and Javascript decoders for the encoded data. + + +_**Contents**_ + + * [Building](#building) + * [Usage](#usage) + * [Unity](#unity) + * [WASM and JavaScript Decoders](#WASM-and-JavaScript-Decoders) + * [Command Line Applications](#command-line-applications) + * [Encoding Tool](#encoding-tool) + * [Encoding Point Clouds](#encoding-point-clouds) + * [Decoding Tool](#decoding-tool) + * [glTF Transcoding Tool](#gltf-transcoding-tool) + * [C++ Decoder API](#c-decoder-api) + * [Javascript Encoder API](#javascript-encoder-api) + * [Javascript Decoder API](#javascript-decoder-api) + * [Javascript Decoder Performance](#javascript-decoder-performance) + * [Metadata API](#metadata-api) + * [NPM Package](#npm-package) + * [three.js Renderer Example](#threejs-renderer-example) + * [GStatic Javascript Builds](#gstatic-javascript-builds) + * [Support](#support) + * [License](#license) + * [References](#references) + + +Building +======== +See [BUILDING](BUILDING.md) for building instructions. + + +Usage +====== + +Unity +----- +For the best information about using Unity with Draco please visit https://github.com/atteneder/DracoUnity + +For a simple example of using Unity with Draco see [README](unity/README.md) in the unity folder. + +WASM and JavaScript Decoders +---------------------------- + +It is recommended to always pull your Draco WASM and JavaScript decoders from: + +~~~~~ bash +https://www.gstatic.com/draco/v1/decoders/ +~~~~~ + +Users will benefit from having the Draco decoder in cache as more sites start using the static URL. + +Command Line Applications +------------------------ + +The default target created from the build files will be the `draco_encoder` +and `draco_decoder` command line applications. Additionally, `draco_transcoder` +is generated when CMake is run with the DRACO_TRANSCODER_SUPPORTED variable set +to ON (see [BUILDING](BUILDING.md#transcoder) for more details). For all +applications, if you run them without any arguments or `-h`, the applications +will output usage and options. + +Encoding Tool +------------- + +`draco_encoder` will read OBJ, STL or PLY files as input, and output +Draco-encoded files. We have included Stanford's [Bunny] mesh for testing. The +basic command line looks like this: + +~~~~~ bash +./draco_encoder -i testdata/bun_zipper.ply -o out.drc +~~~~~ + +A value of `0` for the quantization parameter will not perform any quantization +on the specified attribute. Any value other than `0` will quantize the input +values for the specified attribute to that number of bits. For example: + +~~~~~ bash +./draco_encoder -i testdata/bun_zipper.ply -o out.drc -qp 14 +~~~~~ + +will quantize the positions to 14 bits (default is 11 for the position +coordinates). + +In general, the more you quantize your attributes the better compression rate +you will get. It is up to your project to decide how much deviation it will +tolerate. In general, most projects can set quantization values of about `11` +without any noticeable difference in quality. + +The compression level (`-cl`) parameter turns on/off different compression +features. + +~~~~~ bash +./draco_encoder -i testdata/bun_zipper.ply -o out.drc -cl 8 +~~~~~ + +In general, the highest setting, `10`, will have the most compression but +worst decompression speed. `0` will have the least compression, but best +decompression speed. The default setting is `7`. + +Encoding Point Clouds +--------------------- + +You can encode point cloud data with `draco_encoder` by specifying the +`-point_cloud` parameter. If you specify the `-point_cloud` parameter with a +mesh input file, `draco_encoder` will ignore the connectivity data and encode +the positions from the mesh file. + +~~~~~ bash +./draco_encoder -point_cloud -i testdata/bun_zipper.ply -o out.drc +~~~~~ + +This command line will encode the mesh input as a point cloud, even though the +input might not produce compression that is representative of other point +clouds. Specifically, one can expect much better compression rates for larger +and denser point clouds. + +Decoding Tool +------------- + +`draco_decoder` will read Draco files as input, and output OBJ, STL or PLY +files. The basic command line looks like this: + +~~~~~ bash +./draco_decoder -i in.drc -o out.obj +~~~~~ + +glTF Transcoding Tool +--------------------- + +`draco_transcoder` can be used to add Draco compression to glTF assets. The +basic command line looks like this: + +~~~~~ bash +./draco_transcoder -i in.glb -o out.glb +~~~~~ + +This command line will add geometry compression to all meshes in the `in.glb` +file. Quantization values for different glTF attributes can be specified +similarly to the `draco_encoder` tool. For example `-qp` can be used to define +quantization of the position attribute: + +~~~~~ bash +./draco_transcoder -i in.glb -o out.glb -qp 12 +~~~~~ + +C++ Decoder API +--------------- + +If you'd like to add decoding to your applications you will need to include +the `draco_dec` library. In order to use the Draco decoder you need to +initialize a `DecoderBuffer` with the compressed data. Then call +`DecodeMeshFromBuffer()` to return a decoded mesh object or call +`DecodePointCloudFromBuffer()` to return a decoded `PointCloud` object. For +example: + +~~~~~ cpp +draco::DecoderBuffer buffer; +buffer.Init(data.data(), data.size()); + +const draco::EncodedGeometryType geom_type = + draco::GetEncodedGeometryType(&buffer); +if (geom_type == draco::TRIANGULAR_MESH) { + unique_ptr mesh = draco::DecodeMeshFromBuffer(&buffer); +} else if (geom_type == draco::POINT_CLOUD) { + unique_ptr pc = draco::DecodePointCloudFromBuffer(&buffer); +} +~~~~~ + +Please see [src/draco/mesh/mesh.h](src/draco/mesh/mesh.h) for the full `Mesh` class interface and +[src/draco/point_cloud/point_cloud.h](src/draco/point_cloud/point_cloud.h) for the full `PointCloud` class interface. + + +Javascript Encoder API +---------------------- +The Javascript encoder is located in `javascript/draco_encoder.js`. The encoder +API can be used to compress mesh and point cloud. In order to use the encoder, +you need to first create an instance of `DracoEncoderModule`. Then use this +instance to create `MeshBuilder` and `Encoder` objects. `MeshBuilder` is used +to construct a mesh from geometry data that could be later compressed by +`Encoder`. First create a mesh object using `new encoderModule.Mesh()` . Then, +use `AddFacesToMesh()` to add indices to the mesh and use +`AddFloatAttributeToMesh()` to add attribute data to the mesh, e.g. position, +normal, color and texture coordinates. After a mesh is constructed, you could +then use `EncodeMeshToDracoBuffer()` to compress the mesh. For example: + +~~~~~ js +const mesh = { + indices : new Uint32Array(indices), + vertices : new Float32Array(vertices), + normals : new Float32Array(normals) +}; + +const encoderModule = DracoEncoderModule(); +const encoder = new encoderModule.Encoder(); +const meshBuilder = new encoderModule.MeshBuilder(); +const dracoMesh = new encoderModule.Mesh(); + +const numFaces = mesh.indices.length / 3; +const numPoints = mesh.vertices.length; +meshBuilder.AddFacesToMesh(dracoMesh, numFaces, mesh.indices); + +meshBuilder.AddFloatAttributeToMesh(dracoMesh, encoderModule.POSITION, + numPoints, 3, mesh.vertices); +if (mesh.hasOwnProperty('normals')) { + meshBuilder.AddFloatAttributeToMesh( + dracoMesh, encoderModule.NORMAL, numPoints, 3, mesh.normals); +} +if (mesh.hasOwnProperty('colors')) { + meshBuilder.AddFloatAttributeToMesh( + dracoMesh, encoderModule.COLOR, numPoints, 3, mesh.colors); +} +if (mesh.hasOwnProperty('texcoords')) { + meshBuilder.AddFloatAttributeToMesh( + dracoMesh, encoderModule.TEX_COORD, numPoints, 3, mesh.texcoords); +} + +if (method === "edgebreaker") { + encoder.SetEncodingMethod(encoderModule.MESH_EDGEBREAKER_ENCODING); +} else if (method === "sequential") { + encoder.SetEncodingMethod(encoderModule.MESH_SEQUENTIAL_ENCODING); +} + +const encodedData = new encoderModule.DracoInt8Array(); +// Use default encoding setting. +const encodedLen = encoder.EncodeMeshToDracoBuffer(dracoMesh, + encodedData); +encoderModule.destroy(dracoMesh); +encoderModule.destroy(encoder); +encoderModule.destroy(meshBuilder); + +~~~~~ +Please see [src/draco/javascript/emscripten/draco_web_encoder.idl](src/draco/javascript/emscripten/draco_web_encoder.idl) for the full API. + +Javascript Decoder API +---------------------- + +The Javascript decoder is located in [javascript/draco_decoder.js](javascript/draco_decoder.js). The +Javascript decoder can decode mesh and point cloud. In order to use the +decoder, you must first create an instance of `DracoDecoderModule`. The +instance is then used to create `DecoderBuffer` and `Decoder` objects. Set +the encoded data in the `DecoderBuffer`. Then call `GetEncodedGeometryType()` +to identify the type of geometry, e.g. mesh or point cloud. Then call either +`DecodeBufferToMesh()` or `DecodeBufferToPointCloud()`, which will return +a Mesh object or a point cloud. For example: + +~~~~~ js +// Create the Draco decoder. +const decoderModule = DracoDecoderModule(); +const buffer = new decoderModule.DecoderBuffer(); +buffer.Init(byteArray, byteArray.length); + +// Create a buffer to hold the encoded data. +const decoder = new decoderModule.Decoder(); +const geometryType = decoder.GetEncodedGeometryType(buffer); + +// Decode the encoded geometry. +let outputGeometry; +let status; +if (geometryType == decoderModule.TRIANGULAR_MESH) { + outputGeometry = new decoderModule.Mesh(); + status = decoder.DecodeBufferToMesh(buffer, outputGeometry); +} else { + outputGeometry = new decoderModule.PointCloud(); + status = decoder.DecodeBufferToPointCloud(buffer, outputGeometry); +} + +// You must explicitly delete objects created from the DracoDecoderModule +// or Decoder. +decoderModule.destroy(outputGeometry); +decoderModule.destroy(decoder); +decoderModule.destroy(buffer); +~~~~~ + +Please see [src/draco/javascript/emscripten/draco_web_decoder.idl](src/draco/javascript/emscripten/draco_web_decoder.idl) for the full API. + +Javascript Decoder Performance +------------------------------ + +The Javascript decoder is built with dynamic memory. This will let the decoder +work with all of the compressed data. But this option is not the fastest. +Pre-allocating the memory sees about a 2x decoder speed improvement. If you +know all of your project's memory requirements, you can turn on static memory +by changing `CMakeLists.txt` accordingly. + +Metadata API +------------ +Starting from v1.0, Draco provides metadata functionality for encoding data +other than geometry. It could be used to encode any custom data along with the +geometry. For example, we can enable metadata functionality to encode the name +of attributes, name of sub-objects and customized information. +For one mesh and point cloud, it can have one top-level geometry metadata class. +The top-level metadata then can have hierarchical metadata. Other than that, +the top-level metadata can have metadata for each attribute which is called +attribute metadata. The attribute metadata should be initialized with the +correspondent attribute id within the mesh. The metadata API is provided both +in C++ and Javascript. +For example, to add metadata in C++: + +~~~~~ cpp +draco::PointCloud pc; +// Add metadata for the geometry. +std::unique_ptr metadata = + std::unique_ptr(new draco::GeometryMetadata()); +metadata->AddEntryString("description", "This is an example."); +pc.AddMetadata(std::move(metadata)); + +// Add metadata for attributes. +draco::GeometryAttribute pos_att; +pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3, + draco::DT_FLOAT32, false, 12, 0); +const uint32_t pos_att_id = pc.AddAttribute(pos_att, false, 0); + +std::unique_ptr pos_metadata = + std::unique_ptr( + new draco::AttributeMetadata(pos_att_id)); +pos_metadata->AddEntryString("name", "position"); + +// Directly add attribute metadata to geometry. +// You can do this without explicitly add |GeometryMetadata| to mesh. +pc.AddAttributeMetadata(pos_att_id, std::move(pos_metadata)); +~~~~~ + +To read metadata from a geometry in C++: + +~~~~~ cpp +// Get metadata for the geometry. +const draco::GeometryMetadata *pc_metadata = pc.GetMetadata(); + +// Request metadata for a specific attribute. +const draco::AttributeMetadata *requested_pos_metadata = + pc.GetAttributeMetadataByStringEntry("name", "position"); +~~~~~ + +Please see [src/draco/metadata](src/draco/metadata) and [src/draco/point_cloud](src/draco/point_cloud) for the full API. + +NPM Package +----------- +Draco NPM NodeJS package is located in [javascript/npm/draco3d](javascript/npm/draco3d). Please see the +doc in the folder for detailed usage. + +three.js Renderer Example +------------------------- + +Here's an [example] of a geometric compressed with Draco loaded via a +Javascript decoder using the `three.js` renderer. + +Please see the [javascript/example/README.md](javascript/example/README.md) file for more information. + +GStatic Javascript Builds +========================= + +Prebuilt versions of the Emscripten-built Draco javascript decoders are hosted +on www.gstatic.com in version labeled directories: + +https://www.gstatic.com/draco/versioned/decoders/VERSION/* + +As of the v1.4.3 release the files available are: + +- [draco_decoder.js](https://www.gstatic.com/draco/versioned/decoders/1.4.3/draco_decoder.js) +- [draco_decoder.wasm](https://www.gstatic.com/draco/versioned/decoders/1.4.3/draco_decoder.wasm) +- [draco_decoder_gltf.js](https://www.gstatic.com/draco/versioned/decoders/1.4.3/draco_decoder_gltf.js) +- [draco_decoder_gltf.wasm](https://www.gstatic.com/draco/versioned/decoders/1.4.3/draco_decoder_gltf.wasm) +- [draco_wasm_wrapper.js](https://www.gstatic.com/draco/versioned/decoders/1.4.3/draco_wasm_wrapper.js) +- [draco_wasm_wrapper_gltf.js](https://www.gstatic.com/draco/versioned/decoders/1.4.3/draco_wasm_wrapper_gltf.js) + +Beginning with the v1.5.1 release assertion enabled builds of the following +files are available: + +- [draco_decoder.js](https://www.gstatic.com/draco/versioned/decoders/1.5.1/with_asserts/draco_decoder.js) +- [draco_decoder.wasm](https://www.gstatic.com/draco/versioned/decoders/1.5.1/with_asserts/draco_decoder.wasm) +- [draco_wasm_wrapper.js](https://www.gstatic.com/draco/versioned/decoders/1.5.1/with_asserts/draco_wasm_wrapper.js) + +Support +======= + +For questions/comments please email + +If you have found an error in this library, please file an issue at + + +Patches are encouraged, and may be submitted by forking this project and +submitting a pull request through GitHub. See [CONTRIBUTING] for more detail. + +License +======= +Licensed under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. + +References +========== +[example]:https://storage.googleapis.com/demos.webmproject.org/draco/draco_loader_throw.html +[meshes]: https://en.wikipedia.org/wiki/Polygon_mesh +[point clouds]: https://en.wikipedia.org/wiki/Point_cloud +[Bunny]: https://graphics.stanford.edu/data/3Dscanrep/ +[CONTRIBUTING]: https://raw.githubusercontent.com/google/draco/main/CONTRIBUTING.md + +Bunny model from Stanford's graphic department diff --git a/third-party/draco/cmake/draco-config.cmake.template b/third-party/draco/cmake/draco-config.cmake.template new file mode 100644 index 0000000000..ed86823ea7 --- /dev/null +++ b/third-party/draco/cmake/draco-config.cmake.template @@ -0,0 +1,3 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/draco-targets.cmake") diff --git a/third-party/draco/cmake/draco.pc.template b/third-party/draco/cmake/draco.pc.template new file mode 100644 index 0000000000..050219ccb1 --- /dev/null +++ b/third-party/draco/cmake/draco.pc.template @@ -0,0 +1,6 @@ +Name: @PROJECT_NAME@ +Description: Draco geometry de(com)pression library. +Version: @DRACO_VERSION@ +Cflags: -I@includes_path@ +Libs: -L@libs_path@ -ldraco +Libs.private: @CMAKE_THREAD_LIBS_INIT@ diff --git a/third-party/draco/cmake/draco_build_definitions.cmake b/third-party/draco/cmake/draco_build_definitions.cmake new file mode 100644 index 0000000000..d845b0a1ec --- /dev/null +++ b/third-party/draco/cmake/draco_build_definitions.cmake @@ -0,0 +1,157 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_BUILD_DEFINITIONS_CMAKE_) + return() +endif() # DRACO_CMAKE_DRACO_BUILD_DEFINITIONS_CMAKE_ +set(DRACO_CMAKE_DRACO_BUILD_DEFINITIONS_CMAKE_ 1) + +# Utility for controlling the main draco library dependency. This changes in +# shared builds, and when an optional target requires a shared library build. +macro(set_draco_target) + if(WIN32) + set(draco_dependency draco) + set(draco_plugin_dependency ${draco_dependency}) + else() + if(BUILD_SHARED_LIBS) + set(draco_dependency draco_shared) + else() + set(draco_dependency draco_static) + endif() + set(draco_plugin_dependency draco_static) + endif() +endmacro() + +# Configures flags and sets build system globals. +macro(draco_set_build_definitions) + string(TOLOWER "${CMAKE_BUILD_TYPE}" build_type_lowercase) + + if(build_type_lowercase MATCHES "rel" AND DRACO_FAST) + if(MSVC) + list(APPEND draco_msvc_cxx_flags "/Ox") + else() + list(APPEND draco_base_cxx_flags "-O3") + endif() + endif() + + draco_load_version_info() + + # Library version info. See the libtool docs for updating the values: + # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info + # + # c=, r=, a= + # + # libtool generates a .so file as .so.[c-a].a.r, while -version-info c:r:a is + # passed to libtool. + # + # We set DRACO_SOVERSION = [c-a].a.r + set(LT_CURRENT 9) + set(LT_REVISION 0) + set(LT_AGE 0) + math(EXPR DRACO_SOVERSION_MAJOR "${LT_CURRENT} - ${LT_AGE}") + set(DRACO_SOVERSION "${DRACO_SOVERSION_MAJOR}.${LT_AGE}.${LT_REVISION}") + unset(LT_CURRENT) + unset(LT_REVISION) + unset(LT_AGE) + + list(APPEND draco_include_paths "${draco_root}" "${draco_root}/src" + "${draco_build}") + + if(DRACO_TRANSCODER_SUPPORTED) + draco_setup_eigen() + draco_setup_filesystem() + draco_setup_tinygltf() + + + endif() + + + list(APPEND draco_defines "DRACO_CMAKE=1" + "DRACO_FLAGS_SRCDIR=\"${draco_root}\"" + "DRACO_FLAGS_TMPDIR=\"/tmp\"") + + if(MSVC OR WIN32) + list(APPEND draco_defines "_CRT_SECURE_NO_DEPRECATE=1" "NOMINMAX=1") + + if(BUILD_SHARED_LIBS) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) + endif() + endif() + + if(NOT MSVC) + if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) + # Ensure 64-bit platforms can support large files. + list(APPEND draco_defines "_LARGEFILE_SOURCE" "_FILE_OFFSET_BITS=64") + endif() + + if(NOT DRACO_DEBUG_COMPILER_WARNINGS) + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + list(APPEND draco_clang_cxx_flags + "-Wno-implicit-const-int-float-conversion") + else() + list(APPEND draco_base_cxx_flags "-Wno-deprecated-declarations") + endif() + endif() + endif() + + if(ANDROID) + if(CMAKE_ANDROID_ARCH_ABI STREQUAL "armeabi-v7a") + set(CMAKE_ANDROID_ARM_MODE ON) + endif() + endif() + + set_draco_target() + + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6") + # Quiet warnings in copy-list-initialization where {} elision has always + # been allowed. + list(APPEND draco_clang_cxx_flags "-Wno-missing-braces") + endif() + endif() + + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "7") + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7") + # Quiet gcc 6 vs 7 abi warnings: + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77728 + list(APPEND draco_base_cxx_flags "-Wno-psabi") + list(APPEND ABSL_GCC_FLAGS "-Wno-psabi") + endif() + endif() + endif() + + # Source file names ending in these suffixes will have the appropriate + # compiler flags added to their compile commands to enable intrinsics. + set(draco_neon_source_file_suffix "neon.cc") + set(draco_sse4_source_file_suffix "sse4.cc") + + if((${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" AND ${CMAKE_CXX_COMPILER_VERSION} + VERSION_LESS 5) + OR (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" + AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4)) + message( + WARNING "GNU/GCC < v5 or Clang/LLVM < v4, ENABLING COMPATIBILITY MODE.") + draco_enable_feature(FEATURE "DRACO_OLD_GCC") + endif() + + if(EMSCRIPTEN) + draco_check_emscripten_environment() + draco_get_required_emscripten_flags( + FLAG_LIST_VAR_COMPILER draco_base_cxx_flags + FLAG_LIST_VAR_LINKER draco_base_exe_linker_flags) + endif() + + draco_configure_sanitizer() +endmacro() diff --git a/third-party/draco/cmake/draco_cpu_detection.cmake b/third-party/draco/cmake/draco_cpu_detection.cmake new file mode 100644 index 0000000000..c3b77b80c4 --- /dev/null +++ b/third-party/draco/cmake/draco_cpu_detection.cmake @@ -0,0 +1,42 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_CPU_DETECTION_CMAKE_) + return() +endif() # DRACO_CMAKE_DRACO_CPU_DETECTION_CMAKE_ +set(DRACO_CMAKE_DRACO_CPU_DETECTION_CMAKE_ 1) + +# Detect optimizations available for the current target CPU. +macro(draco_optimization_detect) + if(DRACO_ENABLE_OPTIMIZATIONS) + string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" cpu_lowercase) + if(cpu_lowercase MATCHES "^arm|^aarch64") + set(draco_have_neon ON) + elseif(cpu_lowercase MATCHES "^x86|amd64") + set(draco_have_sse4 ON) + endif() + endif() + + if(draco_have_neon AND DRACO_ENABLE_NEON) + list(APPEND draco_defines "DRACO_ENABLE_NEON=1") + else() + list(APPEND draco_defines "DRACO_ENABLE_NEON=0") + endif() + + if(draco_have_sse4 AND DRACO_ENABLE_SSE4_1) + list(APPEND draco_defines "DRACO_ENABLE_SSE4_1=1") + else() + list(APPEND draco_defines "DRACO_ENABLE_SSE4_1=0") + endif() +endmacro() diff --git a/third-party/draco/cmake/draco_dependencies.cmake b/third-party/draco/cmake/draco_dependencies.cmake new file mode 100644 index 0000000000..91ee0839b8 --- /dev/null +++ b/third-party/draco/cmake/draco_dependencies.cmake @@ -0,0 +1,136 @@ +# Copyright 2022 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_DEPENDENCIES_CMAKE) + return() +endif() +set(DRACO_CMAKE_DRACO_DEPENDENCIES_CMAKE 1) + +include("${draco_root}/cmake/draco_variables.cmake") + +# Each variable holds a user specified custom path to a local copy of the +# sources that belong to each project that Draco depends on. When paths are +# empty the build will be generated pointing to the Draco git submodules. +# Otherwise the paths specified by the user will be used in the build +# configuration. + +# Path to the Eigen. The path must contain the Eigen directory. +set(DRACO_EIGEN_PATH) +draco_track_configuration_variable(DRACO_EIGEN_PATH) + +# Path to the gulrak/filesystem installation. The path specified must contain +# the ghc subdirectory that houses the filesystem includes. +set(DRACO_FILESYSTEM_PATH) +draco_track_configuration_variable(DRACO_FILESYSTEM_PATH) + +# Path to the googletest installation. The path must be to the root of the +# Googletest project directory. +set(DRACO_GOOGLETEST_PATH) +draco_track_configuration_variable(DRACO_GOOGLETEST_PATH) + +# Path to the syoyo/tinygltf installation. The path must be to the root of the +# project directory. +set(DRACO_TINYGLTF_PATH) +draco_track_configuration_variable(DRACO_TINYGLTF_PATH) + +# Utility macro for killing the build due to a missing submodule directory. +macro(draco_die_missing_submodule dir) + message(FATAL_ERROR "${dir} missing, run git submodule update --init") +endmacro() + +# Determines the Eigen location and updates the build configuration accordingly. +macro(draco_setup_eigen) + if(DRACO_EIGEN_PATH) + set(eigen_path "${DRACO_EIGEN_PATH}") + + if(NOT IS_DIRECTORY "${eigen_path}") + message(FATAL_ERROR "DRACO_EIGEN_PATH does not exist.") + endif() + else() + set(eigen_path "${draco_root}/third_party/eigen") + + if(NOT IS_DIRECTORY "${eigen_path}") + draco_die_missing_submodule("${eigen_path}") + endif() + endif() + + set(eigen_include_path "${eigen_path}/Eigen") + + if(NOT EXISTS "${eigen_path}/Eigen") + message(FATAL_ERROR "The eigen path does not contain an Eigen directory.") + endif() + + list(APPEND draco_include_paths "${eigen_path}") +endmacro() + +# Determines the gulrak/filesystem location and updates the build configuration +# accordingly. +macro(draco_setup_filesystem) + if(DRACO_FILESYSTEM_PATH) + set(fs_path "${DRACO_FILESYSTEM_PATH}") + + if(NOT IS_DIRECTORY "${fs_path}") + message(FATAL_ERROR "DRACO_FILESYSTEM_PATH does not exist.") + endif() + else() + set(fs_path "${draco_root}/third_party/filesystem/include") + + if(NOT IS_DIRECTORY "${fs_path}") + draco_die_missing_submodule("${fs_path}") + endif() + endif() + + list(APPEND draco_include_paths "${fs_path}") +endmacro() + +# Determines the Googletest location and sets up include and source list vars +# for the draco_tests build. +macro(draco_setup_googletest) + if(DRACO_GOOGLETEST_PATH) + set(gtest_path "${DRACO_GOOGLETEST_PATH}") + if(NOT IS_DIRECTORY "${gtest_path}") + message(FATAL_ERROR "DRACO_GOOGLETEST_PATH does not exist.") + endif() + else() + set(gtest_path "${draco_root}/third_party/googletest") + endif() + + list(APPEND draco_test_include_paths ${draco_include_paths} + "${gtest_path}/include" "${gtest_path}/googlemock" + "${gtest_path}/googletest/include" "${gtest_path}/googletest") + + list(APPEND draco_gtest_all "${gtest_path}/googletest/src/gtest-all.cc") + list(APPEND draco_gtest_main "${gtest_path}/googletest/src/gtest_main.cc") +endmacro() + + +# Determines the location of TinyGLTF and updates the build configuration +# accordingly. +macro(draco_setup_tinygltf) + if(DRACO_TINYGLTF_PATH) + set(tinygltf_path "${DRACO_TINYGLTF_PATH}") + + if(NOT IS_DIRECTORY "${tinygltf_path}") + message(FATAL_ERROR "DRACO_TINYGLTF_PATH does not exist.") + endif() + else() + set(tinygltf_path "${draco_root}/third_party/tinygltf") + + if(NOT IS_DIRECTORY "${tinygltf_path}") + draco_die_missing_submodule("${tinygltf_path}") + endif() + endif() + + list(APPEND draco_include_paths "${tinygltf_path}") +endmacro() diff --git a/third-party/draco/cmake/draco_emscripten.cmake b/third-party/draco/cmake/draco_emscripten.cmake new file mode 100644 index 0000000000..c9616ae86e --- /dev/null +++ b/third-party/draco/cmake/draco_emscripten.cmake @@ -0,0 +1,232 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_EMSCRIPTEN_CMAKE_) + return() +endif() # DRACO_CMAKE_DRACO_EMSCRIPTEN_CMAKE_ + +# Checks environment for Emscripten prerequisites. +macro(draco_check_emscripten_environment) + if(NOT PYTHONINTERP_FOUND) + message( + FATAL_ERROR + "Python required for Emscripten builds, but cmake cannot find it.") + endif() + if(NOT EXISTS "$ENV{EMSCRIPTEN}") + message( + FATAL_ERROR + "The EMSCRIPTEN environment variable must be set. See README.md.") + endif() +endmacro() + +# Obtains the required Emscripten flags for Draco targets. +macro(draco_get_required_emscripten_flags) + set(em_FLAG_LIST_VAR_COMPILER) + set(em_FLAG_LIST_VAR_LINKER) + set(em_flags) + set(em_single_arg_opts FLAG_LIST_VAR_COMPILER FLAG_LIST_VAR_LINKER) + set(em_multi_arg_opts) + cmake_parse_arguments(em "${em_flags}" "${em_single_arg_opts}" + "${em_multi_arg_opts}" ${ARGN}) + if(NOT em_FLAG_LIST_VAR_COMPILER) + message( + FATAL + "draco_get_required_emscripten_flags: FLAG_LIST_VAR_COMPILER required") + endif() + + if(NOT em_FLAG_LIST_VAR_LINKER) + message( + FATAL + "draco_get_required_emscripten_flags: FLAG_LIST_VAR_LINKER required") + endif() + + if(DRACO_JS_GLUE) + unset(required_flags) + # TODO(tomfinegan): Revisit splitting of compile/link flags for Emscripten, + # and drop -Wno-unused-command-line-argument. Emscripten complains about + # what are supposedly link-only flags sent with compile commands, but then + # proceeds to produce broken code if the warnings are heeded. + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} + "-Wno-unused-command-line-argument") + + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-Wno-almost-asm") + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "--memory-init-file" "0") + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-fno-omit-frame-pointer") + + # According to Emscripten the following flags are linker only, but sending + # these flags (en masse) to only the linker results in a broken Emscripten + # build with an empty DracoDecoderModule. + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sALLOW_MEMORY_GROWTH=1") + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sMODULARIZE=1") + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sFILESYSTEM=0") + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} + "-sEXPORTED_FUNCTIONS=[\"_free\",\"_malloc\"]") + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sPRECISE_F32=1") + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sNODEJS_CATCH_EXIT=0") + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sNODEJS_CATCH_REJECTION=0") + + if(DRACO_FAST) + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "--llvm-lto" "1") + endif() + + # The WASM flag is reported as linker only. + if(DRACO_WASM) + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sWASM=1") + else() + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sWASM=0") + endif() + + # The LEGACY_VM_SUPPORT flag is reported as linker only. + if(DRACO_IE_COMPATIBLE) + list(APPEND ${em_FLAG_LIST_VAR_COMPILER} "-sLEGACY_VM_SUPPORT=1") + endif() + endif() +endmacro() + +# Macro for generating C++ glue code from IDL for Emscripten targets. Executes +# python to generate the C++ binding, and establishes dendency: $OUTPUT_PATH.cpp +# on $INPUT_IDL. +macro(draco_generate_emscripten_glue) + set(glue_flags) + set(glue_single_arg_opts INPUT_IDL OUTPUT_PATH) + set(glue_multi_arg_opts) + cmake_parse_arguments(glue "${glue_flags}" "${glue_single_arg_opts}" + "${glue_multi_arg_opts}" ${ARGN}) + + if(DRACO_VERBOSE GREATER 1) + message( + "--------- draco_generate_emscripten_glue -----------\n" + "glue_INPUT_IDL=${glue_INPUT_IDL}\n" + "glue_OUTPUT_PATH=${glue_OUTPUT_PATH}\n" + "----------------------------------------------------\n") + endif() + + if(NOT glue_INPUT_IDL OR NOT glue_OUTPUT_PATH) + message( + FATAL_ERROR + "draco_generate_emscripten_glue: INPUT_IDL and OUTPUT_PATH required.") + endif() + + # Generate the glue source. + execute_process( + COMMAND ${PYTHON_EXECUTABLE} $ENV{EMSCRIPTEN}/tools/webidl_binder.py + ${glue_INPUT_IDL} ${glue_OUTPUT_PATH}) + if(NOT EXISTS "${glue_OUTPUT_PATH}.cpp") + message(FATAL_ERROR "JS glue generation failed for ${glue_INPUT_IDL}.") + endif() + + # Create a dependency so that it regenerated on edits. + add_custom_command( + OUTPUT "${glue_OUTPUT_PATH}.cpp" + COMMAND ${PYTHON_EXECUTABLE} $ENV{EMSCRIPTEN}/tools/webidl_binder.py + ${glue_INPUT_IDL} ${glue_OUTPUT_PATH} + DEPENDS ${draco_js_dec_idl} + COMMENT "Generating ${glue_OUTPUT_PATH}.cpp." + WORKING_DIRECTORY ${draco_build} + VERBATIM) +endmacro() + +# Wrapper for draco_add_executable() that handles the extra work necessary for +# emscripten targets when generating JS glue: +# +# ~~~ +# - Set source level dependency on the C++ binding. +# - Pre/Post link emscripten magic. +# +# Required args: +# - GLUE_PATH: Base path for glue file. Used to generate .cpp and .js files. +# - PRE_LINK_JS_SOURCES: em_link_pre_js() source files. +# - POST_LINK_JS_SOURCES: em_link_post_js() source files. +# Optional args: +# - FEATURES: +# ~~~ +macro(draco_add_emscripten_executable) + unset(emexe_NAME) + unset(emexe_FEATURES) + unset(emexe_SOURCES) + unset(emexe_DEFINES) + unset(emexe_INCLUDES) + unset(emexe_LINK_FLAGS) + set(optional_args) + set(single_value_args NAME GLUE_PATH) + set(multi_value_args + SOURCES + DEFINES + FEATURES + INCLUDES + LINK_FLAGS + PRE_LINK_JS_SOURCES + POST_LINK_JS_SOURCES) + + cmake_parse_arguments(emexe "${optional_args}" "${single_value_args}" + "${multi_value_args}" ${ARGN}) + + if(NOT + (emexe_GLUE_PATH + AND emexe_POST_LINK_JS_SOURCES + AND emexe_PRE_LINK_JS_SOURCES)) + message(FATAL + "draco_add_emscripten_executable: GLUE_PATH PRE_LINK_JS_SOURCES " + "POST_LINK_JS_SOURCES args required.") + endif() + + if(DRACO_VERBOSE GREATER 1) + message( + "--------- draco_add_emscripten_executable ---------\n" + "emexe_NAME=${emexe_NAME}\n" + "emexe_SOURCES=${emexe_SOURCES}\n" + "emexe_DEFINES=${emexe_DEFINES}\n" + "emexe_INCLUDES=${emexe_INCLUDES}\n" + "emexe_LINK_FLAGS=${emexe_LINK_FLAGS}\n" + "emexe_GLUE_PATH=${emexe_GLUE_PATH}\n" + "emexe_FEATURES=${emexe_FEATURES}\n" + "emexe_PRE_LINK_JS_SOURCES=${emexe_PRE_LINK_JS_SOURCES}\n" + "emexe_POST_LINK_JS_SOURCES=${emexe_POST_LINK_JS_SOURCES}\n" + "----------------------------------------------------\n") + endif() + + # The Emscripten linker needs the C++ flags in addition to whatever has been + # passed in with the target. + list(APPEND emexe_LINK_FLAGS ${DRACO_CXX_FLAGS}) + + if(DRACO_GLTF_BITSTREAM) + # Add "_gltf" suffix to target output name. + draco_add_executable( + NAME ${emexe_NAME} + OUTPUT_NAME ${emexe_NAME}_gltf + SOURCES ${emexe_SOURCES} + DEFINES ${emexe_DEFINES} + INCLUDES ${emexe_INCLUDES} + LINK_FLAGS ${emexe_LINK_FLAGS}) + else() + draco_add_executable( + NAME ${emexe_NAME} + SOURCES ${emexe_SOURCES} + DEFINES ${emexe_DEFINES} + INCLUDES ${emexe_INCLUDES} + LINK_FLAGS ${emexe_LINK_FLAGS}) + endif() + + foreach(feature ${emexe_FEATURES}) + draco_enable_feature(FEATURE ${feature} TARGETS ${emexe_NAME}) + endforeach() + + set_property( + SOURCE ${emexe_SOURCES} + APPEND + PROPERTY OBJECT_DEPENDS "${emexe_GLUE_PATH}.cpp") + em_link_pre_js(${emexe_NAME} ${emexe_PRE_LINK_JS_SOURCES}) + em_link_post_js(${emexe_NAME} "${emexe_GLUE_PATH}.js" + ${emexe_POST_LINK_JS_SOURCES}) +endmacro() diff --git a/third-party/draco/cmake/draco_flags.cmake b/third-party/draco/cmake/draco_flags.cmake new file mode 100644 index 0000000000..f3b24c6e14 --- /dev/null +++ b/third-party/draco/cmake/draco_flags.cmake @@ -0,0 +1,292 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_FLAGS_CMAKE_) + return() +endif() # DRACO_CMAKE_DRACO_FLAGS_CMAKE_ +set(DRACO_CMAKE_DRACO_FLAGS_CMAKE_ 1) + +include(CheckCXXCompilerFlag) +include(CheckCXXSourceCompiles) + +# Adds compiler flags specified by FLAGS to the sources specified by SOURCES: +# +# draco_set_compiler_flags_for_sources(SOURCES FLAGS ) +macro(draco_set_compiler_flags_for_sources) + unset(compiler_SOURCES) + unset(compiler_FLAGS) + unset(optional_args) + unset(single_value_args) + set(multi_value_args SOURCES FLAGS) + cmake_parse_arguments(compiler "${optional_args}" "${single_value_args}" + "${multi_value_args}" ${ARGN}) + + if(NOT (compiler_SOURCES AND compiler_FLAGS)) + draco_die("draco_set_compiler_flags_for_sources: SOURCES and " + "FLAGS required.") + endif() + + set_source_files_properties(${compiler_SOURCES} PROPERTIES COMPILE_FLAGS + ${compiler_FLAGS}) + + if(DRACO_VERBOSE GREATER 1) + foreach(source ${compiler_SOURCES}) + foreach(flag ${compiler_FLAGS}) + message("draco_set_compiler_flags_for_sources: source:${source} " + "flag:${flag}") + endforeach() + endforeach() + endif() +endmacro() + +# Tests compiler flags stored in list(s) specified by FLAG_LIST_VAR_NAMES, adds +# flags to $DRACO_CXX_FLAGS when tests pass. Terminates configuration if +# FLAG_REQUIRED is specified and any flag check fails. +# +# ~~~ +# draco_test_cxx_flag(> +# [FLAG_REQUIRED]) +# ~~~ +macro(draco_test_cxx_flag) + unset(cxx_test_FLAG_LIST_VAR_NAMES) + unset(cxx_test_FLAG_REQUIRED) + unset(single_value_args) + set(optional_args FLAG_REQUIRED) + set(multi_value_args FLAG_LIST_VAR_NAMES) + cmake_parse_arguments(cxx_test "${optional_args}" "${single_value_args}" + "${multi_value_args}" ${ARGN}) + + if(NOT cxx_test_FLAG_LIST_VAR_NAMES) + draco_die("draco_test_cxx_flag: FLAG_LIST_VAR_NAMES required") + endif() + + unset(cxx_flags) + foreach(list_var ${cxx_test_FLAG_LIST_VAR_NAMES}) + if(DRACO_VERBOSE) + message("draco_test_cxx_flag: adding ${list_var} to cxx_flags") + endif() + list(APPEND cxx_flags ${${list_var}}) + endforeach() + + if(DRACO_VERBOSE) + message("CXX test: all flags: ${cxx_flags}") + endif() + + unset(all_cxx_flags) + list(APPEND all_cxx_flags ${DRACO_CXX_FLAGS} ${cxx_flags}) + + # Turn off output from check_cxx_source_compiles. Print status directly + # instead since the logging messages from check_cxx_source_compiles can be + # quite confusing. + set(CMAKE_REQUIRED_QUIET TRUE) + + # Run the actual compile test. + unset(draco_all_cxx_flags_pass CACHE) + message("--- Running combined CXX flags test, flags: ${all_cxx_flags}") + + # check_cxx_compiler_flag() requires that the flags are a string. When flags + # are passed as a list it will remove the list separators, and attempt to run + # a compile command using list entries concatenated together as a single + # argument. Avoid the problem by forcing the argument to be a string. + draco_set_and_stringify(SOURCE_VARS all_cxx_flags DEST all_cxx_flags_string) + check_cxx_compiler_flag("${all_cxx_flags_string}" draco_all_cxx_flags_pass) + + if(cxx_test_FLAG_REQUIRED AND NOT draco_all_cxx_flags_pass) + draco_die("Flag test failed for required flag(s): " + "${all_cxx_flags} and FLAG_REQUIRED specified.") + endif() + + if(draco_all_cxx_flags_pass) + # Test passed: update the global flag list used by the draco target creation + # wrappers. + set(DRACO_CXX_FLAGS ${cxx_flags}) + list(REMOVE_DUPLICATES DRACO_CXX_FLAGS) + + if(DRACO_VERBOSE) + message("DRACO_CXX_FLAGS=${DRACO_CXX_FLAGS}") + endif() + + message("--- Passed combined CXX flags test") + else() + message("--- Failed combined CXX flags test, testing flags individually.") + + if(cxx_flags) + message("--- Testing flags from $cxx_flags: " "${cxx_flags}") + foreach(cxx_flag ${cxx_flags}) + # Since 3.17.0 check_cxx_compiler_flag() sets a normal variable at + # parent scope while check_cxx_source_compiles() continues to set an + # internal cache variable, so we unset both to avoid the failure / + # success state persisting between checks. This has been fixed in newer + # CMake releases, but 3.17 is pretty common: we will need this to avoid + # weird build breakages while the fix propagates. + unset(cxx_flag_test_passed) + unset(cxx_flag_test_passed CACHE) + message("--- Testing flag: ${cxx_flag}") + check_cxx_compiler_flag("${cxx_flag}" cxx_flag_test_passed) + + if(cxx_flag_test_passed) + message("--- Passed test for ${cxx_flag}") + else() + list(REMOVE_ITEM cxx_flags ${cxx_flag}) + message("--- Failed test for ${cxx_flag}, flag removed.") + endif() + endforeach() + + set(DRACO_CXX_FLAGS ${cxx_flags}) + endif() + endif() + + if(DRACO_CXX_FLAGS) + list(REMOVE_DUPLICATES DRACO_CXX_FLAGS) + endif() +endmacro() + +# Tests executable linker flags stored in list specified by FLAG_LIST_VAR_NAME, +# adds flags to $DRACO_EXE_LINKER_FLAGS when test passes. Terminates +# configuration when flag check fails. draco_set_cxx_flags() must be called +# before calling this macro because it assumes $DRACO_CXX_FLAGS contains only +# valid CXX flags. +# +# draco_test_exe_linker_flag() +macro(draco_test_exe_linker_flag) + unset(link_FLAG_LIST_VAR_NAME) + unset(optional_args) + unset(multi_value_args) + set(single_value_args FLAG_LIST_VAR_NAME) + cmake_parse_arguments(link "${optional_args}" "${single_value_args}" + "${multi_value_args}" ${ARGN}) + + if(NOT link_FLAG_LIST_VAR_NAME) + draco_die("draco_test_link_flag: FLAG_LIST_VAR_NAME required") + endif() + + draco_set_and_stringify(DEST linker_flags SOURCE_VARS + ${link_FLAG_LIST_VAR_NAME}) + + if(DRACO_VERBOSE) + message("EXE LINKER test: all flags: ${linker_flags}") + endif() + + # Tests of $DRACO_CXX_FLAGS have already passed. Include them with the linker + # test. + draco_set_and_stringify(DEST CMAKE_REQUIRED_FLAGS SOURCE_VARS DRACO_CXX_FLAGS) + + # Cache the global exe linker flags. + if(CMAKE_EXE_LINKER_FLAGS) + set(cached_CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}) + draco_set_and_stringify(DEST CMAKE_EXE_LINKER_FLAGS SOURCE ${linker_flags}) + endif() + + draco_set_and_stringify(DEST CMAKE_EXE_LINKER_FLAGS SOURCE ${linker_flags} + ${CMAKE_EXE_LINKER_FLAGS}) + + # Turn off output from check_cxx_source_compiles. Print status directly + # instead since the logging messages from check_cxx_source_compiles can be + # quite confusing. + set(CMAKE_REQUIRED_QUIET TRUE) + + message("--- Running EXE LINKER test for flags: ${linker_flags}") + + unset(linker_flag_test_passed CACHE) + set(draco_cxx_main "\nint main() { return 0; }") + check_cxx_source_compiles("${draco_cxx_main}" linker_flag_test_passed) + + if(NOT linker_flag_test_passed) + draco_die("EXE LINKER test failed.") + endif() + + message("--- Passed EXE LINKER flag test.") + + # Restore cached global exe linker flags. + if(cached_CMAKE_EXE_LINKER_FLAGS) + set(CMAKE_EXE_LINKER_FLAGS ${cached_CMAKE_EXE_LINKER_FLAGS}) + else() + unset(CMAKE_EXE_LINKER_FLAGS) + endif() + + list(APPEND DRACO_EXE_LINKER_FLAGS ${${link_FLAG_LIST_VAR_NAME}}) + list(REMOVE_DUPLICATES DRACO_EXE_LINKER_FLAGS) +endmacro() + +# Runs the draco compiler tests. This macro builds up the list of list var(s) +# that is passed to draco_test_cxx_flag(). +# +# Note: draco_set_build_definitions() must be called before this macro. +macro(draco_set_cxx_flags) + unset(cxx_flag_lists) + + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") + list(APPEND cxx_flag_lists draco_base_cxx_flags) + endif() + + # Append clang flags after the base set to allow -Wno* overrides to take + # effect. Some of the base flags may enable a large set of warnings, e.g., + # -Wall. + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + list(APPEND cxx_flag_lists draco_clang_cxx_flags) + endif() + + if(MSVC) + list(APPEND cxx_flag_lists draco_msvc_cxx_flags) + endif() + + draco_set_and_stringify(DEST cxx_flags SOURCE_VARS ${cxx_flag_lists}) + if(DRACO_VERBOSE) + message("draco_set_cxx_flags: internal CXX flags: ${cxx_flags}") + endif() + + if(DRACO_CXX_FLAGS) + list(APPEND cxx_flag_lists DRACO_CXX_FLAGS) + if(DRACO_VERBOSE) + message("draco_set_cxx_flags: user CXX flags: ${DRACO_CXX_FLAGS}") + endif() + endif() + + draco_set_and_stringify(DEST cxx_flags SOURCE_VARS ${cxx_flag_lists}) + + if(cxx_flags) + draco_test_cxx_flag(FLAG_LIST_VAR_NAMES ${cxx_flag_lists}) + endif() +endmacro() + +# Collects Draco built-in and user-specified linker flags and tests them. Halts +# configuration and reports the error when any flags cause the build to fail. +# +# Note: draco_test_exe_linker_flag() does the real work of setting the flags and +# running the test compile commands. +macro(draco_set_exe_linker_flags) + unset(linker_flag_lists) + + if(DRACO_VERBOSE) + message("draco_set_exe_linker_flags: " + "draco_base_exe_linker_flags=${draco_base_exe_linker_flags}") + endif() + + if(draco_base_exe_linker_flags) + list(APPEND linker_flag_lists draco_base_exe_linker_flags) + endif() + + if(linker_flag_lists) + unset(test_linker_flags) + + if(DRACO_VERBOSE) + message("draco_set_exe_linker_flags: " + "linker_flag_lists=${linker_flag_lists}") + endif() + + draco_set_and_stringify(DEST test_linker_flags SOURCE_VARS + ${linker_flag_lists}) + draco_test_exe_linker_flag(FLAG_LIST_VAR_NAME test_linker_flags) + endif() +endmacro() diff --git a/third-party/draco/cmake/draco_helpers.cmake b/third-party/draco/cmake/draco_helpers.cmake new file mode 100644 index 0000000000..69e24c5bea --- /dev/null +++ b/third-party/draco/cmake/draco_helpers.cmake @@ -0,0 +1,124 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_HELPERS_CMAKE_) + return() +endif() # DRACO_CMAKE_DRACO_HELPERS_CMAKE_ +set(DRACO_CMAKE_DRACO_HELPERS_CMAKE_ 1) + +# Kills build generation using message(FATAL_ERROR) and outputs all data passed +# to the console via use of $ARGN. +macro(draco_die) + message(FATAL_ERROR ${ARGN}) +endmacro() + +# Converts semi-colon delimited list variable(s) to string. Output is written to +# variable supplied via the DEST parameter. Input is from an expanded variable +# referenced by SOURCE and/or variable(s) referenced by SOURCE_VARS. +macro(draco_set_and_stringify) + set(optional_args) + set(single_value_args DEST SOURCE_VAR) + set(multi_value_args SOURCE SOURCE_VARS) + cmake_parse_arguments(sas "${optional_args}" "${single_value_args}" + "${multi_value_args}" ${ARGN}) + + if(NOT sas_DEST OR NOT (sas_SOURCE OR sas_SOURCE_VARS)) + draco_die("draco_set_and_stringify: DEST and at least one of SOURCE " + "SOURCE_VARS required.") + endif() + + unset(${sas_DEST}) + + if(sas_SOURCE) + # $sas_SOURCE is one or more expanded variables, just copy the values to + # $sas_DEST. + set(${sas_DEST} "${sas_SOURCE}") + endif() + + if(sas_SOURCE_VARS) + # $sas_SOURCE_VARS is one or more variable names. Each iteration expands a + # variable and appends it to $sas_DEST. + foreach(source_var ${sas_SOURCE_VARS}) + set(${sas_DEST} "${${sas_DEST}} ${${source_var}}") + endforeach() + + # Because $sas_DEST can be empty when entering this scope leading whitespace + # can be introduced to $sas_DEST on the first iteration of the above loop. + # Remove it: + string(STRIP "${${sas_DEST}}" ${sas_DEST}) + endif() + + # Lists in CMake are simply semicolon delimited strings, so stringification is + # just a find and replace of the semicolon. + string(REPLACE ";" " " ${sas_DEST} "${${sas_DEST}}") + + if(DRACO_VERBOSE GREATER 1) + message("draco_set_and_stringify: ${sas_DEST}=${${sas_DEST}}") + endif() +endmacro() + +# Creates a dummy source file in $DRACO_GENERATED_SOURCES_DIRECTORY and adds it +# to the specified target. Optionally adds its path to a list variable. +# +# draco_create_dummy_source_file( BASENAME > +# [LISTVAR ]) +macro(draco_create_dummy_source_file) + set(optional_args) + set(single_value_args TARGET BASENAME LISTVAR) + set(multi_value_args) + cmake_parse_arguments(cdsf "${optional_args}" "${single_value_args}" + "${multi_value_args}" ${ARGN}) + + if(NOT cdsf_TARGET OR NOT cdsf_BASENAME) + draco_die("draco_create_dummy_source_file: TARGET and BASENAME required.") + endif() + + if(NOT DRACO_GENERATED_SOURCES_DIRECTORY) + set(DRACO_GENERATED_SOURCES_DIRECTORY "${draco_build}/gen_src") + endif() + + set(dummy_source_dir "${DRACO_GENERATED_SOURCES_DIRECTORY}") + set(dummy_source_file + "${dummy_source_dir}/draco_${cdsf_TARGET}_${cdsf_BASENAME}.cc") + set(dummy_source_code + "// Generated file. DO NOT EDIT!\n" + "// C++ source file created for target ${cdsf_TARGET}.\n" + "void draco_${cdsf_TARGET}_${cdsf_BASENAME}_dummy_function(void)\;\n" + "void draco_${cdsf_TARGET}_${cdsf_BASENAME}_dummy_function(void) {}\n") + file(WRITE "${dummy_source_file}" ${dummy_source_code}) + + target_sources(${cdsf_TARGET} PRIVATE ${dummy_source_file}) + + if(cdsf_LISTVAR) + list(APPEND ${cdsf_LISTVAR} "${dummy_source_file}") + endif() +endmacro() + +# Loads the version string from $draco_source/draco/version.h and sets +# $DRACO_VERSION. +macro(draco_load_version_info) + file(STRINGS "${draco_src_root}/core/draco_version.h" version_file_strings) + foreach(str ${version_file_strings}) + if(str MATCHES "char kDracoVersion") + string(FIND "${str}" "\"" open_quote_pos) + string(FIND "${str}" ";" semicolon_pos) + math(EXPR open_quote_pos "${open_quote_pos} + 1") + math(EXPR close_quote_pos "${semicolon_pos} - 1") + math(EXPR version_string_length "${close_quote_pos} - ${open_quote_pos}") + string(SUBSTRING "${str}" ${open_quote_pos} ${version_string_length} + DRACO_VERSION) + break() + endif() + endforeach() +endmacro() diff --git a/third-party/draco/cmake/draco_install.cmake b/third-party/draco/cmake/draco_install.cmake new file mode 100644 index 0000000000..7fa04d05e0 --- /dev/null +++ b/third-party/draco/cmake/draco_install.cmake @@ -0,0 +1,135 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_INSTALL_CMAKE_) + return() +endif() # DRACO_CMAKE_DRACO_INSTALL_CMAKE_ +set(DRACO_CMAKE_DRACO_INSTALL_CMAKE_ 1) + +include(CMakePackageConfigHelpers) +include(GNUInstallDirs) + +# Sets up the draco install targets. Must be called after the static library +# target is created. +macro(draco_setup_install_target) + if(DRACO_INSTALL) + set(bin_path "${CMAKE_INSTALL_BINDIR}") + set(data_path "${CMAKE_INSTALL_DATAROOTDIR}") + set(includes_path "${CMAKE_INSTALL_INCLUDEDIR}") + set(libs_path "${CMAKE_INSTALL_LIBDIR}") + + foreach(file ${draco_sources}) + if(file MATCHES "h$") + list(APPEND draco_api_includes ${file}) + endif() + endforeach() + + list(REMOVE_DUPLICATES draco_api_includes) + + # Strip $draco_src_root from the file paths: we need to install relative to + # $include_directory. + # list(TRANSFORM draco_api_includes REPLACE "${draco_src_root}/" "") + macro(LIST_REPLACE LIST INDEX NEWVALUE) + list(INSERT ${LIST} ${INDEX} ${NEWVALUE}) + MATH(EXPR __INDEX "${INDEX} + 1") + list (REMOVE_AT ${LIST} ${__INDEX}) + endmacro(LIST_REPLACE) + list(LENGTH draco_api_includes list_count) + math(EXPR list_max_index ${list_count}-1) + foreach(i RANGE ${list_max_index}) + list(GET draco_api_includes ${i} x) + string(REPLACE "${draco_src_root}/" "" new ${x}) + LIST_REPLACE(draco_api_includes ${i} ${new}) + endforeach(i) + + foreach(draco_api_include ${draco_api_includes}) + get_filename_component(file_directory ${draco_api_include} DIRECTORY) + set(target_directory "${includes_path}/draco/${file_directory}") + install(FILES ${draco_src_root}/${draco_api_include} + DESTINATION "${target_directory}") + endforeach() + + install(FILES "${draco_build}/draco/draco_features.h" + DESTINATION "${includes_path}/draco/") + + install(TARGETS draco_decoder DESTINATION "${bin_path}") + install(TARGETS draco_encoder DESTINATION "${bin_path}") + + if(DRACO_TRANSCODER_SUPPORTED) + install(TARGETS draco_transcoder DESTINATION "${bin_path}") + endif() + + if(WIN32) + install( + TARGETS draco + EXPORT dracoExport + RUNTIME DESTINATION "${bin_path}" + ARCHIVE DESTINATION "${libs_path}" + LIBRARY DESTINATION "${libs_path}") + else() + install( + TARGETS draco_static + EXPORT dracoExport + DESTINATION "${libs_path}") + + if(BUILD_SHARED_LIBS) + install( + TARGETS draco_shared + EXPORT dracoExport + RUNTIME DESTINATION "${bin_path}" + ARCHIVE DESTINATION "${libs_path}" + LIBRARY DESTINATION "${libs_path}") + endif() + endif() + + if(DRACO_UNITY_PLUGIN) + install(TARGETS dracodec_unity DESTINATION "${libs_path}") + endif() + + if(DRACO_MAYA_PLUGIN) + install(TARGETS draco_maya_wrapper DESTINATION "${libs_path}") + endif() + + # pkg-config: draco.pc + configure_file("${draco_root}/cmake/draco.pc.template" + "${draco_build}/draco.pc" @ONLY NEWLINE_STYLE UNIX) + install(FILES "${draco_build}/draco.pc" DESTINATION "${libs_path}/pkgconfig") + + # CMake config: draco-config.cmake + configure_package_config_file( + "${draco_root}/cmake/draco-config.cmake.template" + "${draco_build}/draco-config.cmake" + INSTALL_DESTINATION "${data_path}/cmake/draco") + + write_basic_package_version_file( + "${draco_build}/draco-config-version.cmake" + VERSION ${DRACO_VERSION} + COMPATIBILITY AnyNewerVersion) + + export( + EXPORT dracoExport + NAMESPACE draco:: + FILE "${draco_build}/draco-targets.cmake") + + install( + EXPORT dracoExport + NAMESPACE draco:: + FILE draco-targets.cmake + DESTINATION "${data_path}/cmake/draco") + + install(FILES "${draco_build}/draco-config.cmake" + "${draco_build}/draco-config-version.cmake" + DESTINATION "${data_path}/cmake/draco") + endif(DRACO_INSTALL) +endmacro() diff --git a/third-party/draco/cmake/draco_intrinsics.cmake b/third-party/draco/cmake/draco_intrinsics.cmake new file mode 100644 index 0000000000..178df97a69 --- /dev/null +++ b/third-party/draco/cmake/draco_intrinsics.cmake @@ -0,0 +1,106 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_INTRINSICS_CMAKE_) + return() +endif() # DRACO_CMAKE_DRACO_INTRINSICS_CMAKE_ +set(DRACO_CMAKE_DRACO_INTRINSICS_CMAKE_ 1) + +# Returns the compiler flag for the SIMD intrinsics suffix specified by the +# SUFFIX argument via the variable specified by the VARIABLE argument: +# draco_get_intrinsics_flag_for_suffix(SUFFIX VARIABLE ) +macro(draco_get_intrinsics_flag_for_suffix) + unset(intrinsics_SUFFIX) + unset(intrinsics_VARIABLE) + unset(optional_args) + unset(multi_value_args) + set(single_value_args SUFFIX VARIABLE) + cmake_parse_arguments(intrinsics "${optional_args}" "${single_value_args}" + "${multi_value_args}" ${ARGN}) + + if(NOT (intrinsics_SUFFIX AND intrinsics_VARIABLE)) + message(FATAL_ERROR "draco_get_intrinsics_flag_for_suffix: SUFFIX and " + "VARIABLE required.") + endif() + + if(intrinsics_SUFFIX MATCHES "neon") + if(NOT MSVC) + set(${intrinsics_VARIABLE} "${DRACO_NEON_INTRINSICS_FLAG}") + endif() + elseif(intrinsics_SUFFIX MATCHES "sse4") + if(NOT MSVC) + set(${intrinsics_VARIABLE} "-msse4.1") + endif() + else() + message(FATAL_ERROR "draco_get_intrinsics_flag_for_suffix: Unknown " + "instrinics suffix: ${intrinsics_SUFFIX}") + endif() + + if(DRACO_VERBOSE GREATER 1) + message("draco_get_intrinsics_flag_for_suffix: " + "suffix:${intrinsics_SUFFIX} flag:${${intrinsics_VARIABLE}}") + endif() +endmacro() + +# Processes source files specified by SOURCES and adds intrinsics flags as +# necessary: draco_process_intrinsics_sources(SOURCES ) +# +# Detects requirement for intrinsics flags using source file name suffix. +# Currently supports only SSE4.1. +macro(draco_process_intrinsics_sources) + unset(arg_TARGET) + unset(arg_SOURCES) + unset(optional_args) + set(single_value_args TARGET) + set(multi_value_args SOURCES) + cmake_parse_arguments(arg "${optional_args}" "${single_value_args}" + "${multi_value_args}" ${ARGN}) + if(NOT (arg_TARGET AND arg_SOURCES)) + message(FATAL_ERROR "draco_process_intrinsics_sources: TARGET and " + "SOURCES required.") + endif() + + if(DRACO_ENABLE_SSE4_1 AND draco_have_sse4) + unset(sse4_sources) + list(APPEND sse4_sources ${arg_SOURCES}) + + list(FILTER sse4_sources INCLUDE REGEX "${draco_sse4_source_file_suffix}$") + + if(sse4_sources) + unset(sse4_flags) + draco_get_intrinsics_flag_for_suffix( + SUFFIX ${draco_sse4_source_file_suffix} VARIABLE sse4_flags) + if(sse4_flags) + draco_set_compiler_flags_for_sources(SOURCES ${sse4_sources} FLAGS + ${sse4_flags}) + endif() + endif() + endif() + + if(DRACO_ENABLE_NEON AND draco_have_neon) + unset(neon_sources) + list(APPEND neon_sources ${arg_SOURCES}) + list(FILTER neon_sources INCLUDE REGEX "${draco_neon_source_file_suffix}$") + + if(neon_sources AND DRACO_NEON_INTRINSICS_FLAG) + unset(neon_flags) + draco_get_intrinsics_flag_for_suffix( + SUFFIX ${draco_neon_source_file_suffix} VARIABLE neon_flags) + if(neon_flags) + draco_set_compiler_flags_for_sources(SOURCES ${neon_sources} FLAGS + ${neon_flags}) + endif() + endif() + endif() +endmacro() diff --git a/third-party/draco/cmake/draco_options.cmake b/third-party/draco/cmake/draco_options.cmake new file mode 100644 index 0000000000..e89c6a8fa2 --- /dev/null +++ b/third-party/draco/cmake/draco_options.cmake @@ -0,0 +1,358 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_OPTIONS_CMAKE_) + return() +endif() # DRACO_CMAKE_DRACO_OPTIONS_CMAKE_ +set(DRACO_CMAKE_DRACO_OPTIONS_CMAKE_) + +set(draco_features_file_name "${draco_src_root}/draco_features.h") +set(draco_features_list) + +# Simple wrapper for CMake's builtin option command that tracks draco's build +# options in the list variable $draco_options. +macro(draco_option) + unset(option_NAME) + unset(option_HELPSTRING) + unset(option_VALUE) + unset(optional_args) + unset(multi_value_args) + set(single_value_args NAME HELPSTRING VALUE) + cmake_parse_arguments(option "${optional_args}" "${single_value_args}" + "${multi_value_args}" ${ARGN}) + + if(NOT + (option_NAME + AND option_HELPSTRING + AND DEFINED option_VALUE)) + message(FATAL_ERROR "draco_option: NAME HELPSTRING and VALUE required.") + endif() + + option(${option_NAME} ${option_HELPSTRING} ${option_VALUE}) + + if(DRACO_VERBOSE GREATER 2) + message( + "--------- draco_option ---------\n" + "option_NAME=${option_NAME}\n" + "option_HELPSTRING=${option_HELPSTRING}\n" + "option_VALUE=${option_VALUE}\n" + "------------------------------------------\n") + endif() + + list(APPEND draco_options ${option_NAME}) + list(REMOVE_DUPLICATES draco_options) +endmacro() + +# Dumps the $draco_options list via CMake message command. +macro(draco_dump_options) + foreach(option_name ${draco_options}) + message("${option_name}: ${${option_name}}") + endforeach() +endmacro() + +# Set default options. +macro(draco_set_default_options) + draco_option( + NAME DRACO_FAST + HELPSTRING "Try to build faster libs." + VALUE OFF) + draco_option( + NAME DRACO_JS_GLUE + HELPSTRING "Enable JS Glue and JS targets when using Emscripten." + VALUE ON) + draco_option( + NAME DRACO_IE_COMPATIBLE + HELPSTRING "Enable support for older IE builds when using Emscripten." + VALUE OFF) + draco_option( + NAME DRACO_MESH_COMPRESSION + HELPSTRING "Enable mesh compression." + VALUE ON) + draco_option( + NAME DRACO_POINT_CLOUD_COMPRESSION + HELPSTRING "Enable point cloud compression." + VALUE ON) + draco_option( + NAME DRACO_PREDICTIVE_EDGEBREAKER + HELPSTRING "Enable predictive edgebreaker." + VALUE ON) + draco_option( + NAME DRACO_STANDARD_EDGEBREAKER + HELPSTRING "Enable stand edgebreaker." + VALUE ON) + draco_option( + NAME DRACO_BACKWARDS_COMPATIBILITY + HELPSTRING "Enable backwards compatibility." + VALUE ON) + draco_option( + NAME DRACO_DECODER_ATTRIBUTE_DEDUPLICATION + HELPSTRING "Enable attribute deduping." + VALUE OFF) + draco_option( + NAME DRACO_TESTS + HELPSTRING "Enables tests." + VALUE OFF) + draco_option( + NAME DRACO_WASM + HELPSTRING "Enables WASM support." + VALUE OFF) + draco_option( + NAME DRACO_UNITY_PLUGIN + HELPSTRING "Build plugin library for Unity." + VALUE OFF) + draco_option( + NAME DRACO_ANIMATION_ENCODING + HELPSTRING "Enable animation." + VALUE OFF) + draco_option( + NAME DRACO_GLTF_BITSTREAM + HELPSTRING "Draco GLTF extension bitstream specified features only." + VALUE OFF) + draco_option( + NAME DRACO_MAYA_PLUGIN + HELPSTRING "Build plugin library for Maya." + VALUE OFF) + draco_option( + NAME DRACO_TRANSCODER_SUPPORTED + HELPSTRING "Enable the Draco transcoder." + VALUE OFF) + draco_option( + NAME DRACO_DEBUG_COMPILER_WARNINGS + HELPSTRING "Turn on more warnings." + VALUE OFF) + draco_option( + NAME DRACO_INSTALL + HELPSTRING "Enable installation." + VALUE ON) + draco_check_deprecated_options() +endmacro() + +# Warns when a deprecated option is used and sets the option that replaced it. +macro(draco_handle_deprecated_option) + unset(option_OLDNAME) + unset(option_NEWNAME) + unset(optional_args) + unset(multi_value_args) + set(single_value_args OLDNAME NEWNAME) + cmake_parse_arguments(option "${optional_args}" "${single_value_args}" + "${multi_value_args}" ${ARGN}) + + if("${${option_OLDNAME}}") + message(WARNING "${option_OLDNAME} is deprecated. Use ${option_NEWNAME}.") + set(${option_NEWNAME} ${${option_OLDNAME}}) + endif() +endmacro() + +# Checks for use of deprecated options. +macro(draco_check_deprecated_options) + draco_handle_deprecated_option(OLDNAME ENABLE_EXTRA_SPEED NEWNAME DRACO_FAST) + draco_handle_deprecated_option(OLDNAME ENABLE_JS_GLUE NEWNAME DRACO_JS_GLUE) + draco_handle_deprecated_option(OLDNAME ENABLE_MESH_COMPRESSION NEWNAME + DRACO_MESH_COMPRESSION) + draco_handle_deprecated_option(OLDNAME ENABLE_POINT_CLOUD_COMPRESSION NEWNAME + DRACO_POINT_CLOUD_COMPRESSION) + draco_handle_deprecated_option(OLDNAME ENABLE_PREDICTIVE_EDGEBREAKER NEWNAME + DRACO_PREDICTIVE_EDGEBREAKER) + draco_handle_deprecated_option(OLDNAME ENABLE_STANDARD_EDGEBREAKER NEWNAME + DRACO_STANDARD_EDGEBREAKER) + draco_handle_deprecated_option(OLDNAME ENABLE_BACKWARDS_COMPATIBILITY NEWNAME + DRACO_BACKWARDS_COMPATIBILITY) + draco_handle_deprecated_option(OLDNAME ENABLE_DECODER_ATTRIBUTE_DEDUPLICATION + NEWNAME DRACO_DECODER_ATTRIBUTE_DEDUPLICATION) + draco_handle_deprecated_option(OLDNAME ENABLE_TESTS NEWNAME DRACO_TESTS) + draco_handle_deprecated_option(OLDNAME ENABLE_WASM NEWNAME DRACO_WASM) + draco_handle_deprecated_option(OLDNAME BUILD_UNITY_PLUGIN NEWNAME + DRACO_UNITY_PLUGIN) + draco_handle_deprecated_option(OLDNAME BUILD_ANIMATION_ENCODING NEWNAME + DRACO_ANIMATION_ENCODING) + draco_handle_deprecated_option(OLDNAME BUILD_FOR_GLTF NEWNAME DRACO_GLTF) + draco_handle_deprecated_option(OLDNAME BUILD_MAYA_PLUGIN NEWNAME + DRACO_MAYA_PLUGIN) + draco_handle_deprecated_option(OLDNAME BUILD_USD_PLUGIN NEWNAME + BUILD_SHARED_LIBS) + draco_handle_deprecated_option(OLDNAME DRACO_GLTF NEWNAME + DRACO_GLTF_BITSTREAM) + +endmacro() + +# Macro for setting Draco features based on user configuration. Features enabled +# by this macro are Draco global. +macro(draco_set_optional_features) + if(DRACO_GLTF_BITSTREAM) + # Enable only the features included in the Draco GLTF bitstream spec. + draco_enable_feature(FEATURE "DRACO_MESH_COMPRESSION_SUPPORTED") + draco_enable_feature(FEATURE "DRACO_NORMAL_ENCODING_SUPPORTED") + draco_enable_feature(FEATURE "DRACO_STANDARD_EDGEBREAKER_SUPPORTED") + else() + if(DRACO_POINT_CLOUD_COMPRESSION) + draco_enable_feature(FEATURE "DRACO_POINT_CLOUD_COMPRESSION_SUPPORTED") + endif() + if(DRACO_MESH_COMPRESSION) + draco_enable_feature(FEATURE "DRACO_MESH_COMPRESSION_SUPPORTED") + draco_enable_feature(FEATURE "DRACO_NORMAL_ENCODING_SUPPORTED") + + if(DRACO_STANDARD_EDGEBREAKER) + draco_enable_feature(FEATURE "DRACO_STANDARD_EDGEBREAKER_SUPPORTED") + endif() + if(DRACO_PREDICTIVE_EDGEBREAKER) + draco_enable_feature(FEATURE "DRACO_PREDICTIVE_EDGEBREAKER_SUPPORTED") + endif() + endif() + + if(DRACO_BACKWARDS_COMPATIBILITY) + draco_enable_feature(FEATURE "DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED") + endif() + + + if(NOT EMSCRIPTEN) + # For now, enable deduplication for both encoder and decoder. + # TODO(ostava): Support for disabling attribute deduplication for the C++ + # decoder is planned in future releases. + draco_enable_feature(FEATURE + DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED) + draco_enable_feature(FEATURE + DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED) + endif() + endif() + + if(DRACO_UNITY_PLUGIN) + draco_enable_feature(FEATURE "DRACO_UNITY_PLUGIN") + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + endif() + + if(DRACO_MAYA_PLUGIN) + draco_enable_feature(FEATURE "DRACO_MAYA_PLUGIN") + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + endif() + + if(DRACO_TRANSCODER_SUPPORTED) + draco_enable_feature(FEATURE "DRACO_TRANSCODER_SUPPORTED") + endif() + + +endmacro() + +# Macro that handles tracking of Draco preprocessor symbols for the purpose of +# producing draco_features.h. +# +# ~~~ +# draco_enable_feature(FEATURE [TARGETS ]) +# ~~~ +# +# FEATURE is required. It should be a Draco preprocessor symbol. TARGETS is +# optional. It can be one or more draco targets. +# +# When the TARGETS argument is not present the preproc symbol is added to +# draco_features.h. When it is draco_features.h is unchanged, and +# target_compile_options() is called for each target specified. +macro(draco_enable_feature) + set(def_flags) + set(def_single_arg_opts FEATURE) + set(def_multi_arg_opts TARGETS) + cmake_parse_arguments(DEF "${def_flags}" "${def_single_arg_opts}" + "${def_multi_arg_opts}" ${ARGN}) + if("${DEF_FEATURE}" STREQUAL "") + message(FATAL_ERROR "Empty FEATURE passed to draco_enable_feature().") + endif() + + # Do nothing/return early if $DEF_FEATURE is already in the list. + list(FIND draco_features_list ${DEF_FEATURE} df_index) + if(NOT df_index EQUAL -1) + return() + endif() + + list(LENGTH DEF_TARGETS df_targets_list_length) + if(${df_targets_list_length} EQUAL 0) + list(APPEND draco_features_list ${DEF_FEATURE}) + else() + foreach(target ${DEF_TARGETS}) + target_compile_definitions(${target} PRIVATE ${DEF_FEATURE}) + endforeach() + endif() +endmacro() + +# Function for generating draco_features.h. +function(draco_generate_features_h) + file(WRITE "${draco_features_file_name}.new" + "// GENERATED FILE -- DO NOT EDIT\n\n" "#ifndef DRACO_FEATURES_H_\n" + "#define DRACO_FEATURES_H_\n\n") + + foreach(feature ${draco_features_list}) + file(APPEND "${draco_features_file_name}.new" "#define ${feature}\n") + endforeach() + + if(WIN32) + if(NOT DRACO_DEBUG_COMPILER_WARNINGS) + file(APPEND "${draco_features_file_name}.new" + "// Enable DRACO_DEBUG_COMPILER_WARNINGS at CMake generation \n" + "// time to remove these pragmas.\n") + + # warning C4018: '': signed/unsigned mismatch. + file(APPEND "${draco_features_file_name}.new" + "#pragma warning(disable:4018)\n") + + # warning C4146: unary minus operator applied to unsigned type, result + # still unsigned + file(APPEND "${draco_features_file_name}.new" + "#pragma warning(disable:4146)\n") + + # warning C4244: 'return': conversion from '' to '', possible + # loss of data. + file(APPEND "${draco_features_file_name}.new" + "#pragma warning(disable:4244)\n") + + # warning C4267: 'initializing' conversion from '' to '', + # possible loss of data. + file(APPEND "${draco_features_file_name}.new" + "#pragma warning(disable:4267)\n") + + # warning C4305: 'context' : truncation from 'type1' to 'type2'. + file(APPEND "${draco_features_file_name}.new" + "#pragma warning(disable:4305)\n") + + # warning C4661: 'identifier' : no suitable definition provided for + # explicit template instantiation request. + file(APPEND "${draco_features_file_name}.new" + "#pragma warning(disable:4661)\n") + + # warning C4800: Implicit conversion from 'type' to bool. Possible + # information loss. + # Also, in older MSVC releases: + # warning C4800: 'type' : forcing value to bool 'true' or 'false' + # (performance warning). + file(APPEND "${draco_features_file_name}.new" + "#pragma warning(disable:4800)\n") + + # warning C4804: '': unsafe use of type '' in operation. + file(APPEND "${draco_features_file_name}.new" + "#pragma warning(disable:4804)\n") + endif() + endif() + + file(APPEND "${draco_features_file_name}.new" + "\n#endif // DRACO_FEATURES_H_\n") + + # Will replace ${draco_features_file_name} only if the file content has + # changed. This prevents forced Draco rebuilds after CMake runs. + configure_file("${draco_features_file_name}.new" + "${draco_features_file_name}") + file(REMOVE "${draco_features_file_name}.new") +endfunction() + +# Sets default options for the build and processes user controlled options to +# compute enabled features. +macro(draco_setup_options) + draco_set_default_options() + draco_set_optional_features() +endmacro() diff --git a/third-party/draco/cmake/draco_sanitizer.cmake b/third-party/draco/cmake/draco_sanitizer.cmake new file mode 100644 index 0000000000..77d141481f --- /dev/null +++ b/third-party/draco/cmake/draco_sanitizer.cmake @@ -0,0 +1,48 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_SANITIZER_CMAKE_) + return() +endif() # DRACO_CMAKE_DRACO_SANITIZER_CMAKE_ +set(DRACO_CMAKE_DRACO_SANITIZER_CMAKE_ 1) + +# Handles the details of enabling sanitizers. +macro(draco_configure_sanitizer) + if(DRACO_SANITIZE + AND NOT EMSCRIPTEN + AND NOT MSVC) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + if(DRACO_SANITIZE MATCHES "cfi") + list(APPEND SAN_CXX_FLAGS "-flto" "-fno-sanitize-trap=cfi") + list(APPEND SAN_LINKER_FLAGS "-flto" "-fno-sanitize-trap=cfi" + "-fuse-ld=gold") + endif() + + if(${CMAKE_SIZEOF_VOID_P} EQUAL 4 AND DRACO_SANITIZE MATCHES + "integer|undefined") + list(APPEND SAN_LINKER_FLAGS "--rtlib=compiler-rt" "-lgcc_s") + endif() + endif() + + list(APPEND SAN_CXX_FLAGS "-fsanitize=${DRACO_SANITIZE}") + list(APPEND SAN_LINKER_FLAGS "-fsanitize=${DRACO_SANITIZE}") + + # Make sanitizer callstacks accurate. + list(APPEND SAN_CXX_FLAGS "-fno-omit-frame-pointer") + list(APPEND SAN_CXX_FLAGS "-fno-optimize-sibling-calls") + + draco_test_cxx_flag(FLAG_LIST_VAR_NAMES SAN_CXX_FLAGS FLAG_REQUIRED) + draco_test_exe_linker_flag(FLAG_LIST_VAR_NAME SAN_LINKER_FLAGS) + endif() +endmacro() diff --git a/third-party/draco/cmake/draco_targets.cmake b/third-party/draco/cmake/draco_targets.cmake new file mode 100644 index 0000000000..c8c79f5111 --- /dev/null +++ b/third-party/draco/cmake/draco_targets.cmake @@ -0,0 +1,400 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_TARGETS_CMAKE_) + return() +endif() # DRACO_CMAKE_DRACO_TARGETS_CMAKE_ +set(DRACO_CMAKE_DRACO_TARGETS_CMAKE_ 1) + +# Resets list variables used to track draco targets. +macro(draco_reset_target_lists) + unset(draco_targets) + unset(draco_exe_targets) + unset(draco_lib_targets) + unset(draco_objlib_targets) + unset(draco_module_targets) + unset(draco_sources) + unset(draco_test_targets) +endmacro() + +# Creates an executable target. The target name is passed as a parameter to the +# NAME argument, and the sources passed as a parameter to the SOURCES argument: +# draco_add_executable(NAME SOURCES [optional args]) +# +# Optional args: +# cmake-format: off +# - OUTPUT_NAME: Override output file basename. Target basename defaults to +# NAME. +# - TEST: Flag. Presence means treat executable as a test. +# - DEFINES: List of preprocessor macro definitions. +# - INCLUDES: list of include directories for the target. +# - COMPILE_FLAGS: list of compiler flags for the target. +# - LINK_FLAGS: List of linker flags for the target. +# - OBJLIB_DEPS: List of CMake object library target dependencies. +# - LIB_DEPS: List of CMake library dependencies. +# cmake-format: on +# +# Sources passed to this macro are added to $draco_test_sources when TEST is +# specified. Otherwise sources are added to $draco_sources. +# +# Targets passed to this macro are always added to the $draco_targets list. When +# TEST is specified targets are also added to the $draco_test_targets list. +# Otherwise targets are added to $draco_exe_targets. +macro(draco_add_executable) + unset(exe_TEST) + unset(exe_TEST_DEFINES_MAIN) + unset(exe_NAME) + unset(exe_OUTPUT_NAME) + unset(exe_SOURCES) + unset(exe_DEFINES) + unset(exe_INCLUDES) + unset(exe_COMPILE_FLAGS) + unset(exe_LINK_FLAGS) + unset(exe_OBJLIB_DEPS) + unset(exe_LIB_DEPS) + set(optional_args TEST) + set(single_value_args NAME OUTPUT_NAME) + set(multi_value_args + SOURCES + DEFINES + INCLUDES + COMPILE_FLAGS + LINK_FLAGS + OBJLIB_DEPS + LIB_DEPS) + + cmake_parse_arguments(exe "${optional_args}" "${single_value_args}" + "${multi_value_args}" ${ARGN}) + + if(DRACO_VERBOSE GREATER 1) + message( + "--------- draco_add_executable ---------\n" + "exe_TEST=${exe_TEST}\n" + "exe_TEST_DEFINES_MAIN=${exe_TEST_DEFINES_MAIN}\n" + "exe_NAME=${exe_NAME}\n" + "exe_OUTPUT_NAME=${exe_OUTPUT_NAME}\n" + "exe_SOURCES=${exe_SOURCES}\n" + "exe_DEFINES=${exe_DEFINES}\n" + "exe_INCLUDES=${exe_INCLUDES}\n" + "exe_COMPILE_FLAGS=${exe_COMPILE_FLAGS}\n" + "exe_LINK_FLAGS=${exe_LINK_FLAGS}\n" + "exe_OBJLIB_DEPS=${exe_OBJLIB_DEPS}\n" + "exe_LIB_DEPS=${exe_LIB_DEPS}\n" + "------------------------------------------\n") + endif() + + if(NOT (exe_NAME AND exe_SOURCES)) + message(FATAL_ERROR "draco_add_executable: NAME and SOURCES required.") + endif() + + list(APPEND draco_targets ${exe_NAME}) + if(exe_TEST) + list(APPEND draco_test_targets ${exe_NAME}) + list(APPEND draco_test_sources ${exe_SOURCES}) + else() + list(APPEND draco_exe_targets ${exe_NAME}) + list(APPEND draco_sources ${exe_SOURCES}) + endif() + + add_executable(${exe_NAME} ${exe_SOURCES}) + + target_compile_features(${exe_NAME} PUBLIC cxx_std_11) + + if(NOT EMSCRIPTEN) + set_target_properties(${exe_NAME} PROPERTIES VERSION ${DRACO_VERSION}) + endif() + + if(exe_OUTPUT_NAME) + set_target_properties(${exe_NAME} PROPERTIES OUTPUT_NAME ${exe_OUTPUT_NAME}) + endif() + + draco_process_intrinsics_sources(TARGET ${exe_NAME} SOURCES ${exe_SOURCES}) + + if(exe_DEFINES) + target_compile_definitions(${exe_NAME} PRIVATE ${exe_DEFINES}) + endif() + + if(exe_INCLUDES) + target_include_directories(${exe_NAME} PRIVATE ${exe_INCLUDES}) + endif() + + if(exe_COMPILE_FLAGS OR DRACO_CXX_FLAGS) + target_compile_options(${exe_NAME} PRIVATE ${exe_COMPILE_FLAGS} + ${DRACO_CXX_FLAGS}) + endif() + + if(exe_LINK_FLAGS OR DRACO_EXE_LINKER_FLAGS) + if(${CMAKE_VERSION} VERSION_LESS "3.13") + list(APPEND exe_LINK_FLAGS "${DRACO_EXE_LINKER_FLAGS}") + # LINK_FLAGS is managed as a string. + draco_set_and_stringify(SOURCE "${exe_LINK_FLAGS}" DEST exe_LINK_FLAGS) + set_target_properties(${exe_NAME} PROPERTIES LINK_FLAGS + "${exe_LINK_FLAGS}") + else() + target_link_options(${exe_NAME} PRIVATE ${exe_LINK_FLAGS} + ${DRACO_EXE_LINKER_FLAGS}) + endif() + endif() + + if(exe_OBJLIB_DEPS) + foreach(objlib_dep ${exe_OBJLIB_DEPS}) + target_sources(${exe_NAME} PRIVATE $) + endforeach() + endif() + + if(CMAKE_THREAD_LIBS_INIT) + list(APPEND exe_LIB_DEPS ${CMAKE_THREAD_LIBS_INIT}) + endif() + + if(BUILD_SHARED_LIBS AND (MSVC OR WIN32)) + target_compile_definitions(${exe_NAME} PRIVATE "DRACO_BUILDING_DLL=0") + endif() + + if(exe_LIB_DEPS) + if(CMAKE_CXX_COMPILER_ID MATCHES "^Clang|^GNU") + # Third party dependencies can introduce dependencies on system and test + # libraries. Since the target created here is an executable, and CMake + # does not provide a method of controlling order of link dependencies, + # wrap all of the dependencies of this target in start/end group flags to + # ensure that dependencies of third party targets can be resolved when + # those dependencies happen to be resolved by dependencies of the current + # target. + # TODO(tomfinegan): For portability use LINK_GROUP with RESCAN instead of + # directly (ab)using compiler/linker specific flags once CMake v3.24 is in + # wider use. See: + # https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#genex:LINK_GROUP + list(INSERT exe_LIB_DEPS 0 -Wl,--start-group) + list(APPEND exe_LIB_DEPS -Wl,--end-group) + endif() + target_link_libraries(${exe_NAME} PRIVATE ${exe_LIB_DEPS}) + endif() +endmacro() + +# Creates a library target of the specified type. The target name is passed as a +# parameter to the NAME argument, the type as a parameter to the TYPE argument, +# and the sources passed as a parameter to the SOURCES argument: +# draco_add_library(NAME TYPE SOURCES [optional args]) +# +# Optional args: +# cmake-format: off +# - OUTPUT_NAME: Override output file basename. Target basename defaults to +# NAME. OUTPUT_NAME is ignored when BUILD_SHARED_LIBS is enabled and CMake +# is generating a build for which MSVC is true. This is to avoid output +# basename collisions with DLL import libraries. +# - TEST: Flag. Presence means treat library as a test. +# - DEFINES: List of preprocessor macro definitions. +# - INCLUDES: list of include directories for the target. +# - COMPILE_FLAGS: list of compiler flags for the target. +# - LINK_FLAGS: List of linker flags for the target. +# - OBJLIB_DEPS: List of CMake object library target dependencies. +# - LIB_DEPS: List of CMake library dependencies. +# - PUBLIC_INCLUDES: List of include paths to export to dependents. +# cmake-format: on +# +# Sources passed to the macro are added to the lists tracking draco sources: +# cmake-format: off +# - When TEST is specified sources are added to $draco_test_sources. +# - Otherwise sources are added to $draco_sources. +# cmake-format: on +# +# Targets passed to this macro are added to the lists tracking draco targets: +# cmake-format: off +# - Targets are always added to $draco_targets. +# - When the TEST flag is specified, targets are added to +# $draco_test_targets. +# - When TEST is not specified: +# - Libraries of type SHARED are added to $draco_dylib_targets. +# - Libraries of type OBJECT are added to $draco_objlib_targets. +# - Libraries of type STATIC are added to $draco_lib_targets. +# cmake-format: on +macro(draco_add_library) + unset(lib_TEST) + unset(lib_NAME) + unset(lib_OUTPUT_NAME) + unset(lib_TYPE) + unset(lib_SOURCES) + unset(lib_DEFINES) + unset(lib_INCLUDES) + unset(lib_COMPILE_FLAGS) + unset(lib_LINK_FLAGS) + unset(lib_OBJLIB_DEPS) + unset(lib_LIB_DEPS) + unset(lib_PUBLIC_INCLUDES) + unset(lib_TARGET_PROPERTIES) + set(optional_args TEST) + set(single_value_args NAME OUTPUT_NAME TYPE) + set(multi_value_args + SOURCES + DEFINES + INCLUDES + COMPILE_FLAGS + LINK_FLAGS + OBJLIB_DEPS + LIB_DEPS + PUBLIC_INCLUDES + TARGET_PROPERTIES) + + cmake_parse_arguments(lib "${optional_args}" "${single_value_args}" + "${multi_value_args}" ${ARGN}) + + if(DRACO_VERBOSE GREATER 1) + message( + "--------- draco_add_library ---------\n" + "lib_TEST=${lib_TEST}\n" + "lib_NAME=${lib_NAME}\n" + "lib_OUTPUT_NAME=${lib_OUTPUT_NAME}\n" + "lib_TYPE=${lib_TYPE}\n" + "lib_SOURCES=${lib_SOURCES}\n" + "lib_DEFINES=${lib_DEFINES}\n" + "lib_INCLUDES=${lib_INCLUDES}\n" + "lib_COMPILE_FLAGS=${lib_COMPILE_FLAGS}\n" + "lib_LINK_FLAGS=${lib_LINK_FLAGS}\n" + "lib_OBJLIB_DEPS=${lib_OBJLIB_DEPS}\n" + "lib_LIB_DEPS=${lib_LIB_DEPS}\n" + "lib_PUBLIC_INCLUDES=${lib_PUBLIC_INCLUDES}\n" + "---------------------------------------\n") + endif() + + if(NOT (lib_NAME AND lib_TYPE)) + message(FATAL_ERROR "draco_add_library: NAME and TYPE required.") + endif() + + list(APPEND draco_targets ${lib_NAME}) + if(lib_TEST) + list(APPEND draco_test_targets ${lib_NAME}) + list(APPEND draco_test_sources ${lib_SOURCES}) + else() + list(APPEND draco_sources ${lib_SOURCES}) + if(lib_TYPE STREQUAL MODULE) + list(APPEND draco_module_targets ${lib_NAME}) + elseif(lib_TYPE STREQUAL OBJECT) + list(APPEND draco_objlib_targets ${lib_NAME}) + elseif(lib_TYPE STREQUAL SHARED) + list(APPEND draco_dylib_targets ${lib_NAME}) + elseif(lib_TYPE STREQUAL STATIC) + list(APPEND draco_lib_targets ${lib_NAME}) + else() + message(WARNING "draco_add_library: Unhandled type: ${lib_TYPE}") + endif() + endif() + + add_library(${lib_NAME} ${lib_TYPE} ${lib_SOURCES}) + + target_compile_features(${lib_NAME} PUBLIC cxx_std_11) + + target_include_directories(${lib_NAME} PUBLIC $) + + if(BUILD_SHARED_LIBS) + # Enable PIC for all targets in shared configurations. + set_target_properties(${lib_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) + endif() + + if(lib_SOURCES) + draco_process_intrinsics_sources(TARGET ${lib_NAME} SOURCES ${lib_SOURCES}) + endif() + + if(lib_OUTPUT_NAME) + if(NOT (BUILD_SHARED_LIBS AND MSVC)) + set_target_properties(${lib_NAME} PROPERTIES OUTPUT_NAME + ${lib_OUTPUT_NAME}) + endif() + endif() + + if(lib_DEFINES) + target_compile_definitions(${lib_NAME} PRIVATE ${lib_DEFINES}) + endif() + + if(lib_INCLUDES) + target_include_directories(${lib_NAME} PRIVATE ${lib_INCLUDES}) + endif() + + if(lib_PUBLIC_INCLUDES) + target_include_directories(${lib_NAME} PUBLIC ${lib_PUBLIC_INCLUDES}) + endif() + + if(lib_COMPILE_FLAGS OR DRACO_CXX_FLAGS) + target_compile_options(${lib_NAME} PRIVATE ${lib_COMPILE_FLAGS} + ${DRACO_CXX_FLAGS}) + endif() + + if(lib_LINK_FLAGS) + set_target_properties(${lib_NAME} PROPERTIES LINK_FLAGS ${lib_LINK_FLAGS}) + endif() + + if(lib_OBJLIB_DEPS) + foreach(objlib_dep ${lib_OBJLIB_DEPS}) + target_sources(${lib_NAME} PRIVATE $) + endforeach() + endif() + + if(lib_LIB_DEPS) + if(lib_TYPE STREQUAL STATIC) + set(link_type PUBLIC) + else() + set(link_type PRIVATE) + if(lib_TYPE STREQUAL SHARED AND CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") + # The draco shared object uses the static draco as input to turn it into + # a shared object. Include everything from the static library in the + # shared object. + if(APPLE) + list(INSERT lib_LIB_DEPS 0 -Wl,-force_load) + else() + list(INSERT lib_LIB_DEPS 0 -Wl,--whole-archive) + list(APPEND lib_LIB_DEPS -Wl,--no-whole-archive) + endif() + endif() + endif() + target_link_libraries(${lib_NAME} ${link_type} ${lib_LIB_DEPS}) + endif() + + if(NOT MSVC AND lib_NAME MATCHES "^lib") + # Non-MSVC generators prepend lib to static lib target file names. Libdraco + # already includes lib in its name. Avoid naming output files liblib*. + set_target_properties(${lib_NAME} PROPERTIES PREFIX "") + endif() + + if(NOT EMSCRIPTEN) + # VERSION and SOVERSION as necessary + if((lib_TYPE STREQUAL BUNDLE OR lib_TYPE STREQUAL SHARED) AND NOT MSVC) + set_target_properties( + ${lib_NAME} PROPERTIES VERSION ${DRACO_SOVERSION} + SOVERSION ${DRACO_SOVERSION_MAJOR}) + endif() + endif() + + if(BUILD_SHARED_LIBS AND (MSVC OR WIN32)) + if(lib_TYPE STREQUAL SHARED) + target_compile_definitions(${lib_NAME} PRIVATE "DRACO_BUILDING_DLL=1") + else() + target_compile_definitions(${lib_NAME} PRIVATE "DRACO_BUILDING_DLL=0") + endif() + endif() + + # Determine if $lib_NAME is a header only target. + unset(sources_list) + if(lib_SOURCES) + set(sources_list ${lib_SOURCES}) + list(FILTER sources_list INCLUDE REGEX cc$) + endif() + + if(NOT sources_list) + if(NOT XCODE) + # This is a header only target. Tell CMake the link language. + set_target_properties(${lib_NAME} PROPERTIES LINKER_LANGUAGE CXX) + else() + # The Xcode generator ignores LINKER_LANGUAGE. Add a dummy cc file. + draco_create_dummy_source_file(TARGET ${lib_NAME} BASENAME ${lib_NAME}) + endif() + endif() +endmacro() diff --git a/third-party/draco/cmake/draco_test_config.h.cmake b/third-party/draco/cmake/draco_test_config.h.cmake new file mode 100644 index 0000000000..9bb1745699 --- /dev/null +++ b/third-party/draco/cmake/draco_test_config.h.cmake @@ -0,0 +1,28 @@ +// Copyright 2021 The Draco Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef DRACO_TESTING_DRACO_TEST_CONFIG_H_ +#define DRACO_TESTING_DRACO_TEST_CONFIG_H_ + +// If this file is named draco_test_config.h.cmake: +// This file is used as input at cmake generation time. + +// If this file is named draco_test_config.h: +// GENERATED FILE, DO NOT EDIT. SEE ABOVE. + +#define DRACO_TEST_DATA_DIR "${DRACO_TEST_DATA_DIR}" +#define DRACO_TEST_TEMP_DIR "${DRACO_TEST_TEMP_DIR}" +#define DRACO_TEST_ROOT_DIR "${DRACO_TEST_ROOT_DIR}" + +#endif // DRACO_TESTING_DRACO_TEST_CONFIG_H_ diff --git a/third-party/draco/cmake/draco_tests.cmake b/third-party/draco/cmake/draco_tests.cmake new file mode 100644 index 0000000000..a8283e2d7e --- /dev/null +++ b/third-party/draco/cmake/draco_tests.cmake @@ -0,0 +1,173 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_TESTS_CMAKE) + return() +endif() +set(DRACO_CMAKE_DRACO_TESTS_CMAKE 1) + +# The factory tests are in a separate target to avoid breaking tests that rely +# on file I/O via the factories. The fake reader and writer implementations +# interfere with normal file I/O function. +set(draco_factory_test_sources + "${draco_src_root}/io/file_reader_factory_test.cc" + "${draco_src_root}/io/file_writer_factory_test.cc") + +list( + APPEND draco_test_common_sources + "${draco_src_root}/core/draco_test_base.h" + "${draco_src_root}/core/draco_test_utils.cc" + "${draco_src_root}/core/draco_test_utils.h" + "${draco_src_root}/core/status.cc") + +list( + APPEND + draco_test_sources + "${draco_src_root}/animation/keyframe_animation_encoding_test.cc" + "${draco_src_root}/animation/keyframe_animation_test.cc" + "${draco_src_root}/attributes/point_attribute_test.cc" + "${draco_src_root}/compression/attributes/point_d_vector_test.cc" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_test.cc" + "${draco_src_root}/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_test.cc" + "${draco_src_root}/compression/attributes/sequential_integer_attribute_encoding_test.cc" + "${draco_src_root}/compression/bit_coders/rans_coding_test.cc" + "${draco_src_root}/compression/decode_test.cc" + "${draco_src_root}/compression/encode_test.cc" + "${draco_src_root}/compression/entropy/shannon_entropy_test.cc" + "${draco_src_root}/compression/entropy/symbol_coding_test.cc" + "${draco_src_root}/compression/mesh/mesh_edgebreaker_encoding_test.cc" + "${draco_src_root}/compression/mesh/mesh_encoder_test.cc" + "${draco_src_root}/compression/point_cloud/point_cloud_kd_tree_encoding_test.cc" + "${draco_src_root}/compression/point_cloud/point_cloud_sequential_encoding_test.cc" + "${draco_src_root}/core/buffer_bit_coding_test.cc" + "${draco_src_root}/core/math_utils_test.cc" + "${draco_src_root}/core/quantization_utils_test.cc" + "${draco_src_root}/core/status_test.cc" + "${draco_src_root}/core/vector_d_test.cc" + "${draco_src_root}/io/file_reader_test_common.h" + "${draco_src_root}/io/file_utils_test.cc" + "${draco_src_root}/io/file_writer_utils_test.cc" + "${draco_src_root}/io/stdio_file_reader_test.cc" + "${draco_src_root}/io/stdio_file_writer_test.cc" + "${draco_src_root}/io/obj_decoder_test.cc" + "${draco_src_root}/io/obj_encoder_test.cc" + "${draco_src_root}/io/ply_decoder_test.cc" + "${draco_src_root}/io/ply_reader_test.cc" + "${draco_src_root}/io/stl_decoder_test.cc" + "${draco_src_root}/io/stl_encoder_test.cc" + "${draco_src_root}/io/point_cloud_io_test.cc" + "${draco_src_root}/mesh/corner_table_test.cc" + "${draco_src_root}/mesh/mesh_are_equivalent_test.cc" + "${draco_src_root}/mesh/mesh_cleanup_test.cc" + "${draco_src_root}/mesh/triangle_soup_mesh_builder_test.cc" + "${draco_src_root}/metadata/metadata_encoder_test.cc" + "${draco_src_root}/metadata/metadata_test.cc" + "${draco_src_root}/point_cloud/point_cloud_builder_test.cc" + "${draco_src_root}/point_cloud/point_cloud_test.cc") + +if(DRACO_TRANSCODER_SUPPORTED) + list( + APPEND draco_test_sources + "${draco_src_root}/animation/animation_test.cc" + "${draco_src_root}/io/gltf_decoder_test.cc" + "${draco_src_root}/io/gltf_encoder_test.cc" + "${draco_src_root}/io/gltf_utils_test.cc" + "${draco_src_root}/io/gltf_test_helper.cc" + "${draco_src_root}/io/gltf_test_helper.h" + "${draco_src_root}/io/scene_io_test.cc" + "${draco_src_root}/io/texture_io_test.cc" + "${draco_src_root}/material/material_library_test.cc" + "${draco_src_root}/material/material_test.cc" + "${draco_src_root}/metadata/property_attribute_test.cc" + "${draco_src_root}/metadata/property_table_test.cc" + "${draco_src_root}/metadata/structural_metadata_test.cc" + "${draco_src_root}/metadata/structural_metadata_schema_test.cc" + "${draco_src_root}/scene/instance_array_test.cc" + "${draco_src_root}/scene/light_test.cc" + "${draco_src_root}/scene/mesh_group_test.cc" + "${draco_src_root}/scene/scene_test.cc" + "${draco_src_root}/scene/scene_are_equivalent_test.cc" + "${draco_src_root}/scene/scene_utils_test.cc" + "${draco_src_root}/scene/trs_matrix_test.cc" + "${draco_src_root}/texture/texture_library_test.cc" + "${draco_src_root}/texture/texture_map_test.cc" + "${draco_src_root}/texture/texture_transform_test.cc") + +endif() + +macro(draco_setup_test_targets) + if(DRACO_TESTS) + draco_setup_googletest() + + if(NOT (EXISTS ${draco_gtest_all} AND EXISTS ${draco_gtest_main})) + message(FATAL_ERROR "googletest missing, run git submodule update --init") + endif() + + list(APPEND draco_test_defines GTEST_HAS_PTHREAD=0) + + draco_add_library( + TEST + NAME draco_test_common + TYPE STATIC + SOURCES ${draco_test_common_sources} + DEFINES ${draco_defines} ${draco_test_defines} + INCLUDES ${draco_test_include_paths}) + + draco_add_library( + TEST + NAME draco_gtest + TYPE STATIC + SOURCES ${draco_gtest_all} + DEFINES ${draco_defines} ${draco_test_defines} + INCLUDES ${draco_test_include_paths}) + + draco_add_library( + TEST + NAME draco_gtest_main + TYPE STATIC + SOURCES ${draco_gtest_main} + DEFINES ${draco_defines} ${draco_test_defines} + INCLUDES ${draco_test_include_paths}) + + set(DRACO_TEST_DATA_DIR "${draco_root}/testdata") + set(DRACO_TEST_TEMP_DIR "${draco_build}/draco_test_temp") + set(DRACO_TEST_ROOT_DIR "${draco_root}") + file(MAKE_DIRECTORY "${DRACO_TEST_TEMP_DIR}") + + # Sets DRACO_TEST_DATA_DIR and DRACO_TEST_TEMP_DIR. + configure_file("${draco_root}/cmake/draco_test_config.h.cmake" + "${draco_build}/testing/draco_test_config.h") + + # Create the test targets. + draco_add_executable( + TEST + NAME draco_tests + SOURCES ${draco_test_sources} + DEFINES ${draco_defines} ${draco_test_defines} + INCLUDES ${draco_test_include_paths} + LIB_DEPS ${draco_dependency} draco_gtest draco_gtest_main + draco_test_common) + + draco_add_executable( + TEST + NAME draco_factory_tests + SOURCES ${draco_factory_test_sources} + DEFINES ${draco_defines} ${draco_test_defines} + INCLUDES ${draco_test_include_paths} + LIB_DEPS ${draco_dependency} draco_gtest draco_gtest_main + draco_test_common) + + + endif() +endmacro() diff --git a/third-party/draco/cmake/draco_variables.cmake b/third-party/draco/cmake/draco_variables.cmake new file mode 100644 index 0000000000..6d1b6a99da --- /dev/null +++ b/third-party/draco/cmake/draco_variables.cmake @@ -0,0 +1,79 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_DRACO_VARIABLES_CMAKE_) + return() +endif() # DRACO_CMAKE_DRACO_VARIABLES_CMAKE_ +set(DRACO_CMAKE_DRACO_VARIABLES_CMAKE_ 1) + +# Halts generation when $variable_name does not refer to a directory that +# exists. +macro(draco_variable_must_be_directory variable_name) + if("${variable_name}" STREQUAL "") + message( + FATAL_ERROR + "Empty variable_name passed to draco_variable_must_be_directory.") + endif() + + if("${${variable_name}}" STREQUAL "") + message( + FATAL_ERROR "Empty variable ${variable_name} is required to build draco.") + endif() + + if(NOT IS_DIRECTORY "${${variable_name}}") + message( + FATAL_ERROR + "${variable_name}, which is ${${variable_name}}, does not refer to a\n" + "directory.") + endif() +endmacro() + +# Adds $var_name to the tracked variables list. +macro(draco_track_configuration_variable var_name) + if(DRACO_VERBOSE GREATER 2) + message("---- draco_track_configuration_variable ----\n" + "var_name=${var_name}\n" + "----------------------------------------------\n") + endif() + + list(APPEND draco_configuration_variables ${var_name}) + list(REMOVE_DUPLICATES draco_configuration_variables) +endmacro() + +# Logs current C++ and executable linker flags via the CMake message command. +macro(draco_dump_cmake_flag_variables) + unset(flag_variables) + list(APPEND flag_variables "CMAKE_CXX_FLAGS_INIT" "CMAKE_CXX_FLAGS" + "CMAKE_EXE_LINKER_FLAGS_INIT" "CMAKE_EXE_LINKER_FLAGS") + if(CMAKE_BUILD_TYPE) + list( + APPEND flag_variables + "CMAKE_BUILD_TYPE" + "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}_INIT" + "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" + "CMAKE_EXE_LINKER_FLAGS_${CMAKE_BUILD_TYPE}_INIT" + "CMAKE_EXE_LINKER_FLAGS_${CMAKE_BUILD_TYPE}") + endif() + foreach(flag_variable ${flag_variables}) + message("${flag_variable}:${${flag_variable}}") + endforeach() +endmacro() + +# Dumps the variables tracked in $draco_configuration_variables via the CMake +# message command. +macro(draco_dump_tracked_configuration_variables) + foreach(config_variable ${draco_configuration_variables}) + message("${config_variable}:${${config_variable}}") + endforeach() +endmacro() diff --git a/third-party/draco/cmake/toolchains/aarch64-linux-gnu.cmake b/third-party/draco/cmake/toolchains/aarch64-linux-gnu.cmake new file mode 100644 index 0000000000..a55da20faf --- /dev/null +++ b/third-party/draco/cmake/toolchains/aarch64-linux-gnu.cmake @@ -0,0 +1,28 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_AARCH64_LINUX_GNU_CMAKE_) + return() +endif() # DRACO_CMAKE_TOOLCHAINS_AARCH64_LINUX_GNU_CMAKE_ +set(DRACO_CMAKE_TOOLCHAINS_AARCH64_LINUX_GNU_CMAKE_ 1) + +set(CMAKE_SYSTEM_NAME "Linux") + +if("${CROSS}" STREQUAL "") + set(CROSS aarch64-linux-gnu-) +endif() + +set(CMAKE_CXX_COMPILER ${CROSS}g++) +set(CMAKE_CXX_FLAGS_INIT "-march=armv8-a") +set(CMAKE_SYSTEM_PROCESSOR "aarch64") diff --git a/third-party/draco/cmake/toolchains/android-ndk-common.cmake b/third-party/draco/cmake/toolchains/android-ndk-common.cmake new file mode 100644 index 0000000000..80396af485 --- /dev/null +++ b/third-party/draco/cmake/toolchains/android-ndk-common.cmake @@ -0,0 +1,37 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_ANDROID_NDK_COMMON_CMAKE_) + return() +endif() +set(DRACO_CMAKE_TOOLCHAINS_ANDROID_NDK_COMMON_CMAKE_ 1) + +# Toolchain files do not have access to cached variables: +# https://gitlab.kitware.com/cmake/cmake/issues/16170. Set an intermediate +# environment variable when loaded the first time. +if(DRACO_ANDROID_NDK_PATH) + set(ENV{DRACO_ANDROID_NDK_PATH} "${DRACO_ANDROID_NDK_PATH}") +else() + set(DRACO_ANDROID_NDK_PATH "$ENV{DRACO_ANDROID_NDK_PATH}") +endif() + +set(CMAKE_SYSTEM_NAME Android) + +if(NOT CMAKE_ANDROID_STL_TYPE) + set(CMAKE_ANDROID_STL_TYPE c++_static) +endif() + +if(NOT CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION) + set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang) +endif() diff --git a/third-party/draco/cmake/toolchains/android.cmake b/third-party/draco/cmake/toolchains/android.cmake new file mode 100644 index 0000000000..ba50576b7d --- /dev/null +++ b/third-party/draco/cmake/toolchains/android.cmake @@ -0,0 +1,53 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_ANDROID_CMAKE_) + return() +endif() # DRACO_CMAKE_TOOLCHAINS_ANDROID_CMAKE_ + +# Additional ANDROID_* settings are available, see: +# https://developer.android.com/ndk/guides/cmake#variables + +if(NOT ANDROID_PLATFORM) + set(ANDROID_PLATFORM android-21) +endif() + +# Choose target architecture with: +# +# -DANDROID_ABI={armeabi-v7a,armeabi-v7a with NEON,arm64-v8a,x86,x86_64} +if(NOT ANDROID_ABI) + set(ANDROID_ABI arm64-v8a) +endif() + +# Force arm mode for 32-bit arm targets (instead of the default thumb) to +# improve performance. +if(ANDROID_ABI MATCHES "^armeabi" AND NOT ANDROID_ARM_MODE) + set(ANDROID_ARM_MODE arm) +endif() + +# Toolchain files do not have access to cached variables: +# https://gitlab.kitware.com/cmake/cmake/issues/16170. Set an intermediate +# environment variable when loaded the first time. +if(DRACO_ANDROID_NDK_PATH) + set(ENV{DRACO_ANDROID_NDK_PATH} "${DRACO_ANDROID_NDK_PATH}") +else() + set(DRACO_ANDROID_NDK_PATH "$ENV{DRACO_ANDROID_NDK_PATH}") +endif() + +if(NOT DRACO_ANDROID_NDK_PATH) + message(FATAL_ERROR "DRACO_ANDROID_NDK_PATH not set.") + return() +endif() + +include("${DRACO_ANDROID_NDK_PATH}/build/cmake/android.toolchain.cmake") diff --git a/third-party/draco/cmake/toolchains/arm-ios-common.cmake b/third-party/draco/cmake/toolchains/arm-ios-common.cmake new file mode 100644 index 0000000000..fab54bb398 --- /dev/null +++ b/third-party/draco/cmake/toolchains/arm-ios-common.cmake @@ -0,0 +1,29 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_ARM_IOS_COMMON_CMAKE_) + return() +endif() +set(DRACO_CMAKE_ARM_IOS_COMMON_CMAKE_ 1) + +set(CMAKE_SYSTEM_NAME "Darwin") +if(CMAKE_OSX_SDK) + set(CMAKE_OSX_SYSROOT ${CMAKE_OSX_SDK}) +else() + set(CMAKE_OSX_SYSROOT iphoneos) +endif() +set(CMAKE_C_COMPILER clang) +set(CMAKE_C_COMPILER_ARG1 "-arch ${CMAKE_SYSTEM_PROCESSOR}") +set(CMAKE_CXX_COMPILER clang++) +set(CMAKE_CXX_COMPILER_ARG1 "-arch ${CMAKE_SYSTEM_PROCESSOR}") diff --git a/third-party/draco/cmake/toolchains/arm-linux-gnueabihf.cmake b/third-party/draco/cmake/toolchains/arm-linux-gnueabihf.cmake new file mode 100644 index 0000000000..f1f83d67c6 --- /dev/null +++ b/third-party/draco/cmake/toolchains/arm-linux-gnueabihf.cmake @@ -0,0 +1,29 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_ARM_LINUX_GNUEABIHF_CMAKE_) + return() +endif() # DRACO_CMAKE_TOOLCHAINS_ARM_LINUX_GNUEABIHF_CMAKE_ +set(DRACO_CMAKE_TOOLCHAINS_ARM_LINUX_GNUEABIHF_CMAKE_ 1) + +set(CMAKE_SYSTEM_NAME "Linux") + +if("${CROSS}" STREQUAL "") + set(CROSS arm-linux-gnueabihf-) +endif() + +set(CMAKE_CXX_COMPILER ${CROSS}g++) +set(CMAKE_CXX_FLAGS_INIT "-march=armv7-a -marm") +set(CMAKE_SYSTEM_PROCESSOR "armv7") +set(DRACO_NEON_INTRINSICS_FLAG "-mfpu=neon") diff --git a/third-party/draco/cmake/toolchains/arm64-android-ndk-libcpp.cmake b/third-party/draco/cmake/toolchains/arm64-android-ndk-libcpp.cmake new file mode 100644 index 0000000000..80d452f97f --- /dev/null +++ b/third-party/draco/cmake/toolchains/arm64-android-ndk-libcpp.cmake @@ -0,0 +1,30 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_) + return() +endif() +set(DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_ 1) + +include("${CMAKE_CURRENT_LIST_DIR}/android-ndk-common.cmake") + +if(NOT ANDROID_PLATFORM) + set(ANROID_PLATFORM android-21) +endif() + +if(NOT ANDROID_ABI) + set(ANDROID_ABI arm64-v8a) +endif() + +include("${DRACO_ANDROID_NDK_PATH}/build/cmake/android.toolchain.cmake") diff --git a/third-party/draco/cmake/toolchains/arm64-ios.cmake b/third-party/draco/cmake/toolchains/arm64-ios.cmake new file mode 100644 index 0000000000..5365d70f15 --- /dev/null +++ b/third-party/draco/cmake/toolchains/arm64-ios.cmake @@ -0,0 +1,27 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_ARM64_IOS_CMAKE_) + return() +endif() +set(DRACO_CMAKE_TOOLCHAINS_ARM64_IOS_CMAKE_ 1) + +if(XCODE) + message(FATAL_ERROR "This toolchain does not support Xcode.") +endif() + +set(CMAKE_SYSTEM_PROCESSOR "arm64") +set(CMAKE_OSX_ARCHITECTURES "arm64") + +include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake") diff --git a/third-party/draco/cmake/toolchains/arm64-linux-gcc.cmake b/third-party/draco/cmake/toolchains/arm64-linux-gcc.cmake new file mode 100644 index 0000000000..a332760b2e --- /dev/null +++ b/third-party/draco/cmake/toolchains/arm64-linux-gcc.cmake @@ -0,0 +1,32 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_ARM64_LINUX_GCC_CMAKE_) + return() +endif() +set(DRACO_CMAKE_TOOLCHAINS_ARM64_LINUX_GCC_CMAKE_ 1) + +set(CMAKE_SYSTEM_NAME "Linux") + +if("${CROSS}" STREQUAL "") + # Default the cross compiler prefix to something known to work. + set(CROSS aarch64-linux-gnu-) +endif() + +set(CMAKE_C_COMPILER ${CROSS}gcc) +set(CMAKE_CXX_COMPILER ${CROSS}g++) +set(AS_EXECUTABLE ${CROSS}as) +set(CMAKE_C_COMPILER_ARG1 "-march=armv8-a") +set(CMAKE_CXX_COMPILER_ARG1 "-march=armv8-a") +set(CMAKE_SYSTEM_PROCESSOR "arm64") diff --git a/third-party/draco/cmake/toolchains/armv7-android-ndk-libcpp.cmake b/third-party/draco/cmake/toolchains/armv7-android-ndk-libcpp.cmake new file mode 100644 index 0000000000..bedcc0cad9 --- /dev/null +++ b/third-party/draco/cmake/toolchains/armv7-android-ndk-libcpp.cmake @@ -0,0 +1,30 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_) + return() +endif() +set(DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_ 1) + +include("${CMAKE_CURRENT_LIST_DIR}/android-ndk-common.cmake") + +if(NOT ANDROID_PLATFORM) + set(ANDROID_PLATFORM android-18) +endif() + +if(NOT ANDROID_ABI) + set(ANDROID_ABI armeabi-v7a) +endif() + +include("${DRACO_ANDROID_NDK_PATH}/build/cmake/android.toolchain.cmake") diff --git a/third-party/draco/cmake/toolchains/armv7-ios.cmake b/third-party/draco/cmake/toolchains/armv7-ios.cmake new file mode 100644 index 0000000000..43e208b1fb --- /dev/null +++ b/third-party/draco/cmake/toolchains/armv7-ios.cmake @@ -0,0 +1,27 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_ARMV7_IOS_CMAKE_) + return() +endif() +set(DRACO_CMAKE_TOOLCHAINS_ARMV7_IOS_CMAKE_ 1) + +if(XCODE) + message(FATAL_ERROR "This toolchain does not support Xcode.") +endif() + +set(CMAKE_SYSTEM_PROCESSOR "armv7") +set(CMAKE_OSX_ARCHITECTURES "armv7") + +include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake") diff --git a/third-party/draco/cmake/toolchains/armv7-linux-gcc.cmake b/third-party/draco/cmake/toolchains/armv7-linux-gcc.cmake new file mode 100644 index 0000000000..730a87f4b5 --- /dev/null +++ b/third-party/draco/cmake/toolchains/armv7-linux-gcc.cmake @@ -0,0 +1,38 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_ARMV7_LINUX_GCC_CMAKE_) + return() +endif() +set(DRACO_CMAKE_TOOLCHAINS_ARMV7_LINUX_GCC_CMAKE_ 1) + +set(CMAKE_SYSTEM_NAME "Linux") + +if("${CROSS}" STREQUAL "") + # Default the cross compiler prefix to something known to work. + set(CROSS arm-linux-gnueabihf-) +endif() + +if(NOT ${CROSS} MATCHES hf-$) + set(DRACO_EXTRA_TOOLCHAIN_FLAGS "-mfloat-abi=softfp") +endif() + +set(CMAKE_C_COMPILER ${CROSS}gcc) +set(CMAKE_CXX_COMPILER ${CROSS}g++) +set(AS_EXECUTABLE ${CROSS}as) +set(CMAKE_C_COMPILER_ARG1 + "-march=armv7-a -mfpu=neon ${DRACO_EXTRA_TOOLCHAIN_FLAGS}") +set(CMAKE_CXX_COMPILER_ARG1 + "-march=armv7-a -mfpu=neon ${DRACO_EXTRA_TOOLCHAIN_FLAGS}") +set(CMAKE_SYSTEM_PROCESSOR "armv7") diff --git a/third-party/draco/cmake/toolchains/armv7s-ios.cmake b/third-party/draco/cmake/toolchains/armv7s-ios.cmake new file mode 100644 index 0000000000..4727561179 --- /dev/null +++ b/third-party/draco/cmake/toolchains/armv7s-ios.cmake @@ -0,0 +1,27 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_ARMV7S_IOS_CMAKE_) + return() +endif() +set(DRACO_CMAKE_TOOLCHAINS_ARMV7S_IOS_CMAKE_ 1) + +if(XCODE) + message(FATAL_ERROR "This toolchain does not support Xcode.") +endif() + +set(CMAKE_SYSTEM_PROCESSOR "armv7s") +set(CMAKE_OSX_ARCHITECTURES "armv7s") + +include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake") diff --git a/third-party/draco/cmake/toolchains/i386-ios.cmake b/third-party/draco/cmake/toolchains/i386-ios.cmake new file mode 100644 index 0000000000..38989d225c --- /dev/null +++ b/third-party/draco/cmake/toolchains/i386-ios.cmake @@ -0,0 +1,28 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_i386_IOS_CMAKE_) + return() +endif() +set(DRACO_CMAKE_TOOLCHAINS_i386_IOS_CMAKE_ 1) + +if(XCODE) + message(FATAL_ERROR "This toolchain does not support Xcode.") +endif() + +set(CMAKE_SYSTEM_PROCESSOR "i386") +set(CMAKE_OSX_ARCHITECTURES "i386") +set(CMAKE_OSX_SDK "iphonesimulator") + +include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake") diff --git a/third-party/draco/cmake/toolchains/x86-android-ndk-libcpp.cmake b/third-party/draco/cmake/toolchains/x86-android-ndk-libcpp.cmake new file mode 100644 index 0000000000..6f63f2c311 --- /dev/null +++ b/third-party/draco/cmake/toolchains/x86-android-ndk-libcpp.cmake @@ -0,0 +1,30 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_) + return() +endif() +set(DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_ 1) + +include("${CMAKE_CURRENT_LIST_DIR}/android-ndk-common.cmake") + +if(NOT ANDROID_PLATFORM) + set(ANDROID_PLATFORM android-18) +endif() + +if(NOT ANDROID_ABI) + set(ANDROID_ABI x86) +endif() + +include("${DRACO_ANDROID_NDK_PATH}/build/cmake/android.toolchain.cmake") diff --git a/third-party/draco/cmake/toolchains/x86_64-android-ndk-libcpp.cmake b/third-party/draco/cmake/toolchains/x86_64-android-ndk-libcpp.cmake new file mode 100644 index 0000000000..7a630f4d49 --- /dev/null +++ b/third-party/draco/cmake/toolchains/x86_64-android-ndk-libcpp.cmake @@ -0,0 +1,30 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_) + return() +endif() +set(DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_ 1) + +include("${CMAKE_CURRENT_LIST_DIR}/android-ndk-common.cmake") + +if(NOT ANDROID_PLATFORM) + set(ANDROID_PLATFORM android-21) +endif() + +if(NOT ANDROID_ABI) + set(ANDROID_ABI x86_64) +endif() + +include("${DRACO_ANDROID_NDK_PATH}/build/cmake/android.toolchain.cmake") diff --git a/third-party/draco/cmake/toolchains/x86_64-ios.cmake b/third-party/draco/cmake/toolchains/x86_64-ios.cmake new file mode 100644 index 0000000000..6946ce4105 --- /dev/null +++ b/third-party/draco/cmake/toolchains/x86_64-ios.cmake @@ -0,0 +1,28 @@ +# Copyright 2021 The Draco Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. + +if(DRACO_CMAKE_TOOLCHAINS_X86_64_IOS_CMAKE_) + return() +endif() +set(DRACO_CMAKE_TOOLCHAINS_X86_64_IOS_CMAKE_ 1) + +if(XCODE) + message(FATAL_ERROR "This toolchain does not support Xcode.") +endif() + +set(CMAKE_SYSTEM_PROCESSOR "x86_64") +set(CMAKE_OSX_ARCHITECTURES "x86_64") +set(CMAKE_OSX_SDK "iphonesimulator") + +include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake") diff --git a/third-party/draco/src/draco/animation/animation.cc b/third-party/draco/src/draco/animation/animation.cc new file mode 100644 index 0000000000..471cf29421 --- /dev/null +++ b/third-party/draco/src/draco/animation/animation.cc @@ -0,0 +1,47 @@ +// Copyright 2019 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/animation/animation.h" + +#ifdef DRACO_TRANSCODER_SUPPORTED + +namespace draco { + +void Animation::Copy(const Animation &src) { + name_ = src.name_; + channels_.clear(); + for (int i = 0; i < src.NumChannels(); ++i) { + std::unique_ptr new_channel(new AnimationChannel()); + new_channel->Copy(*src.GetChannel(i)); + channels_.push_back(std::move(new_channel)); + } + + samplers_.clear(); + for (int i = 0; i < src.NumSamplers(); ++i) { + std::unique_ptr new_sampler(new AnimationSampler()); + new_sampler->Copy(*src.GetSampler(i)); + samplers_.push_back(std::move(new_sampler)); + } + + node_animation_data_.clear(); + for (int i = 0; i < src.NumNodeAnimationData(); ++i) { + std::unique_ptr new_data(new NodeAnimationData()); + new_data->Copy(*src.GetNodeAnimationData(i)); + node_animation_data_.push_back(std::move(new_data)); + } +} + +} // namespace draco + +#endif // DRACO_TRANSCODER_SUPPORTED diff --git a/third-party/draco/src/draco/animation/animation.h b/third-party/draco/src/draco/animation/animation.h new file mode 100644 index 0000000000..3713f98862 --- /dev/null +++ b/third-party/draco/src/draco/animation/animation.h @@ -0,0 +1,149 @@ +// Copyright 2019 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ANIMATION_ANIMATION_H_ +#define DRACO_ANIMATION_ANIMATION_H_ + +#include "draco/draco_features.h" + +#ifdef DRACO_TRANSCODER_SUPPORTED +#include +#include + +#include "draco/animation/node_animation_data.h" +#include "draco/core/status.h" + +namespace draco { + +// Struct to hold information about an animation's sampler. +struct AnimationSampler { + enum class SamplerInterpolation { LINEAR, STEP, CUBICSPLINE }; + + static std::string InterpolationToString(SamplerInterpolation value) { + switch (value) { + case SamplerInterpolation::STEP: + return "STEP"; + case SamplerInterpolation::CUBICSPLINE: + return "CUBICSPLINE"; + default: + return "LINEAR"; + } + } + + AnimationSampler() + : input_index(-1), + interpolation_type(SamplerInterpolation::LINEAR), + output_index(-1) {} + + void Copy(const AnimationSampler &src) { + input_index = src.input_index; + interpolation_type = src.interpolation_type; + output_index = src.output_index; + } + + int input_index; + SamplerInterpolation interpolation_type; + int output_index; +}; + +// Struct to hold information about an animation's channel. +struct AnimationChannel { + enum class ChannelTransformation { TRANSLATION, ROTATION, SCALE, WEIGHTS }; + + static std::string TransformationToString(ChannelTransformation value) { + switch (value) { + case ChannelTransformation::ROTATION: + return "rotation"; + case ChannelTransformation::SCALE: + return "scale"; + case ChannelTransformation::WEIGHTS: + return "weights"; + default: + return "translation"; + } + } + + AnimationChannel() + : target_index(-1), + transformation_type(ChannelTransformation::TRANSLATION), + sampler_index(-1) {} + + void Copy(const AnimationChannel &src) { + target_index = src.target_index; + transformation_type = src.transformation_type; + sampler_index = src.sampler_index; + } + + int target_index; + ChannelTransformation transformation_type; + int sampler_index; +}; + +// This class is used to hold data and information of glTF animations. +class Animation { + public: + Animation() {} + + void Copy(const Animation &src); + + const std::string &GetName() const { return name_; } + void SetName(const std::string &name) { name_ = name; } + + // Returns the number of channels in an animation. + int NumChannels() const { return channels_.size(); } + // Returns the number of samplers in an animation. + int NumSamplers() const { return samplers_.size(); } + // Returns the number of accessors in an animation. + int NumNodeAnimationData() const { return node_animation_data_.size(); } + + // Returns a channel in the animation. + AnimationChannel *GetChannel(int index) { return channels_[index].get(); } + const AnimationChannel *GetChannel(int index) const { + return channels_[index].get(); + } + // Returns a sampler in the animation. + AnimationSampler *GetSampler(int index) { return samplers_[index].get(); } + const AnimationSampler *GetSampler(int index) const { + return samplers_[index].get(); + } + // Returns an accessor in the animation. + NodeAnimationData *GetNodeAnimationData(int index) { + return node_animation_data_[index].get(); + } + const NodeAnimationData *GetNodeAnimationData(int index) const { + return node_animation_data_[index].get(); + } + + void AddNodeAnimationData( + std::unique_ptr node_animation_data) { + node_animation_data_.push_back(std::move(node_animation_data)); + } + void AddSampler(std::unique_ptr sampler) { + samplers_.push_back(std::move(sampler)); + } + void AddChannel(std::unique_ptr channel) { + channels_.push_back(std::move(channel)); + } + + private: + std::string name_; + std::vector> samplers_; + std::vector> channels_; + std::vector> node_animation_data_; +}; + +} // namespace draco + +#endif // DRACO_TRANSCODER_SUPPORTED +#endif // DRACO_ANIMATION_ANIMATION_H_ diff --git a/third-party/draco/src/draco/animation/animation_test.cc b/third-party/draco/src/draco/animation/animation_test.cc new file mode 100644 index 0000000000..473938bcaf --- /dev/null +++ b/third-party/draco/src/draco/animation/animation_test.cc @@ -0,0 +1,71 @@ +// Copyright 2021 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/animation/animation.h" + +#include "draco/core/draco_test_base.h" +#include "draco/draco_features.h" + +namespace { + +#ifdef DRACO_TRANSCODER_SUPPORTED +TEST(AnimationTest, TestCopy) { + // Test copying of animation data. + draco::Animation src_anim; + ASSERT_TRUE(src_anim.GetName().empty()); + src_anim.SetName("Walking"); + ASSERT_EQ(src_anim.GetName(), "Walking"); + + std::unique_ptr src_sampler_0( + new draco::AnimationSampler()); + src_sampler_0->interpolation_type = + draco::AnimationSampler::SamplerInterpolation::CUBICSPLINE; + std::unique_ptr src_sampler_1( + new draco::AnimationSampler()); + src_sampler_1->Copy(*src_sampler_0); + + ASSERT_EQ(src_sampler_0->interpolation_type, + src_sampler_1->interpolation_type); + + src_sampler_1->interpolation_type = + draco::AnimationSampler::SamplerInterpolation::STEP; + + src_anim.AddSampler(std::move(src_sampler_0)); + src_anim.AddSampler(std::move(src_sampler_1)); + ASSERT_EQ(src_anim.NumSamplers(), 2); + + std::unique_ptr src_channel( + new draco::AnimationChannel()); + src_channel->transformation_type = + draco::AnimationChannel::ChannelTransformation::WEIGHTS; + src_anim.AddChannel(std::move(src_channel)); + ASSERT_EQ(src_anim.NumChannels(), 1); + + draco::Animation dst_anim; + dst_anim.Copy(src_anim); + + ASSERT_EQ(dst_anim.GetName(), src_anim.GetName()); + ASSERT_EQ(dst_anim.NumSamplers(), 2); + ASSERT_EQ(dst_anim.NumChannels(), 1); + + ASSERT_EQ(dst_anim.GetSampler(0)->interpolation_type, + src_anim.GetSampler(0)->interpolation_type); + ASSERT_EQ(dst_anim.GetSampler(1)->interpolation_type, + src_anim.GetSampler(1)->interpolation_type); + ASSERT_EQ(dst_anim.GetChannel(0)->transformation_type, + src_anim.GetChannel(0)->transformation_type); +} +#endif // DRACO_TRANSCODER_SUPPORTED + +} // namespace diff --git a/third-party/draco/src/draco/animation/keyframe_animation.cc b/third-party/draco/src/draco/animation/keyframe_animation.cc new file mode 100644 index 0000000000..eaf94a3305 --- /dev/null +++ b/third-party/draco/src/draco/animation/keyframe_animation.cc @@ -0,0 +1,54 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/animation/keyframe_animation.h" + +namespace draco { + +KeyframeAnimation::KeyframeAnimation() {} + +bool KeyframeAnimation::SetTimestamps( + const std::vector ×tamp) { + // Already added attributes. + const int32_t num_frames = timestamp.size(); + if (num_attributes() > 0) { + // Timestamp attribute could be added only once. + if (timestamps()->size()) { + return false; + } else { + // Check if the number of frames is consistent with + // the existing keyframes. + if (num_frames != num_points()) { + return false; + } + } + } else { + // This is the first attribute. + set_num_frames(num_frames); + } + + // Add attribute for time stamp data. + std::unique_ptr timestamp_att = + std::unique_ptr(new PointAttribute()); + timestamp_att->Init(GeometryAttribute::GENERIC, 1, DT_FLOAT32, false, + num_frames); + for (PointIndex i(0); i < num_frames; ++i) { + timestamp_att->SetAttributeValue(timestamp_att->mapped_index(i), + ×tamp[i.value()]); + } + this->SetAttribute(kTimestampId, std::move(timestamp_att)); + return true; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/animation/keyframe_animation.h b/third-party/draco/src/draco/animation/keyframe_animation.h new file mode 100644 index 0000000000..a7afb2b81b --- /dev/null +++ b/third-party/draco/src/draco/animation/keyframe_animation.h @@ -0,0 +1,107 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ANIMATION_KEYFRAME_ANIMATION_H_ +#define DRACO_ANIMATION_KEYFRAME_ANIMATION_H_ + +#include + +#include "draco/point_cloud/point_cloud.h" + +namespace draco { + +// Class for holding keyframe animation data. It will have two or more +// attributes as a point cloud. The first attribute is always the timestamp +// of the animation. Each KeyframeAnimation could have multiple animations with +// the same number of frames. Each animation will be treated as a point +// attribute. +class KeyframeAnimation : public PointCloud { + public: + // Force time stamp to be float type. + using TimestampType = float; + + KeyframeAnimation(); + + // Animation must have only one timestamp attribute. + // This function must be called before adding any animation data. + // Returns false if timestamp already exists. + bool SetTimestamps(const std::vector ×tamp); + + // Returns an id for the added animation data. This id will be used to + // identify this animation. + // Returns -1 if error, e.g. number of frames is not consistent. + // Type |T| should be consistent with |DataType|, e.g: + // float - DT_FLOAT32, + // int32_t - DT_INT32, ... + template + int32_t AddKeyframes(DataType data_type, uint32_t num_components, + const std::vector &data); + + const PointAttribute *timestamps() const { + return GetAttributeByUniqueId(kTimestampId); + } + const PointAttribute *keyframes(int32_t animation_id) const { + return GetAttributeByUniqueId(animation_id); + } + + // Number of frames should be equal to number points in the point cloud. + void set_num_frames(int32_t num_frames) { set_num_points(num_frames); } + int32_t num_frames() const { return static_cast(num_points()); } + + int32_t num_animations() const { return num_attributes() - 1; } + + private: + // Attribute id of timestamp is fixed to 0. + static constexpr int32_t kTimestampId = 0; +}; + +template +int32_t KeyframeAnimation::AddKeyframes(DataType data_type, + uint32_t num_components, + const std::vector &data) { + // TODO(draco-eng): Verify T is consistent with |data_type|. + if (num_components == 0) { + return -1; + } + // If timestamps is not added yet, then reserve attribute 0 for timestamps. + if (!num_attributes()) { + // Add a temporary attribute with 0 points to fill attribute id 0. + std::unique_ptr temp_att = + std::unique_ptr(new PointAttribute()); + temp_att->Init(GeometryAttribute::GENERIC, num_components, data_type, false, + 0); + this->AddAttribute(std::move(temp_att)); + + set_num_frames(data.size() / num_components); + } + + if (data.size() != num_components * num_frames()) { + return -1; + } + + std::unique_ptr keyframe_att = + std::unique_ptr(new PointAttribute()); + keyframe_att->Init(GeometryAttribute::GENERIC, num_components, data_type, + false, num_frames()); + const size_t stride = num_components; + for (PointIndex i(0); i < num_frames(); ++i) { + keyframe_att->SetAttributeValue(keyframe_att->mapped_index(i), + &data[i.value() * stride]); + } + return this->AddAttribute(std::move(keyframe_att)); +} + +} // namespace draco + +#endif // DRACO_ANIMATION_KEYFRAME_ANIMATION_H_ diff --git a/third-party/draco/src/draco/animation/keyframe_animation_decoder.cc b/third-party/draco/src/draco/animation/keyframe_animation_decoder.cc new file mode 100644 index 0000000000..20659468d9 --- /dev/null +++ b/third-party/draco/src/draco/animation/keyframe_animation_decoder.cc @@ -0,0 +1,30 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/animation/keyframe_animation_decoder.h" + +namespace draco { + +Status KeyframeAnimationDecoder::Decode(const DecoderOptions &options, + DecoderBuffer *in_buffer, + KeyframeAnimation *animation) { + const auto status = PointCloudSequentialDecoder::Decode( + options, in_buffer, static_cast(animation)); + if (!status.ok()) { + return status; + } + return OkStatus(); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/animation/keyframe_animation_decoder.h b/third-party/draco/src/draco/animation/keyframe_animation_decoder.h new file mode 100644 index 0000000000..fdf086b3a3 --- /dev/null +++ b/third-party/draco/src/draco/animation/keyframe_animation_decoder.h @@ -0,0 +1,34 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ANIMATION_KEYFRAME_ANIMATION_DECODER_H_ +#define DRACO_ANIMATION_KEYFRAME_ANIMATION_DECODER_H_ + +#include "draco/animation/keyframe_animation.h" +#include "draco/compression/point_cloud/point_cloud_sequential_decoder.h" + +namespace draco { + +// Class for decoding keyframe animation. +class KeyframeAnimationDecoder : private PointCloudSequentialDecoder { + public: + KeyframeAnimationDecoder(){}; + + Status Decode(const DecoderOptions &options, DecoderBuffer *in_buffer, + KeyframeAnimation *animation); +}; + +} // namespace draco + +#endif // DRACO_ANIMATION_KEYFRAME_ANIMATION_DECODER_H_ diff --git a/third-party/draco/src/draco/animation/keyframe_animation_encoder.cc b/third-party/draco/src/draco/animation/keyframe_animation_encoder.cc new file mode 100644 index 0000000000..f7d84f3106 --- /dev/null +++ b/third-party/draco/src/draco/animation/keyframe_animation_encoder.cc @@ -0,0 +1,28 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/animation/keyframe_animation_encoder.h" + +namespace draco { + +KeyframeAnimationEncoder::KeyframeAnimationEncoder() {} + +Status KeyframeAnimationEncoder::EncodeKeyframeAnimation( + const KeyframeAnimation &animation, const EncoderOptions &options, + EncoderBuffer *out_buffer) { + SetPointCloud(animation); + return Encode(options, out_buffer); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/animation/keyframe_animation_encoder.h b/third-party/draco/src/draco/animation/keyframe_animation_encoder.h new file mode 100644 index 0000000000..6096c79fa1 --- /dev/null +++ b/third-party/draco/src/draco/animation/keyframe_animation_encoder.h @@ -0,0 +1,39 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ANIMATION_KEYFRAME_ANIMATION_ENCODER_H_ +#define DRACO_ANIMATION_KEYFRAME_ANIMATION_ENCODER_H_ + +#include "draco/animation/keyframe_animation.h" +#include "draco/compression/point_cloud/point_cloud_sequential_encoder.h" + +namespace draco { + +// Class for encoding keyframe animation. It takes KeyframeAnimation as a +// PointCloud and compress it. It's mostly a wrapper around PointCloudEncoder so +// that the animation module could be separated from geometry compression when +// exposed to developers. +class KeyframeAnimationEncoder : private PointCloudSequentialEncoder { + public: + KeyframeAnimationEncoder(); + + // Encode an animation to a buffer. + Status EncodeKeyframeAnimation(const KeyframeAnimation &animation, + const EncoderOptions &options, + EncoderBuffer *out_buffer); +}; + +} // namespace draco + +#endif // DRACO_ANIMATION_KEYFRAME_ANIMATION_ENCODER_H_ diff --git a/third-party/draco/src/draco/animation/keyframe_animation_encoding_test.cc b/third-party/draco/src/draco/animation/keyframe_animation_encoding_test.cc new file mode 100644 index 0000000000..fcd0eaa6f5 --- /dev/null +++ b/third-party/draco/src/draco/animation/keyframe_animation_encoding_test.cc @@ -0,0 +1,169 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/animation/keyframe_animation.h" +#include "draco/animation/keyframe_animation_decoder.h" +#include "draco/animation/keyframe_animation_encoder.h" +#include "draco/core/draco_test_base.h" +#include "draco/core/draco_test_utils.h" + +namespace draco { + +class KeyframeAnimationEncodingTest : public ::testing::Test { + protected: + KeyframeAnimationEncodingTest() {} + + bool CreateAndAddTimestamps(int32_t num_frames) { + timestamps_.resize(num_frames); + for (int i = 0; i < timestamps_.size(); ++i) { + timestamps_[i] = static_cast(i); + } + return keyframe_animation_.SetTimestamps(timestamps_); + } + + int32_t CreateAndAddAnimationData(int32_t num_frames, + uint32_t num_components) { + // Create and add animation data with. + animation_data_.resize(num_frames * num_components); + for (int i = 0; i < animation_data_.size(); ++i) { + animation_data_[i] = static_cast(i); + } + return keyframe_animation_.AddKeyframes(draco::DT_FLOAT32, num_components, + animation_data_); + } + + template + void CompareAnimationData(const KeyframeAnimation &animation0, + const KeyframeAnimation &animation1, + bool quantized) { + ASSERT_EQ(animation0.num_frames(), animation1.num_frames()); + ASSERT_EQ(animation0.num_animations(), animation1.num_animations()); + + if (quantized) { + // TODO(b/199760123) : Add test for stable quantization. + // Quantization will result in slightly different values. + // Skip comparing values. + return; + } + + // Compare time stamp. + const auto timestamp_att0 = animation0.timestamps(); + const auto timestamp_att1 = animation0.timestamps(); + for (int i = 0; i < animation0.num_frames(); ++i) { + std::array att_value0; + std::array att_value1; + ASSERT_TRUE((timestamp_att0->GetValue( + draco::AttributeValueIndex(i), &att_value0))); + ASSERT_TRUE((timestamp_att1->GetValue( + draco::AttributeValueIndex(i), &att_value1))); + ASSERT_FLOAT_EQ(att_value0[0], att_value1[0]); + } + + for (int animation_id = 1; animation_id < animation0.num_animations(); + ++animation_id) { + // Compare keyframe data. + const auto keyframe_att0 = animation0.keyframes(animation_id); + const auto keyframe_att1 = animation1.keyframes(animation_id); + ASSERT_EQ(keyframe_att0->num_components(), + keyframe_att1->num_components()); + for (int i = 0; i < animation0.num_frames(); ++i) { + std::array att_value0; + std::array att_value1; + ASSERT_TRUE((keyframe_att0->GetValue( + draco::AttributeValueIndex(i), &att_value0))); + ASSERT_TRUE((keyframe_att1->GetValue( + draco::AttributeValueIndex(i), &att_value1))); + for (int j = 0; j < att_value0.size(); ++j) { + ASSERT_FLOAT_EQ(att_value0[j], att_value1[j]); + } + } + } + } + + template + void TestKeyframeAnimationEncoding() { + TestKeyframeAnimationEncoding(false); + } + + template + void TestKeyframeAnimationEncoding(bool quantized) { + // Encode animation class. + draco::EncoderBuffer buffer; + draco::KeyframeAnimationEncoder encoder; + EncoderOptions options = EncoderOptions::CreateDefaultOptions(); + if (quantized) { + // Set quantization for timestamps. + options.SetAttributeInt(0, "quantization_bits", 20); + // Set quantization for keyframes. + for (int i = 1; i <= keyframe_animation_.num_animations(); ++i) { + options.SetAttributeInt(i, "quantization_bits", 20); + } + } + + DRACO_ASSERT_OK( + encoder.EncodeKeyframeAnimation(keyframe_animation_, options, &buffer)); + + draco::DecoderBuffer dec_decoder; + draco::KeyframeAnimationDecoder decoder; + DecoderBuffer dec_buffer; + dec_buffer.Init(buffer.data(), buffer.size()); + + // Decode animation class. + std::unique_ptr decoded_animation( + new KeyframeAnimation()); + DecoderOptions dec_options; + DRACO_ASSERT_OK( + decoder.Decode(dec_options, &dec_buffer, decoded_animation.get())); + + // Verify if animation before and after compression is identical. + CompareAnimationData(keyframe_animation_, + *decoded_animation, quantized); + } + + draco::KeyframeAnimation keyframe_animation_; + std::vector timestamps_; + std::vector animation_data_; +}; + +TEST_F(KeyframeAnimationEncodingTest, OneComponent) { + const int num_frames = 1; + ASSERT_TRUE(CreateAndAddTimestamps(num_frames)); + ASSERT_EQ(CreateAndAddAnimationData(num_frames, 1), 1); + TestKeyframeAnimationEncoding<1>(); +} + +TEST_F(KeyframeAnimationEncodingTest, ManyComponents) { + const int num_frames = 100; + ASSERT_TRUE(CreateAndAddTimestamps(num_frames)); + ASSERT_EQ(CreateAndAddAnimationData(num_frames, 100), 1); + TestKeyframeAnimationEncoding<100>(); +} + +TEST_F(KeyframeAnimationEncodingTest, ManyComponentsWithQuantization) { + const int num_frames = 100; + ASSERT_TRUE(CreateAndAddTimestamps(num_frames)); + ASSERT_EQ(CreateAndAddAnimationData(num_frames, 4), 1); + // Test compression with quantization. + TestKeyframeAnimationEncoding<4>(true); +} + +TEST_F(KeyframeAnimationEncodingTest, MultipleAnimations) { + const int num_frames = 5; + ASSERT_TRUE(CreateAndAddTimestamps(num_frames)); + ASSERT_EQ(CreateAndAddAnimationData(num_frames, 3), 1); + ASSERT_EQ(CreateAndAddAnimationData(num_frames, 3), 2); + TestKeyframeAnimationEncoding<3>(); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/animation/keyframe_animation_test.cc b/third-party/draco/src/draco/animation/keyframe_animation_test.cc new file mode 100644 index 0000000000..94566972bf --- /dev/null +++ b/third-party/draco/src/draco/animation/keyframe_animation_test.cc @@ -0,0 +1,104 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/animation/keyframe_animation.h" + +#include "draco/core/draco_test_base.h" + +namespace { + +class KeyframeAnimationTest : public ::testing::Test { + protected: + KeyframeAnimationTest() {} + + bool CreateAndAddTimestamps(int32_t num_frames) { + timestamps_.resize(num_frames); + for (int i = 0; i < timestamps_.size(); ++i) { + timestamps_[i] = static_cast(i); + } + return keyframe_animation_.SetTimestamps(timestamps_); + } + + int32_t CreateAndAddAnimationData(int32_t num_frames, + uint32_t num_components) { + // Create and add animation data with. + animation_data_.resize(num_frames * num_components); + for (int i = 0; i < animation_data_.size(); ++i) { + animation_data_[i] = static_cast(i); + } + return keyframe_animation_.AddKeyframes(draco::DT_FLOAT32, num_components, + animation_data_); + } + + template + void CompareAnimationData() { + // Compare time stamp. + const auto timestamp_att = keyframe_animation_.timestamps(); + for (int i = 0; i < timestamps_.size(); ++i) { + std::array att_value; + ASSERT_TRUE((timestamp_att->GetValue( + draco::AttributeValueIndex(i), &att_value))); + ASSERT_FLOAT_EQ(att_value[0], i); + } + + // Compare keyframe data. + const auto keyframe_att = keyframe_animation_.keyframes(1); + for (int i = 0; i < animation_data_.size() / num_components_t; ++i) { + std::array att_value; + ASSERT_TRUE((keyframe_att->GetValue( + draco::AttributeValueIndex(i), &att_value))); + for (int j = 0; j < num_components_t; ++j) { + ASSERT_FLOAT_EQ(att_value[j], i * num_components_t + j); + } + } + } + + template + void TestKeyframeAnimation(int32_t num_frames) { + ASSERT_TRUE(CreateAndAddTimestamps(num_frames)); + ASSERT_EQ(CreateAndAddAnimationData(num_frames, num_components_t), 1); + CompareAnimationData(); + } + + draco::KeyframeAnimation keyframe_animation_; + std::vector timestamps_; + std::vector animation_data_; +}; + +// Test animation with 1 component and 10 frames. +TEST_F(KeyframeAnimationTest, OneComponent) { TestKeyframeAnimation<1>(10); } + +// Test animation with 4 component and 10 frames. +TEST_F(KeyframeAnimationTest, FourComponent) { TestKeyframeAnimation<4>(10); } + +// Test adding animation data before timestamp. +TEST_F(KeyframeAnimationTest, AddingAnimationFirst) { + ASSERT_EQ(CreateAndAddAnimationData(5, 1), 1); + ASSERT_TRUE(CreateAndAddTimestamps(5)); +} + +// Test adding timestamp more than once. +TEST_F(KeyframeAnimationTest, ErrorAddingTimestampsTwice) { + ASSERT_TRUE(CreateAndAddTimestamps(5)); + ASSERT_FALSE(CreateAndAddTimestamps(5)); +} +// Test animation with multiple animation data. +TEST_F(KeyframeAnimationTest, MultipleAnimationData) { + const int num_frames = 5; + ASSERT_TRUE(CreateAndAddTimestamps(num_frames)); + ASSERT_EQ(CreateAndAddAnimationData(num_frames, 1), 1); + ASSERT_EQ(CreateAndAddAnimationData(num_frames, 2), 2); +} + +} // namespace diff --git a/third-party/draco/src/draco/animation/node_animation_data.h b/third-party/draco/src/draco/animation/node_animation_data.h new file mode 100644 index 0000000000..7799e33768 --- /dev/null +++ b/third-party/draco/src/draco/animation/node_animation_data.h @@ -0,0 +1,150 @@ +// Copyright 2019 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ANIMATION_NODE_ANIMATION_DATA_H_ +#define DRACO_ANIMATION_NODE_ANIMATION_DATA_H_ + +#include "draco/draco_features.h" + +#ifdef DRACO_TRANSCODER_SUPPORTED + +#include "draco/core/hash_utils.h" +#include "draco/core/status.h" +#include "draco/core/status_or.h" + +namespace draco { + +// This class is used to store information and data for animations that only +// affect the nodes. +// TODO(fgalligan): Think about changing the name of this class now that Skin +// is using it. +class NodeAnimationData { + public: + enum class Type { SCALAR, VEC3, VEC4, MAT4 }; + + NodeAnimationData() : type_(Type::SCALAR), count_(0), normalized_(false) {} + + void Copy(const NodeAnimationData &src) { + type_ = src.type_; + count_ = src.count_; + normalized_ = src.normalized_; + data_ = src.data_; + } + + Type type() const { return type_; } + int count() const { return count_; } + bool normalized() const { return normalized_; } + + std::vector *GetMutableData() { return &data_; } + const std::vector *GetData() const { return &data_; } + + void SetType(Type type) { type_ = type; } + void SetCount(int count) { count_ = count; } + void SetNormalized(bool normalized) { normalized_ = normalized; } + + int ComponentSize() const { return sizeof(float); } + int NumComponents() const { + switch (type_) { + case Type::SCALAR: + return 1; + case Type::VEC3: + return 3; + case Type::MAT4: + return 16; + default: + return 4; + } + } + + std::string TypeAsString() const { + switch (type_) { + case Type::SCALAR: + return "SCALAR"; + case Type::VEC3: + return "VEC3"; + case Type::MAT4: + return "MAT4"; + default: + return "VEC4"; + } + } + + bool operator==(const NodeAnimationData &nad) const { + return type_ == nad.type_ && count_ == nad.count_ && + normalized_ == nad.normalized_ && data_ == nad.data_; + } + + private: + Type type_; + int count_; + bool normalized_; + std::vector data_; +}; + +// Wrapper class for hashing NodeAnimationData. When using different containers, +// this class is preferable instead of copying the data in NodeAnimationData +// every time. +class NodeAnimationDataHash { + public: + NodeAnimationDataHash() = delete; + NodeAnimationDataHash &operator=(const NodeAnimationDataHash &) = delete; + NodeAnimationDataHash(NodeAnimationDataHash &&) = delete; + NodeAnimationDataHash &operator=(NodeAnimationDataHash &&) = delete; + + explicit NodeAnimationDataHash(const NodeAnimationData *nad) + : node_animation_data_(nad) { + hash_ = NodeAnimationDataHash::HashNodeAnimationData(*node_animation_data_); + } + + NodeAnimationDataHash(const NodeAnimationDataHash &nadh) { + node_animation_data_ = nadh.node_animation_data_; + hash_ = nadh.hash_; + } + + bool operator==(const NodeAnimationDataHash &nadh) const { + return *node_animation_data_ == *nadh.node_animation_data_; + } + + struct Hash { + size_t operator()(const NodeAnimationDataHash &nadh) const { + return nadh.hash_; + } + }; + + const NodeAnimationData *GetNodeAnimationData() { + return node_animation_data_; + } + + private: + // Returns a hash of |nad|. + static size_t HashNodeAnimationData(const NodeAnimationData &nad) { + size_t hash = 79; // Magic number. + hash = HashCombine(static_cast(nad.type()), hash); + hash = HashCombine(nad.count(), hash); + hash = HashCombine(nad.normalized(), hash); + const uint64_t data_hash = + FingerprintString(reinterpret_cast(nad.GetData()->data()), + nad.GetData()->size() * sizeof(float)); + hash = HashCombine(data_hash, hash); + return hash; + } + + const NodeAnimationData *node_animation_data_; + size_t hash_; +}; + +} // namespace draco + +#endif // DRACO_TRANSCODER_SUPPORTED +#endif // DRACO_ANIMATION_NODE_ANIMATION_DATA_H_ diff --git a/third-party/draco/src/draco/animation/skin.cc b/third-party/draco/src/draco/animation/skin.cc new file mode 100644 index 0000000000..f232978c23 --- /dev/null +++ b/third-party/draco/src/draco/animation/skin.cc @@ -0,0 +1,29 @@ +// Copyright 2019 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/animation/skin.h" + +#ifdef DRACO_TRANSCODER_SUPPORTED + +namespace draco { + +void Skin::Copy(const Skin &s) { + inverse_bind_matrices_.Copy(s.GetInverseBindMatrices()); + joints_ = s.GetJoints(); + joint_root_index_ = s.GetJointRoot(); +} + +} // namespace draco + +#endif // DRACO_TRANSCODER_SUPPORTED diff --git a/third-party/draco/src/draco/animation/skin.h b/third-party/draco/src/draco/animation/skin.h new file mode 100644 index 0000000000..81ca997eb4 --- /dev/null +++ b/third-party/draco/src/draco/animation/skin.h @@ -0,0 +1,64 @@ +// Copyright 2019 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ANIMATION_SKIN_H_ +#define DRACO_ANIMATION_SKIN_H_ + +#include "draco/draco_features.h" + +#ifdef DRACO_TRANSCODER_SUPPORTED + +#include + +#include "draco/animation/node_animation_data.h" +#include "draco/scene/scene_indices.h" + +namespace draco { + +// This class is used to store information on animation skins. +class Skin { + public: + Skin() : joint_root_index_(-1) {} + + void Copy(const Skin &s); + + NodeAnimationData &GetInverseBindMatrices() { return inverse_bind_matrices_; } + const NodeAnimationData &GetInverseBindMatrices() const { + return inverse_bind_matrices_; + } + + int AddJoint(SceneNodeIndex index) { + joints_.push_back(index); + return joints_.size() - 1; + } + int NumJoints() const { return joints_.size(); } + SceneNodeIndex GetJoint(int index) const { return joints_[index]; } + SceneNodeIndex &GetJoint(int index) { return joints_[index]; } + const std::vector &GetJoints() const { return joints_; } + + void SetJointRoot(SceneNodeIndex index) { joint_root_index_ = index; } + SceneNodeIndex GetJointRoot() const { return joint_root_index_; } + + private: + NodeAnimationData inverse_bind_matrices_; + + // List of node indices that make up the joint hierarchy. + std::vector joints_; + SceneNodeIndex joint_root_index_; +}; + +} // namespace draco + +#endif // DRACO_TRANSCODER_SUPPORTED +#endif // DRACO_ANIMATION_SKIN_H_ diff --git a/third-party/draco/src/draco/attributes/attribute_octahedron_transform.cc b/third-party/draco/src/draco/attributes/attribute_octahedron_transform.cc new file mode 100644 index 0000000000..51c3bb6c87 --- /dev/null +++ b/third-party/draco/src/draco/attributes/attribute_octahedron_transform.cc @@ -0,0 +1,145 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "draco/attributes/attribute_octahedron_transform.h" + +#include "draco/attributes/attribute_transform_type.h" +#include "draco/compression/attributes/normal_compression_utils.h" + +namespace draco { + +bool AttributeOctahedronTransform::InitFromAttribute( + const PointAttribute &attribute) { + const AttributeTransformData *const transform_data = + attribute.GetAttributeTransformData(); + if (!transform_data || + transform_data->transform_type() != ATTRIBUTE_OCTAHEDRON_TRANSFORM) { + return false; // Wrong transform type. + } + quantization_bits_ = transform_data->GetParameterValue(0); + return true; +} + +void AttributeOctahedronTransform::CopyToAttributeTransformData( + AttributeTransformData *out_data) const { + out_data->set_transform_type(ATTRIBUTE_OCTAHEDRON_TRANSFORM); + out_data->AppendParameterValue(quantization_bits_); +} + +bool AttributeOctahedronTransform::TransformAttribute( + const PointAttribute &attribute, const std::vector &point_ids, + PointAttribute *target_attribute) { + return GeneratePortableAttribute(attribute, point_ids, + target_attribute->size(), target_attribute); +} + +bool AttributeOctahedronTransform::InverseTransformAttribute( + const PointAttribute &attribute, PointAttribute *target_attribute) { + if (target_attribute->data_type() != DT_FLOAT32) { + return false; + } + + const int num_points = target_attribute->size(); + const int num_components = target_attribute->num_components(); + if (num_components != 3) { + return false; + } + constexpr int kEntrySize = sizeof(float) * 3; + float att_val[3]; + const int32_t *source_attribute_data = reinterpret_cast( + attribute.GetAddress(AttributeValueIndex(0))); + uint8_t *target_address = + target_attribute->GetAddress(AttributeValueIndex(0)); + OctahedronToolBox octahedron_tool_box; + if (!octahedron_tool_box.SetQuantizationBits(quantization_bits_)) { + return false; + } + for (uint32_t i = 0; i < num_points; ++i) { + const int32_t s = *source_attribute_data++; + const int32_t t = *source_attribute_data++; + octahedron_tool_box.QuantizedOctahedralCoordsToUnitVector(s, t, att_val); + + // Store the decoded floating point values into the attribute buffer. + std::memcpy(target_address, att_val, kEntrySize); + target_address += kEntrySize; + } + return true; +} + +void AttributeOctahedronTransform::SetParameters(int quantization_bits) { + quantization_bits_ = quantization_bits; +} + +bool AttributeOctahedronTransform::EncodeParameters( + EncoderBuffer *encoder_buffer) const { + if (is_initialized()) { + encoder_buffer->Encode(static_cast(quantization_bits_)); + return true; + } + return false; +} + +bool AttributeOctahedronTransform::DecodeParameters( + const PointAttribute &attribute, DecoderBuffer *decoder_buffer) { + uint8_t quantization_bits; + if (!decoder_buffer->Decode(&quantization_bits)) { + return false; + } + quantization_bits_ = quantization_bits; + return true; +} + +bool AttributeOctahedronTransform::GeneratePortableAttribute( + const PointAttribute &attribute, const std::vector &point_ids, + int num_points, PointAttribute *target_attribute) const { + DRACO_DCHECK(is_initialized()); + + // Quantize all values in the order given by point_ids into portable + // attribute. + int32_t *const portable_attribute_data = reinterpret_cast( + target_attribute->GetAddress(AttributeValueIndex(0))); + float att_val[3]; + int32_t dst_index = 0; + OctahedronToolBox converter; + if (!converter.SetQuantizationBits(quantization_bits_)) { + return false; + } + if (!point_ids.empty()) { + for (uint32_t i = 0; i < point_ids.size(); ++i) { + const AttributeValueIndex att_val_id = + attribute.mapped_index(point_ids[i]); + attribute.GetValue(att_val_id, att_val); + // Encode the vector into a s and t octahedral coordinates. + int32_t s, t; + converter.FloatVectorToQuantizedOctahedralCoords(att_val, &s, &t); + portable_attribute_data[dst_index++] = s; + portable_attribute_data[dst_index++] = t; + } + } else { + for (PointIndex i(0); i < num_points; ++i) { + const AttributeValueIndex att_val_id = attribute.mapped_index(i); + attribute.GetValue(att_val_id, att_val); + // Encode the vector into a s and t octahedral coordinates. + int32_t s, t; + converter.FloatVectorToQuantizedOctahedralCoords(att_val, &s, &t); + portable_attribute_data[dst_index++] = s; + portable_attribute_data[dst_index++] = t; + } + } + + return true; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/attributes/attribute_octahedron_transform.h b/third-party/draco/src/draco/attributes/attribute_octahedron_transform.h new file mode 100644 index 0000000000..21a1725bb5 --- /dev/null +++ b/third-party/draco/src/draco/attributes/attribute_octahedron_transform.h @@ -0,0 +1,81 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef DRACO_ATTRIBUTES_ATTRIBUTE_OCTAHEDRON_TRANSFORM_H_ +#define DRACO_ATTRIBUTES_ATTRIBUTE_OCTAHEDRON_TRANSFORM_H_ + +#include "draco/attributes/attribute_transform.h" +#include "draco/attributes/point_attribute.h" +#include "draco/core/encoder_buffer.h" + +namespace draco { + +// Attribute transform for attributes transformed to octahedral coordinates. +class AttributeOctahedronTransform : public AttributeTransform { + public: + AttributeOctahedronTransform() : quantization_bits_(-1) {} + + // Return attribute transform type. + AttributeTransformType Type() const override { + return ATTRIBUTE_OCTAHEDRON_TRANSFORM; + } + // Try to init transform from attribute. + bool InitFromAttribute(const PointAttribute &attribute) override; + // Copy parameter values into the provided AttributeTransformData instance. + void CopyToAttributeTransformData( + AttributeTransformData *out_data) const override; + + bool TransformAttribute(const PointAttribute &attribute, + const std::vector &point_ids, + PointAttribute *target_attribute) override; + + bool InverseTransformAttribute(const PointAttribute &attribute, + PointAttribute *target_attribute) override; + + // Set number of quantization bits. + void SetParameters(int quantization_bits); + + // Encode relevant parameters into buffer. + bool EncodeParameters(EncoderBuffer *encoder_buffer) const override; + + bool DecodeParameters(const PointAttribute &attribute, + DecoderBuffer *decoder_buffer) override; + + bool is_initialized() const { return quantization_bits_ != -1; } + int32_t quantization_bits() const { return quantization_bits_; } + + protected: + DataType GetTransformedDataType( + const PointAttribute &attribute) const override { + return DT_UINT32; + } + int GetTransformedNumComponents( + const PointAttribute &attribute) const override { + return 2; + } + + // Perform the actual transformation. + bool GeneratePortableAttribute(const PointAttribute &attribute, + const std::vector &point_ids, + int num_points, + PointAttribute *target_attribute) const; + + private: + int32_t quantization_bits_; +}; + +} // namespace draco + +#endif // DRACO_ATTRIBUTES_ATTRIBUTE_OCTAHEDRON_TRANSFORM_H_ diff --git a/third-party/draco/src/draco/attributes/attribute_quantization_transform.cc b/third-party/draco/src/draco/attributes/attribute_quantization_transform.cc new file mode 100644 index 0000000000..667e344312 --- /dev/null +++ b/third-party/draco/src/draco/attributes/attribute_quantization_transform.cc @@ -0,0 +1,268 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/attributes/attribute_quantization_transform.h" + +#include +#include +#include +#include + +#include "draco/attributes/attribute_transform_type.h" +#include "draco/core/quantization_utils.h" + +namespace draco { + +bool AttributeQuantizationTransform::InitFromAttribute( + const PointAttribute &attribute) { + const AttributeTransformData *const transform_data = + attribute.GetAttributeTransformData(); + if (!transform_data || + transform_data->transform_type() != ATTRIBUTE_QUANTIZATION_TRANSFORM) { + return false; // Wrong transform type. + } + int32_t byte_offset = 0; + quantization_bits_ = transform_data->GetParameterValue(byte_offset); + byte_offset += 4; + min_values_.resize(attribute.num_components()); + for (int i = 0; i < attribute.num_components(); ++i) { + min_values_[i] = transform_data->GetParameterValue(byte_offset); + byte_offset += 4; + } + range_ = transform_data->GetParameterValue(byte_offset); + return true; +} + +// Copy parameter values into the provided AttributeTransformData instance. +void AttributeQuantizationTransform::CopyToAttributeTransformData( + AttributeTransformData *out_data) const { + out_data->set_transform_type(ATTRIBUTE_QUANTIZATION_TRANSFORM); + out_data->AppendParameterValue(quantization_bits_); + for (int i = 0; i < min_values_.size(); ++i) { + out_data->AppendParameterValue(min_values_[i]); + } + out_data->AppendParameterValue(range_); +} + +bool AttributeQuantizationTransform::TransformAttribute( + const PointAttribute &attribute, const std::vector &point_ids, + PointAttribute *target_attribute) { + if (point_ids.empty()) { + GeneratePortableAttribute(attribute, target_attribute->size(), + target_attribute); + } else { + GeneratePortableAttribute(attribute, point_ids, target_attribute->size(), + target_attribute); + } + return true; +} + +bool AttributeQuantizationTransform::InverseTransformAttribute( + const PointAttribute &attribute, PointAttribute *target_attribute) { + if (target_attribute->data_type() != DT_FLOAT32) { + return false; + } + + // Convert all quantized values back to floats. + const int32_t max_quantized_value = + (1u << static_cast(quantization_bits_)) - 1; + const int num_components = target_attribute->num_components(); + const int entry_size = sizeof(float) * num_components; + const std::unique_ptr att_val(new float[num_components]); + int quant_val_id = 0; + int out_byte_pos = 0; + Dequantizer dequantizer; + if (!dequantizer.Init(range_, max_quantized_value)) { + return false; + } + const int32_t *const source_attribute_data = + reinterpret_cast( + attribute.GetAddress(AttributeValueIndex(0))); + + const int num_values = target_attribute->size(); + + for (uint32_t i = 0; i < num_values; ++i) { + for (int c = 0; c < num_components; ++c) { + float value = + dequantizer.DequantizeFloat(source_attribute_data[quant_val_id++]); + value = value + min_values_[c]; + att_val[c] = value; + } + // Store the floating point value into the attribute buffer. + target_attribute->buffer()->Write(out_byte_pos, att_val.get(), entry_size); + out_byte_pos += entry_size; + } + return true; +} + +bool AttributeQuantizationTransform::IsQuantizationValid( + int quantization_bits) { + // Currently we allow only up to 30 bit quantization. + return quantization_bits >= 1 && quantization_bits <= 30; +} + +bool AttributeQuantizationTransform::SetParameters(int quantization_bits, + const float *min_values, + int num_components, + float range) { + if (!IsQuantizationValid(quantization_bits)) { + return false; + } + quantization_bits_ = quantization_bits; + min_values_.assign(min_values, min_values + num_components); + range_ = range; + return true; +} + +bool AttributeQuantizationTransform::ComputeParameters( + const PointAttribute &attribute, const int quantization_bits) { + if (quantization_bits_ != -1) { + return false; // already initialized. + } + if (!IsQuantizationValid(quantization_bits)) { + return false; + } + quantization_bits_ = quantization_bits; + + const int num_components = attribute.num_components(); + range_ = 0.f; + min_values_ = std::vector(num_components, 0.f); + const std::unique_ptr max_values(new float[num_components]); + const std::unique_ptr att_val(new float[num_components]); + // Compute minimum values and max value difference. + attribute.GetValue(AttributeValueIndex(0), att_val.get()); + attribute.GetValue(AttributeValueIndex(0), min_values_.data()); + attribute.GetValue(AttributeValueIndex(0), max_values.get()); + + for (AttributeValueIndex i(1); i < static_cast(attribute.size()); + ++i) { + attribute.GetValue(i, att_val.get()); + for (int c = 0; c < num_components; ++c) { + if (std::isnan(att_val[c])) { + return false; + } + if (min_values_[c] > att_val[c]) { + min_values_[c] = att_val[c]; + } + if (max_values[c] < att_val[c]) { + max_values[c] = att_val[c]; + } + } + } + for (int c = 0; c < num_components; ++c) { + if (std::isnan(min_values_[c]) || std::isinf(min_values_[c]) || + std::isnan(max_values[c]) || std::isinf(max_values[c])) { + return false; + } + const float dif = max_values[c] - min_values_[c]; + if (dif > range_) { + range_ = dif; + } + } + + // In case all values are the same, initialize the range to unit length. This + // will ensure that all values are quantized properly to the same value. + if (range_ == 0.f) { + range_ = 1.f; + } + + return true; +} + +bool AttributeQuantizationTransform::EncodeParameters( + EncoderBuffer *encoder_buffer) const { + if (is_initialized()) { + encoder_buffer->Encode(min_values_.data(), + sizeof(float) * min_values_.size()); + encoder_buffer->Encode(range_); + encoder_buffer->Encode(static_cast(quantization_bits_)); + return true; + } + return false; +} + +bool AttributeQuantizationTransform::DecodeParameters( + const PointAttribute &attribute, DecoderBuffer *decoder_buffer) { + min_values_.resize(attribute.num_components()); + if (!decoder_buffer->Decode(&min_values_[0], + sizeof(float) * min_values_.size())) { + return false; + } + if (!decoder_buffer->Decode(&range_)) { + return false; + } + uint8_t quantization_bits; + if (!decoder_buffer->Decode(&quantization_bits)) { + return false; + } + if (!IsQuantizationValid(quantization_bits)) { + return false; + } + quantization_bits_ = quantization_bits; + return true; +} + +void AttributeQuantizationTransform::GeneratePortableAttribute( + const PointAttribute &attribute, int num_points, + PointAttribute *target_attribute) const { + DRACO_DCHECK(is_initialized()); + + const int num_components = attribute.num_components(); + + // Quantize all values using the order given by point_ids. + int32_t *const portable_attribute_data = reinterpret_cast( + target_attribute->GetAddress(AttributeValueIndex(0))); + const uint32_t max_quantized_value = (1 << (quantization_bits_)) - 1; + Quantizer quantizer; + quantizer.Init(range(), max_quantized_value); + int32_t dst_index = 0; + const std::unique_ptr att_val(new float[num_components]); + for (PointIndex i(0); i < num_points; ++i) { + const AttributeValueIndex att_val_id = attribute.mapped_index(i); + attribute.GetValue(att_val_id, att_val.get()); + for (int c = 0; c < num_components; ++c) { + const float value = (att_val[c] - min_values()[c]); + const int32_t q_val = quantizer.QuantizeFloat(value); + portable_attribute_data[dst_index++] = q_val; + } + } +} + +void AttributeQuantizationTransform::GeneratePortableAttribute( + const PointAttribute &attribute, const std::vector &point_ids, + int num_points, PointAttribute *target_attribute) const { + DRACO_DCHECK(is_initialized()); + + const int num_components = attribute.num_components(); + + // Quantize all values using the order given by point_ids. + int32_t *const portable_attribute_data = reinterpret_cast( + target_attribute->GetAddress(AttributeValueIndex(0))); + const uint32_t max_quantized_value = (1 << (quantization_bits_)) - 1; + Quantizer quantizer; + quantizer.Init(range(), max_quantized_value); + int32_t dst_index = 0; + const std::unique_ptr att_val(new float[num_components]); + for (uint32_t i = 0; i < point_ids.size(); ++i) { + const AttributeValueIndex att_val_id = attribute.mapped_index(point_ids[i]); + attribute.GetValue(att_val_id, att_val.get()); + for (int c = 0; c < num_components; ++c) { + const float value = (att_val[c] - min_values()[c]); + const int32_t q_val = quantizer.QuantizeFloat(value); + portable_attribute_data[dst_index++] = q_val; + } + } +} + +} // namespace draco diff --git a/third-party/draco/src/draco/attributes/attribute_quantization_transform.h b/third-party/draco/src/draco/attributes/attribute_quantization_transform.h new file mode 100644 index 0000000000..f1122b680a --- /dev/null +++ b/third-party/draco/src/draco/attributes/attribute_quantization_transform.h @@ -0,0 +1,102 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ATTRIBUTES_ATTRIBUTE_QUANTIZATION_TRANSFORM_H_ +#define DRACO_ATTRIBUTES_ATTRIBUTE_QUANTIZATION_TRANSFORM_H_ + +#include + +#include "draco/attributes/attribute_transform.h" +#include "draco/attributes/point_attribute.h" +#include "draco/core/encoder_buffer.h" + +namespace draco { + +// Attribute transform for quantized attributes. +class AttributeQuantizationTransform : public AttributeTransform { + public: + AttributeQuantizationTransform() : quantization_bits_(-1), range_(0.f) {} + // Return attribute transform type. + AttributeTransformType Type() const override { + return ATTRIBUTE_QUANTIZATION_TRANSFORM; + } + // Try to init transform from attribute. + bool InitFromAttribute(const PointAttribute &attribute) override; + // Copy parameter values into the provided AttributeTransformData instance. + void CopyToAttributeTransformData( + AttributeTransformData *out_data) const override; + + bool TransformAttribute(const PointAttribute &attribute, + const std::vector &point_ids, + PointAttribute *target_attribute) override; + + bool InverseTransformAttribute(const PointAttribute &attribute, + PointAttribute *target_attribute) override; + + bool SetParameters(int quantization_bits, const float *min_values, + int num_components, float range); + + bool ComputeParameters(const PointAttribute &attribute, + const int quantization_bits); + + // Encode relevant parameters into buffer. + bool EncodeParameters(EncoderBuffer *encoder_buffer) const override; + + bool DecodeParameters(const PointAttribute &attribute, + DecoderBuffer *decoder_buffer) override; + + int32_t quantization_bits() const { return quantization_bits_; } + float min_value(int axis) const { return min_values_[axis]; } + const std::vector &min_values() const { return min_values_; } + float range() const { return range_; } + bool is_initialized() const { return quantization_bits_ != -1; } + + protected: + // Create portable attribute using 1:1 mapping between points in the input and + // output attribute. + void GeneratePortableAttribute(const PointAttribute &attribute, + int num_points, + PointAttribute *target_attribute) const; + + // Create portable attribute using custom mapping between input and output + // points. + void GeneratePortableAttribute(const PointAttribute &attribute, + const std::vector &point_ids, + int num_points, + PointAttribute *target_attribute) const; + + DataType GetTransformedDataType( + const PointAttribute &attribute) const override { + return DT_UINT32; + } + int GetTransformedNumComponents( + const PointAttribute &attribute) const override { + return attribute.num_components(); + } + + static bool IsQuantizationValid(int quantization_bits); + + private: + int32_t quantization_bits_; + + // Minimal dequantized value for each component of the attribute. + std::vector min_values_; + + // Bounds of the dequantized attribute (max delta over all components). + float range_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_ATTRIBUTE_DEQUANTIZATION_TRANSFORM_H_ diff --git a/third-party/draco/src/draco/attributes/attribute_transform.cc b/third-party/draco/src/draco/attributes/attribute_transform.cc new file mode 100644 index 0000000000..fb2ed18297 --- /dev/null +++ b/third-party/draco/src/draco/attributes/attribute_transform.cc @@ -0,0 +1,41 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/attributes/attribute_transform.h" + +namespace draco { + +bool AttributeTransform::TransferToAttribute(PointAttribute *attribute) const { + std::unique_ptr transform_data( + new AttributeTransformData()); + this->CopyToAttributeTransformData(transform_data.get()); + attribute->SetAttributeTransformData(std::move(transform_data)); + return true; +} + +std::unique_ptr AttributeTransform::InitTransformedAttribute( + const PointAttribute &src_attribute, int num_entries) { + const int num_components = GetTransformedNumComponents(src_attribute); + const DataType dt = GetTransformedDataType(src_attribute); + GeometryAttribute ga; + ga.Init(src_attribute.attribute_type(), nullptr, num_components, dt, false, + num_components * DataTypeLength(dt), 0); + std::unique_ptr transformed_attribute(new PointAttribute(ga)); + transformed_attribute->Reset(num_entries); + transformed_attribute->SetIdentityMapping(); + transformed_attribute->set_unique_id(src_attribute.unique_id()); + return transformed_attribute; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/attributes/attribute_transform.h b/third-party/draco/src/draco/attributes/attribute_transform.h new file mode 100644 index 0000000000..62aad60db9 --- /dev/null +++ b/third-party/draco/src/draco/attributes/attribute_transform.h @@ -0,0 +1,76 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ATTRIBUTES_ATTRIBUTE_TRANSFORM_H_ +#define DRACO_ATTRIBUTES_ATTRIBUTE_TRANSFORM_H_ + +#include "draco/attributes/attribute_transform_data.h" +#include "draco/attributes/point_attribute.h" +#include "draco/core/decoder_buffer.h" +#include "draco/core/encoder_buffer.h" + +namespace draco { + +// Virtual base class for various attribute transforms, enforcing common +// interface where possible. +class AttributeTransform { + public: + virtual ~AttributeTransform() = default; + + // Return attribute transform type. + virtual AttributeTransformType Type() const = 0; + // Try to init transform from attribute. + virtual bool InitFromAttribute(const PointAttribute &attribute) = 0; + // Copy parameter values into the provided AttributeTransformData instance. + virtual void CopyToAttributeTransformData( + AttributeTransformData *out_data) const = 0; + bool TransferToAttribute(PointAttribute *attribute) const; + + // Applies the transform to |attribute| and stores the result in + // |target_attribute|. |point_ids| is an optional vector that can be used to + // remap values during the transform. + virtual bool TransformAttribute(const PointAttribute &attribute, + const std::vector &point_ids, + PointAttribute *target_attribute) = 0; + + // Applies an inverse transform to |attribute| and stores the result in + // |target_attribute|. In this case, |attribute| is an attribute that was + // already transformed (e.g. quantized) and |target_attribute| is the + // attribute before the transformation. + virtual bool InverseTransformAttribute(const PointAttribute &attribute, + PointAttribute *target_attribute) = 0; + + // Encodes all data needed by the transformation into the |encoder_buffer|. + virtual bool EncodeParameters(EncoderBuffer *encoder_buffer) const = 0; + + // Decodes all data needed to transform |attribute| back to the original + // format. + virtual bool DecodeParameters(const PointAttribute &attribute, + DecoderBuffer *decoder_buffer) = 0; + + // Initializes a transformed attribute that can be used as target in the + // TransformAttribute() function call. + virtual std::unique_ptr InitTransformedAttribute( + const PointAttribute &src_attribute, int num_entries); + + protected: + virtual DataType GetTransformedDataType( + const PointAttribute &attribute) const = 0; + virtual int GetTransformedNumComponents( + const PointAttribute &attribute) const = 0; +}; + +} // namespace draco + +#endif // DRACO_ATTRIBUTES_ATTRIBUTE_OCTAHEDRON_TRANSFORM_H_ diff --git a/third-party/draco/src/draco/attributes/attribute_transform_data.h b/third-party/draco/src/draco/attributes/attribute_transform_data.h new file mode 100644 index 0000000000..96ed073200 --- /dev/null +++ b/third-party/draco/src/draco/attributes/attribute_transform_data.h @@ -0,0 +1,71 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ATTRIBUTES_ATTRIBUTE_TRANSFORM_DATA_H_ +#define DRACO_ATTRIBUTES_ATTRIBUTE_TRANSFORM_DATA_H_ + +#include + +#include "draco/attributes/attribute_transform_type.h" +#include "draco/core/data_buffer.h" + +namespace draco { + +// Class for holding parameter values for an attribute transform of a +// PointAttribute. This can be for example quantization data for an attribute +// that holds quantized values. This class provides only a basic storage for +// attribute transform parameters and it should be accessed only through wrapper +// classes for a specific transform (e.g. AttributeQuantizationTransform). +class AttributeTransformData { + public: + AttributeTransformData() : transform_type_(ATTRIBUTE_INVALID_TRANSFORM) {} + AttributeTransformData(const AttributeTransformData &data) = default; + + // Returns the type of the attribute transform that is described by the class. + AttributeTransformType transform_type() const { return transform_type_; } + void set_transform_type(AttributeTransformType type) { + transform_type_ = type; + } + + // Returns a parameter value on a given |byte_offset|. + template + DataTypeT GetParameterValue(int byte_offset) const { + DataTypeT out_data; + buffer_.Read(byte_offset, &out_data, sizeof(DataTypeT)); + return out_data; + } + + // Sets a parameter value on a given |byte_offset|. + template + void SetParameterValue(int byte_offset, const DataTypeT &in_data) { + if (byte_offset + sizeof(DataTypeT) > buffer_.data_size()) { + buffer_.Resize(byte_offset + sizeof(DataTypeT)); + } + buffer_.Write(byte_offset, &in_data, sizeof(DataTypeT)); + } + + // Sets a parameter value at the end of the |buffer_|. + template + void AppendParameterValue(const DataTypeT &in_data) { + SetParameterValue(static_cast(buffer_.data_size()), in_data); + } + + private: + AttributeTransformType transform_type_; + DataBuffer buffer_; +}; + +} // namespace draco + +#endif // DRACO_ATTRIBUTES_ATTRIBUTE_TRANSFORM_DATA_H_ diff --git a/third-party/draco/src/draco/attributes/attribute_transform_type.h b/third-party/draco/src/draco/attributes/attribute_transform_type.h new file mode 100644 index 0000000000..51ce6f333b --- /dev/null +++ b/third-party/draco/src/draco/attributes/attribute_transform_type.h @@ -0,0 +1,30 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ATTRIBUTES_ATTRIBUTE_TRANSFORM_TYPE_H_ +#define DRACO_ATTRIBUTES_ATTRIBUTE_TRANSFORM_TYPE_H_ + +namespace draco { + +// List of all currently supported attribute transforms. +enum AttributeTransformType { + ATTRIBUTE_INVALID_TRANSFORM = -1, + ATTRIBUTE_NO_TRANSFORM = 0, + ATTRIBUTE_QUANTIZATION_TRANSFORM = 1, + ATTRIBUTE_OCTAHEDRON_TRANSFORM = 2, +}; + +} // namespace draco + +#endif // DRACO_ATTRIBUTES_ATTRIBUTE_TRANSFORM_TYPE_H_ diff --git a/third-party/draco/src/draco/attributes/geometry_attribute.cc b/third-party/draco/src/draco/attributes/geometry_attribute.cc new file mode 100644 index 0000000000..dc5ea45b90 --- /dev/null +++ b/third-party/draco/src/draco/attributes/geometry_attribute.cc @@ -0,0 +1,110 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/attributes/geometry_attribute.h" + +namespace draco { + +GeometryAttribute::GeometryAttribute() + : buffer_(nullptr), + num_components_(1), + data_type_(DT_FLOAT32), + byte_stride_(0), + byte_offset_(0), + attribute_type_(INVALID), + unique_id_(0) {} + +void GeometryAttribute::Init(GeometryAttribute::Type attribute_type, + DataBuffer *buffer, uint8_t num_components, + DataType data_type, bool normalized, + int64_t byte_stride, int64_t byte_offset) { + buffer_ = buffer; + if (buffer) { + buffer_descriptor_.buffer_id = buffer->buffer_id(); + buffer_descriptor_.buffer_update_count = buffer->update_count(); + } + num_components_ = num_components; + data_type_ = data_type; + normalized_ = normalized; + byte_stride_ = byte_stride; + byte_offset_ = byte_offset; + attribute_type_ = attribute_type; +} + +bool GeometryAttribute::CopyFrom(const GeometryAttribute &src_att) { + num_components_ = src_att.num_components_; + data_type_ = src_att.data_type_; + normalized_ = src_att.normalized_; + byte_stride_ = src_att.byte_stride_; + byte_offset_ = src_att.byte_offset_; + attribute_type_ = src_att.attribute_type_; + buffer_descriptor_ = src_att.buffer_descriptor_; + unique_id_ = src_att.unique_id_; + if (src_att.buffer_ == nullptr) { + buffer_ = nullptr; + } else { + if (buffer_ == nullptr) { + return false; + } + buffer_->Update(src_att.buffer_->data(), src_att.buffer_->data_size()); + } +#ifdef DRACO_TRANSCODER_SUPPORTED + name_ = src_att.name_; +#endif + return true; +} + +bool GeometryAttribute::operator==(const GeometryAttribute &va) const { + if (attribute_type_ != va.attribute_type_) { + return false; + } + // It's OK to compare just the buffer descriptors here. We don't need to + // compare the buffers themselves. + if (buffer_descriptor_.buffer_id != va.buffer_descriptor_.buffer_id) { + return false; + } + if (buffer_descriptor_.buffer_update_count != + va.buffer_descriptor_.buffer_update_count) { + return false; + } + if (num_components_ != va.num_components_) { + return false; + } + if (data_type_ != va.data_type_) { + return false; + } + if (byte_stride_ != va.byte_stride_) { + return false; + } + if (byte_offset_ != va.byte_offset_) { + return false; + } +#ifdef DRACO_TRANSCODER_SUPPORTED + if (name_ != va.name_) { + return false; + } +#endif + return true; +} + +void GeometryAttribute::ResetBuffer(DataBuffer *buffer, int64_t byte_stride, + int64_t byte_offset) { + buffer_ = buffer; + buffer_descriptor_.buffer_id = buffer->buffer_id(); + buffer_descriptor_.buffer_update_count = buffer->update_count(); + byte_stride_ = byte_stride; + byte_offset_ = byte_offset; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/attributes/geometry_attribute.h b/third-party/draco/src/draco/attributes/geometry_attribute.h new file mode 100644 index 0000000000..734bd73e75 --- /dev/null +++ b/third-party/draco/src/draco/attributes/geometry_attribute.h @@ -0,0 +1,541 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ATTRIBUTES_GEOMETRY_ATTRIBUTE_H_ +#define DRACO_ATTRIBUTES_GEOMETRY_ATTRIBUTE_H_ + +#include +#include +#include +#include + +#include "draco/attributes/geometry_indices.h" +#include "draco/core/data_buffer.h" +#include "draco/core/hash_utils.h" +#include "draco/draco_features.h" +#ifdef DRACO_TRANSCODER_SUPPORTED +#include "draco/core/status.h" +#endif + +namespace draco { + +// The class provides access to a specific attribute which is stored in a +// DataBuffer, such as normals or coordinates. However, the GeometryAttribute +// class does not own the buffer and the buffer itself may store other data +// unrelated to this attribute (such as data for other attributes in which case +// we can have multiple GeometryAttributes accessing one buffer). Typically, +// all attributes for a point (or corner, face) are stored in one block, which +// is advantageous in terms of memory access. The length of the entire block is +// given by the byte_stride, the position where the attribute starts is given by +// the byte_offset, the actual number of bytes that the attribute occupies is +// given by the data_type and the number of components. +class GeometryAttribute { + public: + // Supported attribute types. + enum Type { + INVALID = -1, + // Named attributes start here. The difference between named and generic + // attributes is that for named attributes we know their purpose and we + // can apply some special methods when dealing with them (e.g. during + // encoding). + POSITION = 0, + NORMAL, + COLOR, + TEX_COORD, + // A special id used to mark attributes that are not assigned to any known + // predefined use case. Such attributes are often used for a shader specific + // data. + GENERIC, +#ifdef DRACO_TRANSCODER_SUPPORTED + // TODO(ostava): Adding a new attribute would be bit-stream change for GLTF. + // Older decoders wouldn't know what to do with this attribute type. This + // should be open-sourced only when we are ready to increase our bit-stream + // version. + TANGENT, + MATERIAL, + JOINTS, + WEIGHTS, +#endif + // Total number of different attribute types. + // Always keep behind all named attributes. + NAMED_ATTRIBUTES_COUNT, + }; + + GeometryAttribute(); + // Initializes and enables the attribute. + void Init(Type attribute_type, DataBuffer *buffer, uint8_t num_components, + DataType data_type, bool normalized, int64_t byte_stride, + int64_t byte_offset); + bool IsValid() const { return buffer_ != nullptr; } + + // Copies data from the source attribute to the this attribute. + // This attribute must have a valid buffer allocated otherwise the operation + // is going to fail and return false. + bool CopyFrom(const GeometryAttribute &src_att); + + // Function for getting a attribute value with a specific format. + // Unsafe. Caller must ensure the accessed memory is valid. + // T is the attribute data type. + // att_components_t is the number of attribute components. + template + std::array GetValue( + AttributeValueIndex att_index) const { + // Byte address of the attribute index. + const int64_t byte_pos = byte_offset_ + byte_stride_ * att_index.value(); + std::array out; + buffer_->Read(byte_pos, &(out[0]), sizeof(out)); + return out; + } + + // Function for getting a attribute value with a specific format. + // T is the attribute data type. + // att_components_t is the number of attribute components. + template + bool GetValue(AttributeValueIndex att_index, + std::array *out) const { + // Byte address of the attribute index. + const int64_t byte_pos = byte_offset_ + byte_stride_ * att_index.value(); + // Check we are not reading past end of data. + if (byte_pos + sizeof(*out) > buffer_->data_size()) { + return false; + } + buffer_->Read(byte_pos, &((*out)[0]), sizeof(*out)); + return true; + } + + // Returns the byte position of the attribute entry in the data buffer. + inline int64_t GetBytePos(AttributeValueIndex att_index) const { + return byte_offset_ + byte_stride_ * att_index.value(); + } + + inline const uint8_t *GetAddress(AttributeValueIndex att_index) const { + const int64_t byte_pos = GetBytePos(att_index); + return buffer_->data() + byte_pos; + } + inline uint8_t *GetAddress(AttributeValueIndex att_index) { + const int64_t byte_pos = GetBytePos(att_index); + return buffer_->data() + byte_pos; + } + inline bool IsAddressValid(const uint8_t *address) const { + return ((buffer_->data() + buffer_->data_size()) > address); + } + + // Fills out_data with the raw value of the requested attribute entry. + // out_data must be at least byte_stride_ long. + void GetValue(AttributeValueIndex att_index, void *out_data) const { + const int64_t byte_pos = byte_offset_ + byte_stride_ * att_index.value(); + buffer_->Read(byte_pos, out_data, byte_stride_); + } + + // Sets a value of an attribute entry. The input value must be allocated to + // cover all components of a single attribute entry. + void SetAttributeValue(AttributeValueIndex entry_index, const void *value) { + const int64_t byte_pos = entry_index.value() * byte_stride(); + buffer_->Write(byte_pos, value, byte_stride()); + } + +#ifdef DRACO_TRANSCODER_SUPPORTED + // Sets a value of an attribute entry. The input |value| must have + // |input_num_components| entries and it will be automatically converted to + // the internal format used by the geometry attribute. If the conversion is + // not possible, an error status will be returned. + template + Status ConvertAndSetAttributeValue(AttributeValueIndex avi, + int input_num_components, + const InputT *value); +#endif + + // DEPRECATED: Use + // ConvertValue(AttributeValueIndex att_id, + // int out_num_components, + // OutT *out_val); + // + // Function for conversion of a attribute to a specific output format. + // OutT is the desired data type of the attribute. + // out_att_components_t is the number of components of the output format. + // Returns false when the conversion failed. + template + bool ConvertValue(AttributeValueIndex att_id, OutT *out_val) const { + return ConvertValue(att_id, out_att_components_t, out_val); + } + + // Function for conversion of a attribute to a specific output format. + // |out_val| needs to be able to store |out_num_components| values. + // OutT is the desired data type of the attribute. + // Returns false when the conversion failed. + template + bool ConvertValue(AttributeValueIndex att_id, int8_t out_num_components, + OutT *out_val) const { + if (out_val == nullptr) { + return false; + } + switch (data_type_) { + case DT_INT8: + return ConvertTypedValue(att_id, out_num_components, + out_val); + case DT_UINT8: + return ConvertTypedValue(att_id, out_num_components, + out_val); + case DT_INT16: + return ConvertTypedValue(att_id, out_num_components, + out_val); + case DT_UINT16: + return ConvertTypedValue(att_id, out_num_components, + out_val); + case DT_INT32: + return ConvertTypedValue(att_id, out_num_components, + out_val); + case DT_UINT32: + return ConvertTypedValue(att_id, out_num_components, + out_val); + case DT_INT64: + return ConvertTypedValue(att_id, out_num_components, + out_val); + case DT_UINT64: + return ConvertTypedValue(att_id, out_num_components, + out_val); + case DT_FLOAT32: + return ConvertTypedValue(att_id, out_num_components, + out_val); + case DT_FLOAT64: + return ConvertTypedValue(att_id, out_num_components, + out_val); + case DT_BOOL: + return ConvertTypedValue(att_id, out_num_components, + out_val); + default: + // Wrong attribute type. + return false; + } + } + + // Function for conversion of a attribute to a specific output format. + // The |out_value| must be able to store all components of a single attribute + // entry. + // OutT is the desired data type of the attribute. + // Returns false when the conversion failed. + template + bool ConvertValue(AttributeValueIndex att_index, OutT *out_value) const { + return ConvertValue(att_index, num_components_, out_value); + } + + // Utility function. Returns |attribute_type| as std::string. + static std::string TypeToString(Type attribute_type) { + switch (attribute_type) { + case INVALID: + return "INVALID"; + case POSITION: + return "POSITION"; + case NORMAL: + return "NORMAL"; + case COLOR: + return "COLOR"; + case TEX_COORD: + return "TEX_COORD"; + case GENERIC: + return "GENERIC"; +#ifdef DRACO_TRANSCODER_SUPPORTED + case TANGENT: + return "TANGENT"; + case MATERIAL: + return "MATERIAL"; + case JOINTS: + return "JOINTS"; + case WEIGHTS: + return "WEIGHTS"; +#endif + default: + return "UNKNOWN"; + } + } + + bool operator==(const GeometryAttribute &va) const; + + // Returns the type of the attribute indicating the nature of the attribute. + Type attribute_type() const { return attribute_type_; } + void set_attribute_type(Type type) { attribute_type_ = type; } + // Returns the data type that is stored in the attribute. + DataType data_type() const { return data_type_; } + // Returns the number of components that are stored for each entry. + // For position attribute this is usually three (x,y,z), + // while texture coordinates have two components (u,v). + uint8_t num_components() const { return num_components_; } + // Indicates whether the data type should be normalized before interpretation, + // that is, it should be divided by the max value of the data type. + bool normalized() const { return normalized_; } + void set_normalized(bool normalized) { normalized_ = normalized; } + // The buffer storing the entire data of the attribute. + const DataBuffer *buffer() const { return buffer_; } + // Returns the number of bytes between two attribute entries, this is, at + // least size of the data types times number of components. + int64_t byte_stride() const { return byte_stride_; } + // The offset where the attribute starts within the block of size byte_stride. + int64_t byte_offset() const { return byte_offset_; } + void set_byte_offset(int64_t byte_offset) { byte_offset_ = byte_offset; } + DataBufferDescriptor buffer_descriptor() const { return buffer_descriptor_; } + uint32_t unique_id() const { return unique_id_; } + void set_unique_id(uint32_t id) { unique_id_ = id; } +#ifdef DRACO_TRANSCODER_SUPPORTED + std::string name() const { return name_; } + void set_name(std::string name) { name_ = name; } +#endif + + protected: + // Sets a new internal storage for the attribute. + void ResetBuffer(DataBuffer *buffer, int64_t byte_stride, + int64_t byte_offset); + + private: + // Function for conversion of an attribute to a specific output format given a + // format of the stored attribute. + // T is the stored attribute data type. + // OutT is the desired data type of the attribute. + template + bool ConvertTypedValue(AttributeValueIndex att_id, uint8_t out_num_components, + OutT *out_value) const { + const uint8_t *src_address = GetAddress(att_id); + + // Convert all components available in both the original and output formats. + for (int i = 0; i < std::min(num_components_, out_num_components); ++i) { + if (!IsAddressValid(src_address)) { + return false; + } + const T in_value = *reinterpret_cast(src_address); + if (!ConvertComponentValue(in_value, normalized_, + out_value + i)) { + return false; + } + src_address += sizeof(T); + } + // Fill empty data for unused output components if needed. + for (int i = num_components_; i < out_num_components; ++i) { + out_value[i] = static_cast(0); + } + return true; + } + +#ifdef DRACO_TRANSCODER_SUPPORTED + // Function that converts input |value| from type T to the internal attribute + // representation defined by OutT and |num_components_|. + template + Status ConvertAndSetAttributeTypedValue(AttributeValueIndex avi, + int8_t input_num_components, + const T *value) { + uint8_t *address = GetAddress(avi); + + // Convert all components available in both the original and output formats. + for (int i = 0; i < num_components_; ++i) { + if (!IsAddressValid(address)) { + return ErrorStatus("GeometryAttribute: Invalid address."); + } + OutT *const out_value = reinterpret_cast(address); + if (i < input_num_components) { + if (!ConvertComponentValue(*(value + i), normalized_, + out_value)) { + return ErrorStatus( + "GeometryAttribute: Failed to convert component value."); + } + } else { + *out_value = static_cast(0); + } + address += sizeof(OutT); + } + return OkStatus(); + } +#endif // DRACO_TRANSCODER_SUPPORTED + + // Converts |in_value| of type T into |out_value| of type OutT. If + // |normalized| is true, any conversion between floating point and integer + // values will be treating integers as normalized types (the entire integer + // range will be used to represent 0-1 floating point range). + template + static bool ConvertComponentValue(const T &in_value, bool normalized, + OutT *out_value) { + // Make sure the |in_value| can be represented as an integral type OutT. + if (std::is_integral::value) { + // Make sure the |in_value| fits within the range of values that OutT + // is able to represent. Perform the check only for integral types. + if (!std::is_same::value && std::is_integral::value) { + static constexpr OutT kOutMin = + std::is_signed::value ? std::numeric_limits::min() : 0; + if (in_value < kOutMin || in_value > std::numeric_limits::max()) { + return false; + } + } + + // Check conversion of floating point |in_value| to integral value OutT. + if (std::is_floating_point::value) { + // Make sure the floating point |in_value| is not NaN and not Inf as + // integral type OutT is unable to represent these values. + if (sizeof(in_value) > sizeof(double)) { + if (std::isnan(static_cast(in_value)) || + std::isinf(static_cast(in_value))) { + return false; + } + } else if (sizeof(in_value) > sizeof(float)) { + if (std::isnan(static_cast(in_value)) || + std::isinf(static_cast(in_value))) { + return false; + } + } else { + if (std::isnan(static_cast(in_value)) || + std::isinf(static_cast(in_value))) { + return false; + } + } + + // Make sure the floating point |in_value| fits within the range of + // values that integral type OutT is able to represent. + if (in_value < std::numeric_limits::min() || + in_value >= std::numeric_limits::max()) { + return false; + } + } + } + + if (std::is_integral::value && std::is_floating_point::value && + normalized) { + // When converting integer to floating point, normalize the value if + // necessary. + *out_value = static_cast(in_value); + *out_value /= static_cast(std::numeric_limits::max()); + } else if (std::is_floating_point::value && + std::is_integral::value && normalized) { + // Converting from floating point to a normalized integer. + if (in_value > 1 || in_value < 0) { + // Normalized float values need to be between 0 and 1. + return false; + } + // TODO(ostava): Consider allowing float to normalized integer conversion + // for 64-bit integer types. Currently it doesn't work because we don't + // have a floating point type that could store all 64 bit integers. + if (sizeof(OutT) > 4) { + return false; + } + // Expand the float to the range of the output integer and round it to the + // nearest representable value. Use doubles for the math to ensure the + // integer values are represented properly during the conversion process. + *out_value = static_cast(std::floor( + in_value * static_cast(std::numeric_limits::max()) + + 0.5)); + } else { + *out_value = static_cast(in_value); + } + + // TODO(ostava): Add handling of normalized attributes when converting + // between different integer representations. If the attribute is + // normalized, integer values should be converted as if they represent 0-1 + // range. E.g. when we convert uint16 to uint8, the range <0, 2^16 - 1> + // should be converted to range <0, 2^8 - 1>. + return true; + } + + DataBuffer *buffer_; + // The buffer descriptor is stored at the time the buffer is attached to this + // attribute. The purpose is to detect if any changes happened to the buffer + // since the time it was attached. + DataBufferDescriptor buffer_descriptor_; + uint8_t num_components_; + DataType data_type_; + bool normalized_; + int64_t byte_stride_; + int64_t byte_offset_; + + Type attribute_type_; + + // Unique id of this attribute. No two attributes could have the same unique + // id. It is used to identify each attribute, especially when there are + // multiple attribute of the same type in a point cloud. + uint32_t unique_id_; + +#ifdef DRACO_TRANSCODER_SUPPORTED + std::string name_; +#endif + + friend struct GeometryAttributeHasher; +}; + +#ifdef DRACO_TRANSCODER_SUPPORTED +template +Status GeometryAttribute::ConvertAndSetAttributeValue(AttributeValueIndex avi, + int input_num_components, + const InputT *value) { + switch (this->data_type()) { + case DT_INT8: + return ConvertAndSetAttributeTypedValue( + avi, input_num_components, value); + case DT_UINT8: + return ConvertAndSetAttributeTypedValue( + avi, input_num_components, value); + case DT_INT16: + return ConvertAndSetAttributeTypedValue( + avi, input_num_components, value); + case DT_UINT16: + return ConvertAndSetAttributeTypedValue( + avi, input_num_components, value); + case DT_INT32: + return ConvertAndSetAttributeTypedValue( + avi, input_num_components, value); + case DT_UINT32: + return ConvertAndSetAttributeTypedValue( + avi, input_num_components, value); + case DT_INT64: + return ConvertAndSetAttributeTypedValue( + avi, input_num_components, value); + case DT_UINT64: + return ConvertAndSetAttributeTypedValue( + avi, input_num_components, value); + case DT_FLOAT32: + return ConvertAndSetAttributeTypedValue( + avi, input_num_components, value); + case DT_FLOAT64: + return ConvertAndSetAttributeTypedValue( + avi, input_num_components, value); + case DT_BOOL: + return ConvertAndSetAttributeTypedValue( + avi, input_num_components, value); + default: + break; + } + return ErrorStatus( + "GeometryAttribute::SetAndConvertAttributeValue: Unsupported " + "attribute type."); +} +#endif + +// Hashing support + +// Function object for using Attribute as a hash key. +struct GeometryAttributeHasher { + size_t operator()(const GeometryAttribute &va) const { + size_t hash = HashCombine(va.buffer_descriptor_.buffer_id, + va.buffer_descriptor_.buffer_update_count); + hash = HashCombine(va.num_components_, hash); + hash = HashCombine(static_cast(va.data_type_), hash); + hash = HashCombine(static_cast(va.attribute_type_), hash); + hash = HashCombine(va.byte_stride_, hash); + return HashCombine(va.byte_offset_, hash); + } +}; + +// Function object for using GeometryAttribute::Type as a hash key. +struct GeometryAttributeTypeHasher { + size_t operator()(const GeometryAttribute::Type &at) const { + return static_cast(at); + } +}; + +} // namespace draco + +#endif // DRACO_ATTRIBUTES_GEOMETRY_ATTRIBUTE_H_ diff --git a/third-party/draco/src/draco/attributes/geometry_indices.h b/third-party/draco/src/draco/attributes/geometry_indices.h new file mode 100644 index 0000000000..80e43e30a1 --- /dev/null +++ b/third-party/draco/src/draco/attributes/geometry_indices.h @@ -0,0 +1,54 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ATTRIBUTES_GEOMETRY_INDICES_H_ +#define DRACO_ATTRIBUTES_GEOMETRY_INDICES_H_ + +#include + +#include + +#include "draco/core/draco_index_type.h" + +namespace draco { + +// Index of an attribute value entry stored in a GeometryAttribute. +DEFINE_NEW_DRACO_INDEX_TYPE(uint32_t, AttributeValueIndex) +// Index of a point in a PointCloud. +DEFINE_NEW_DRACO_INDEX_TYPE(uint32_t, PointIndex) +// Vertex index in a Mesh or CornerTable. +DEFINE_NEW_DRACO_INDEX_TYPE(uint32_t, VertexIndex) +// Corner index that identifies a corner in a Mesh or CornerTable. +DEFINE_NEW_DRACO_INDEX_TYPE(uint32_t, CornerIndex) +// Face index for Mesh and CornerTable. +DEFINE_NEW_DRACO_INDEX_TYPE(uint32_t, FaceIndex) + +// Constants denoting invalid indices. +static constexpr AttributeValueIndex kInvalidAttributeValueIndex( + std::numeric_limits::max()); +static constexpr PointIndex kInvalidPointIndex( + std::numeric_limits::max()); +static constexpr VertexIndex kInvalidVertexIndex( + std::numeric_limits::max()); +static constexpr CornerIndex kInvalidCornerIndex( + std::numeric_limits::max()); +static constexpr FaceIndex kInvalidFaceIndex( + std::numeric_limits::max()); + +// TODO(ostava): Add strongly typed indices for attribute id and unique +// attribute id. + +} // namespace draco + +#endif // DRACO_ATTRIBUTES_GEOMETRY_INDICES_H_ diff --git a/third-party/draco/src/draco/attributes/point_attribute.cc b/third-party/draco/src/draco/attributes/point_attribute.cc new file mode 100644 index 0000000000..5c459f3c44 --- /dev/null +++ b/third-party/draco/src/draco/attributes/point_attribute.cc @@ -0,0 +1,270 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/attributes/point_attribute.h" + +#include +#include +using std::unordered_map; + +// Shortcut for typed conditionals. +template +using conditional_t = typename std::conditional::type; + +namespace draco { + +PointAttribute::PointAttribute() + : num_unique_entries_(0), identity_mapping_(false) {} + +PointAttribute::PointAttribute(const GeometryAttribute &att) + : GeometryAttribute(att), + num_unique_entries_(0), + identity_mapping_(false) {} + +void PointAttribute::Init(Type attribute_type, int8_t num_components, + DataType data_type, bool normalized, + size_t num_attribute_values) { + attribute_buffer_ = std::unique_ptr(new DataBuffer()); + GeometryAttribute::Init(attribute_type, attribute_buffer_.get(), + num_components, data_type, normalized, + DataTypeLength(data_type) * num_components, 0); + Reset(num_attribute_values); + SetIdentityMapping(); +} + +void PointAttribute::CopyFrom(const PointAttribute &src_att) { + if (buffer() == nullptr) { + // If the destination attribute doesn't have a valid buffer, create it. + attribute_buffer_ = std::unique_ptr(new DataBuffer()); + ResetBuffer(attribute_buffer_.get(), 0, 0); + } + if (!GeometryAttribute::CopyFrom(src_att)) { + return; + } + identity_mapping_ = src_att.identity_mapping_; + num_unique_entries_ = src_att.num_unique_entries_; + indices_map_ = src_att.indices_map_; + if (src_att.attribute_transform_data_) { + attribute_transform_data_ = std::unique_ptr( + new AttributeTransformData(*src_att.attribute_transform_data_)); + } else { + attribute_transform_data_ = nullptr; + } +} + +bool PointAttribute::Reset(size_t num_attribute_values) { + if (attribute_buffer_ == nullptr) { + attribute_buffer_ = std::unique_ptr(new DataBuffer()); + } + const int64_t entry_size = DataTypeLength(data_type()) * num_components(); + if (!attribute_buffer_->Update(nullptr, num_attribute_values * entry_size)) { + return false; + } + // Assign the new buffer to the parent attribute. + ResetBuffer(attribute_buffer_.get(), entry_size, 0); + num_unique_entries_ = static_cast(num_attribute_values); + return true; +} + +void PointAttribute::Resize(size_t new_num_unique_entries) { + num_unique_entries_ = static_cast(new_num_unique_entries); + attribute_buffer_->Resize(new_num_unique_entries * byte_stride()); +} + +#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED +AttributeValueIndex::ValueType PointAttribute::DeduplicateValues( + const GeometryAttribute &in_att) { + return DeduplicateValues(in_att, AttributeValueIndex(0)); +} + +AttributeValueIndex::ValueType PointAttribute::DeduplicateValues( + const GeometryAttribute &in_att, AttributeValueIndex in_att_offset) { + AttributeValueIndex::ValueType unique_vals = 0; + switch (in_att.data_type()) { + // Currently we support only float, uint8, and uint16 arguments. + case DT_FLOAT32: + unique_vals = DeduplicateTypedValues(in_att, in_att_offset); + break; + case DT_INT8: + unique_vals = DeduplicateTypedValues(in_att, in_att_offset); + break; + case DT_UINT8: + case DT_BOOL: + unique_vals = DeduplicateTypedValues(in_att, in_att_offset); + break; + case DT_UINT16: + unique_vals = DeduplicateTypedValues(in_att, in_att_offset); + break; + case DT_INT16: + unique_vals = DeduplicateTypedValues(in_att, in_att_offset); + break; + case DT_UINT32: + unique_vals = DeduplicateTypedValues(in_att, in_att_offset); + break; + case DT_INT32: + unique_vals = DeduplicateTypedValues(in_att, in_att_offset); + break; + default: + return -1; // Unsupported data type. + } + if (unique_vals == 0) { + return -1; // Unexpected error. + } + return unique_vals; +} + +// Helper function for calling UnifyDuplicateAttributes +// with the correct template arguments. +// Returns the number of unique attribute values. +template +AttributeValueIndex::ValueType PointAttribute::DeduplicateTypedValues( + const GeometryAttribute &in_att, AttributeValueIndex in_att_offset) { + // Select the correct method to call based on the number of attribute + // components. + switch (in_att.num_components()) { + case 1: + return DeduplicateFormattedValues(in_att, in_att_offset); + case 2: + return DeduplicateFormattedValues(in_att, in_att_offset); + case 3: + return DeduplicateFormattedValues(in_att, in_att_offset); + case 4: + return DeduplicateFormattedValues(in_att, in_att_offset); + default: + return 0; + } +} + +template +AttributeValueIndex::ValueType PointAttribute::DeduplicateFormattedValues( + const GeometryAttribute &in_att, AttributeValueIndex in_att_offset) { + // We want to detect duplicates using a hash map but we cannot hash floating + // point numbers directly so bit-copy floats to the same sized integers and + // hash them. + + // First we need to determine which int type to use (1, 2, 4 or 8 bytes). + // Note, this is done at compile time using std::conditional struct. + // Conditional is in form . If bool-expression + // is true the "true" branch is used and vice versa. All at compile time. + typedef conditional_t>> + HashType; + + AttributeValueIndex unique_vals(0); + typedef std::array AttributeValue; + typedef std::array AttributeHashableValue; + typedef unordered_map> + ValueToIndexMap; + + // Hash map storing index of the first attribute with a given value. + ValueToIndexMap value_to_index_map; + AttributeValue att_value; + AttributeHashableValue hashable_value; + IndexTypeVector value_map( + num_unique_entries_); + for (AttributeValueIndex i(0); i < num_unique_entries_; ++i) { + const AttributeValueIndex att_pos = i + in_att_offset; + att_value = in_att.GetValue(att_pos); + // Convert the value to hashable type. Bit-copy real attributes to integers. + memcpy(&(hashable_value[0]), &(att_value[0]), sizeof(att_value)); + + typename ValueToIndexMap::iterator it; + bool inserted; + std::tie(it, inserted) = value_to_index_map.insert( + std::pair(hashable_value, + unique_vals)); + + // Try to update the hash map with a new entry pointing to the latest unique + // vertex index. + if (!inserted) { + // Duplicated value found. Update index mapping. + value_map[i] = it->second; + } else { + // New unique value. + SetAttributeValue(unique_vals, &att_value); + // Update index mapping. + value_map[i] = unique_vals; + + ++unique_vals; + } + } + if (unique_vals == num_unique_entries_) { + return unique_vals.value(); // Nothing has changed. + } + if (is_mapping_identity()) { + // Change identity mapping to the explicit one. + // The number of points is equal to the number of old unique values. + SetExplicitMapping(num_unique_entries_); + // Update the explicit map. + for (uint32_t i = 0; i < num_unique_entries_; ++i) { + SetPointMapEntry(PointIndex(i), value_map[AttributeValueIndex(i)]); + } + } else { + // Update point to value map using the mapping between old and new values. + for (PointIndex i(0); i < static_cast(indices_map_.size()); ++i) { + SetPointMapEntry(i, value_map[indices_map_[i]]); + } + } + num_unique_entries_ = unique_vals.value(); + return num_unique_entries_; +} +#endif + +#ifdef DRACO_TRANSCODER_SUPPORTED +void PointAttribute::RemoveUnusedValues() { + if (is_mapping_identity()) { + return; // For identity mapping, all values are always used. + } + // For explicit mapping we need to check if any point is mapped to a value. + // If not we can delete the value. + IndexTypeVector is_value_used(size(), false); + int num_used_values = 0; + for (PointIndex pi(0); pi < indices_map_.size(); ++pi) { + const AttributeValueIndex avi = indices_map_[pi]; + if (!is_value_used[avi]) { + is_value_used[avi] = true; + num_used_values++; + } + } + if (num_used_values == size()) { + return; // All values are used. + } + + // Remap the values and update the point to value mapping. + IndexTypeVector + old_to_new_value_map(size(), kInvalidAttributeValueIndex); + AttributeValueIndex new_avi(0); + for (AttributeValueIndex avi(0); avi < size(); ++avi) { + if (!is_value_used[avi]) { + continue; + } + if (avi != new_avi) { + SetAttributeValue(new_avi, GetAddress(avi)); + } + old_to_new_value_map[avi] = new_avi++; + } + + // Remap all points to the new attribute values. + for (PointIndex pi(0); pi < indices_map_.size(); ++pi) { + indices_map_[pi] = old_to_new_value_map[indices_map_[pi]]; + } + + num_unique_entries_ = num_used_values; +} +#endif + +} // namespace draco diff --git a/third-party/draco/src/draco/attributes/point_attribute.h b/third-party/draco/src/draco/attributes/point_attribute.h new file mode 100644 index 0000000000..d55c50c8a5 --- /dev/null +++ b/third-party/draco/src/draco/attributes/point_attribute.h @@ -0,0 +1,196 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_ATTRIBUTES_POINT_ATTRIBUTE_H_ +#define DRACO_ATTRIBUTES_POINT_ATTRIBUTE_H_ + +#include + +#include "draco/attributes/attribute_transform_data.h" +#include "draco/attributes/geometry_attribute.h" +#include "draco/core/draco_index_type_vector.h" +#include "draco/core/hash_utils.h" +#include "draco/core/macros.h" +#include "draco/draco_features.h" + +namespace draco { + +// Class for storing point specific data about each attribute. In general, +// multiple points stored in a point cloud can share the same attribute value +// and this class provides the necessary mapping between point ids and attribute +// value ids. +class PointAttribute : public GeometryAttribute { + public: + PointAttribute(); + explicit PointAttribute(const GeometryAttribute &att); + + // Make sure the move constructor is defined (needed for better performance + // when new attributes are added to PointCloud). + PointAttribute(PointAttribute &&attribute) = default; + PointAttribute &operator=(PointAttribute &&attribute) = default; + + // Initializes a point attribute. By default the attribute will be set to + // identity mapping between point indices and attribute values. To set custom + // mapping use SetExplicitMapping() function. + void Init(Type attribute_type, int8_t num_components, DataType data_type, + bool normalized, size_t num_attribute_values); + + // Copies attribute data from the provided |src_att| attribute. + void CopyFrom(const PointAttribute &src_att); + + // Prepares the attribute storage for the specified number of entries. + bool Reset(size_t num_attribute_values); + + size_t size() const { return num_unique_entries_; } + AttributeValueIndex mapped_index(PointIndex point_index) const { + if (identity_mapping_) { + return AttributeValueIndex(point_index.value()); + } + return indices_map_[point_index]; + } + DataBuffer *buffer() const { return attribute_buffer_.get(); } + bool is_mapping_identity() const { return identity_mapping_; } + size_t indices_map_size() const { + if (is_mapping_identity()) { + return 0; + } + return indices_map_.size(); + } + + const uint8_t *GetAddressOfMappedIndex(PointIndex point_index) const { + return GetAddress(mapped_index(point_index)); + } + + // Sets the new number of unique attribute entries for the attribute. The + // function resizes the attribute storage to hold |num_attribute_values| + // entries. + // All previous entries with AttributeValueIndex < |num_attribute_values| + // are preserved. Caller needs to ensure that the PointAttribute is still + // valid after the resizing operation (that is, each point is mapped to a + // valid attribute value). + void Resize(size_t new_num_unique_entries); + + // Functions for setting the type of mapping between point indices and + // attribute entry ids. + // This function sets the mapping to implicit, where point indices are equal + // to attribute entry indices. + void SetIdentityMapping() { + identity_mapping_ = true; + indices_map_.clear(); + } + // This function sets the mapping to be explicitly using the indices_map_ + // array that needs to be initialized by the caller. + void SetExplicitMapping(size_t num_points) { + identity_mapping_ = false; + indices_map_.resize(num_points, kInvalidAttributeValueIndex); + } + + // Set an explicit map entry for a specific point index. + void SetPointMapEntry(PointIndex point_index, + AttributeValueIndex entry_index) { + DRACO_DCHECK(!identity_mapping_); + indices_map_[point_index] = entry_index; + } + + // Same as GeometryAttribute::GetValue(), but using point id as the input. + // Mapping to attribute value index is performed automatically. + void GetMappedValue(PointIndex point_index, void *out_data) const { + return GetValue(mapped_index(point_index), out_data); + } + +#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED + // Deduplicate |in_att| values into |this| attribute. |in_att| can be equal + // to |this|. + // Returns -1 if the deduplication failed. + AttributeValueIndex::ValueType DeduplicateValues( + const GeometryAttribute &in_att); + + // Same as above but the values read from |in_att| are sampled with the + // provided offset |in_att_offset|. + AttributeValueIndex::ValueType DeduplicateValues( + const GeometryAttribute &in_att, AttributeValueIndex in_att_offset); +#endif + + // Set attribute transform data for the attribute. The data is used to store + // the type and parameters of the transform that is applied on the attribute + // data (optional). + void SetAttributeTransformData( + std::unique_ptr transform_data) { + attribute_transform_data_ = std::move(transform_data); + } + const AttributeTransformData *GetAttributeTransformData() const { + return attribute_transform_data_.get(); + } + +#ifdef DRACO_TRANSCODER_SUPPORTED + // Removes unused values from the attribute. Value is unused when no point + // is mapped to the value. Only applicable when the mapping is not identity. + void RemoveUnusedValues(); +#endif + + private: +#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED + template + AttributeValueIndex::ValueType DeduplicateTypedValues( + const GeometryAttribute &in_att, AttributeValueIndex in_att_offset); + template + AttributeValueIndex::ValueType DeduplicateFormattedValues( + const GeometryAttribute &in_att, AttributeValueIndex in_att_offset); +#endif + + // Data storage for attribute values. GeometryAttribute itself doesn't own its + // buffer so we need to allocate it here. + std::unique_ptr attribute_buffer_; + + // Mapping between point ids and attribute value ids. + IndexTypeVector indices_map_; + AttributeValueIndex::ValueType num_unique_entries_; + // Flag when the mapping between point ids and attribute values is identity. + bool identity_mapping_; + + // If an attribute contains transformed data (e.g. quantized), we can specify + // the attribute transform here and use it to transform the attribute back to + // its original format. + std::unique_ptr attribute_transform_data_; + + friend struct PointAttributeHasher; +}; + +// Hash functor for the PointAttribute class. +struct PointAttributeHasher { + size_t operator()(const PointAttribute &attribute) const { + GeometryAttributeHasher base_hasher; + size_t hash = base_hasher(attribute); + hash = HashCombine(attribute.identity_mapping_, hash); + hash = HashCombine(attribute.num_unique_entries_, hash); + hash = HashCombine(attribute.indices_map_.size(), hash); + if (!attribute.indices_map_.empty()) { + const uint64_t indices_hash = FingerprintString( + reinterpret_cast(attribute.indices_map_.data()), + attribute.indices_map_.size()); + hash = HashCombine(indices_hash, hash); + } + if (attribute.attribute_buffer_ != nullptr) { + const uint64_t buffer_hash = FingerprintString( + reinterpret_cast(attribute.attribute_buffer_->data()), + attribute.attribute_buffer_->data_size()); + hash = HashCombine(buffer_hash, hash); + } + return hash; + } +}; + +} // namespace draco + +#endif // DRACO_ATTRIBUTES_POINT_ATTRIBUTE_H_ diff --git a/third-party/draco/src/draco/attributes/point_attribute_test.cc b/third-party/draco/src/draco/attributes/point_attribute_test.cc new file mode 100644 index 0000000000..4ae23fb3c0 --- /dev/null +++ b/third-party/draco/src/draco/attributes/point_attribute_test.cc @@ -0,0 +1,128 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/attributes/point_attribute.h" + +#include "draco/core/draco_test_base.h" + +namespace { + +class PointAttributeTest : public ::testing::Test { + protected: + PointAttributeTest() {} +}; + +TEST_F(PointAttributeTest, TestCopy) { + // This test verifies that PointAttribute can copy data from another point + // attribute. + draco::PointAttribute pa; + pa.Init(draco::GeometryAttribute::POSITION, 1, draco::DT_INT32, false, 10); + + for (int32_t i = 0; i < 10; ++i) { + pa.SetAttributeValue(draco::AttributeValueIndex(i), &i); + } + + pa.set_unique_id(12); + + draco::PointAttribute other_pa; + other_pa.CopyFrom(pa); + + draco::PointAttributeHasher hasher; + ASSERT_EQ(hasher(pa), hasher(other_pa)); + ASSERT_EQ(pa.unique_id(), other_pa.unique_id()); + + // The hash function does not actually compute the hash from attribute values, + // so ensure the data got copied correctly as well. + for (int32_t i = 0; i < 10; ++i) { + int32_t data; + other_pa.GetValue(draco::AttributeValueIndex(i), &data); + ASSERT_EQ(data, i); + } +} + +TEST_F(PointAttributeTest, TestGetValueFloat) { + draco::PointAttribute pa; + pa.Init(draco::GeometryAttribute::POSITION, 3, draco::DT_FLOAT32, false, 5); + float points[3]; + for (int32_t i = 0; i < 5; ++i) { + points[0] = i * 3.0; + points[1] = (i * 3.0) + 1.0; + points[2] = (i * 3.0) + 2.0; + pa.SetAttributeValue(draco::AttributeValueIndex(i), &points); + } + + for (int32_t i = 0; i < 5; ++i) { + pa.GetValue(draco::AttributeValueIndex(i), &points); + ASSERT_FLOAT_EQ(points[0], i * 3.0); + ASSERT_FLOAT_EQ(points[1], (i * 3.0) + 1.0); + ASSERT_FLOAT_EQ(points[2], (i * 3.0) + 2.0); + } +} + +TEST_F(PointAttributeTest, TestGetArray) { + draco::PointAttribute pa; + pa.Init(draco::GeometryAttribute::POSITION, 3, draco::DT_FLOAT32, false, 5); + float points[3]; + for (int32_t i = 0; i < 5; ++i) { + points[0] = i * 3.0; + points[1] = (i * 3.0) + 1.0; + points[2] = (i * 3.0) + 2.0; + pa.SetAttributeValue(draco::AttributeValueIndex(i), &points); + } + + for (int32_t i = 0; i < 5; ++i) { + std::array att_value; + att_value = pa.GetValue(draco::AttributeValueIndex(i)); + ASSERT_FLOAT_EQ(att_value[0], i * 3.0); + ASSERT_FLOAT_EQ(att_value[1], (i * 3.0) + 1.0); + ASSERT_FLOAT_EQ(att_value[2], (i * 3.0) + 2.0); + } + for (int32_t i = 0; i < 5; ++i) { + std::array att_value; + EXPECT_TRUE( + (pa.GetValue(draco::AttributeValueIndex(i), &att_value))); + ASSERT_FLOAT_EQ(att_value[0], i * 3.0); + ASSERT_FLOAT_EQ(att_value[1], (i * 3.0) + 1.0); + ASSERT_FLOAT_EQ(att_value[2], (i * 3.0) + 2.0); + } +} + +TEST_F(PointAttributeTest, TestArrayReadError) { + draco::PointAttribute pa; + pa.Init(draco::GeometryAttribute::POSITION, 3, draco::DT_FLOAT32, false, 5); + float points[3]; + for (int32_t i = 0; i < 5; ++i) { + points[0] = i * 3.0; + points[1] = (i * 3.0) + 1.0; + points[2] = (i * 3.0) + 2.0; + pa.SetAttributeValue(draco::AttributeValueIndex(i), &points); + } + + std::array att_value; + EXPECT_FALSE( + (pa.GetValue(draco::AttributeValueIndex(5), &att_value))); +} + +TEST_F(PointAttributeTest, TestResize) { + draco::PointAttribute pa; + pa.Init(draco::GeometryAttribute::POSITION, 3, draco::DT_FLOAT32, false, 5); + ASSERT_EQ(pa.size(), 5); + ASSERT_EQ(pa.buffer()->data_size(), 4 * 3 * 5); + + pa.Resize(10); + ASSERT_EQ(pa.size(), 10); + ASSERT_EQ(pa.buffer()->data_size(), 4 * 3 * 10); +} + +} // namespace diff --git a/third-party/draco/src/draco/compression/attributes/attributes_decoder.cc b/third-party/draco/src/draco/compression/attributes/attributes_decoder.cc new file mode 100644 index 0000000000..007dd2f430 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/attributes_decoder.cc @@ -0,0 +1,127 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/attributes_decoder.h" + +#include "draco/core/varint_decoding.h" + +namespace draco { + +AttributesDecoder::AttributesDecoder() + : point_cloud_decoder_(nullptr), point_cloud_(nullptr) {} + +bool AttributesDecoder::Init(PointCloudDecoder *decoder, PointCloud *pc) { + point_cloud_decoder_ = decoder; + point_cloud_ = pc; + return true; +} + +bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) { + // Decode and create attributes. + uint32_t num_attributes; +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + if (point_cloud_decoder_->bitstream_version() < + DRACO_BITSTREAM_VERSION(2, 0)) { + if (!in_buffer->Decode(&num_attributes)) { + return false; + } + } else +#endif + { + if (!DecodeVarint(&num_attributes, in_buffer)) { + return false; + } + } + + // Check that decoded number of attributes is valid. + if (num_attributes == 0) { + return false; + } + if (num_attributes > 5 * in_buffer->remaining_size()) { + // The decoded number of attributes is unreasonably high, because at least + // five bytes of attribute descriptor data per attribute are expected. + return false; + } + + // Decode attribute descriptor data. + point_attribute_ids_.resize(num_attributes); + PointCloud *pc = point_cloud_; + for (uint32_t i = 0; i < num_attributes; ++i) { + // Decode attribute descriptor data. + uint8_t att_type, data_type, num_components, normalized; + if (!in_buffer->Decode(&att_type)) { + return false; + } + if (!in_buffer->Decode(&data_type)) { + return false; + } + if (!in_buffer->Decode(&num_components)) { + return false; + } + if (!in_buffer->Decode(&normalized)) { + return false; + } + if (att_type >= GeometryAttribute::NAMED_ATTRIBUTES_COUNT) { + return false; + } + if (data_type == DT_INVALID || data_type >= DT_TYPES_COUNT) { + return false; + } + + // Check decoded attribute descriptor data. + if (num_components == 0) { + return false; + } + + // Add the attribute to the point cloud. + const DataType draco_dt = static_cast(data_type); + GeometryAttribute ga; + ga.Init(static_cast(att_type), nullptr, + num_components, draco_dt, normalized > 0, + DataTypeLength(draco_dt) * num_components, 0); + uint32_t unique_id; +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + if (point_cloud_decoder_->bitstream_version() < + DRACO_BITSTREAM_VERSION(1, 3)) { + uint16_t custom_id; + if (!in_buffer->Decode(&custom_id)) { + return false; + } + // TODO(draco-eng): Add "custom_id" to attribute metadata. + unique_id = static_cast(custom_id); + ga.set_unique_id(unique_id); + } else +#endif + { + if (!DecodeVarint(&unique_id, in_buffer)) { + return false; + } + ga.set_unique_id(unique_id); + } + const int att_id = pc->AddAttribute( + std::unique_ptr(new PointAttribute(ga))); + pc->attribute(att_id)->set_unique_id(unique_id); + point_attribute_ids_[i] = att_id; + + // Update the inverse map. + if (att_id >= + static_cast(point_attribute_to_local_id_map_.size())) { + point_attribute_to_local_id_map_.resize(att_id + 1, -1); + } + point_attribute_to_local_id_map_[att_id] = i; + } + return true; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/attributes_decoder.h b/third-party/draco/src/draco/compression/attributes/attributes_decoder.h new file mode 100644 index 0000000000..5b2bb2cfeb --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/attributes_decoder.h @@ -0,0 +1,97 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_ATTRIBUTES_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_ATTRIBUTES_DECODER_H_ + +#include + +#include "draco/compression/attributes/attributes_decoder_interface.h" +#include "draco/compression/point_cloud/point_cloud_decoder.h" +#include "draco/core/decoder_buffer.h" +#include "draco/draco_features.h" +#include "draco/point_cloud/point_cloud.h" + +namespace draco { + +// Base class for decoding one or more attributes that were encoded with a +// matching AttributesEncoder. It is a basic implementation of +// AttributesDecoderInterface that provides functionality that is shared between +// all AttributesDecoders. +class AttributesDecoder : public AttributesDecoderInterface { + public: + AttributesDecoder(); + virtual ~AttributesDecoder() = default; + + // Called after all attribute decoders are created. It can be used to perform + // any custom initialization. + bool Init(PointCloudDecoder *decoder, PointCloud *pc) override; + + // Decodes any attribute decoder specific data from the |in_buffer|. + bool DecodeAttributesDecoderData(DecoderBuffer *in_buffer) override; + + int32_t GetAttributeId(int i) const override { + return point_attribute_ids_[i]; + } + int32_t GetNumAttributes() const override { + return static_cast(point_attribute_ids_.size()); + } + PointCloudDecoder *GetDecoder() const override { + return point_cloud_decoder_; + } + + // Decodes attribute data from the source buffer. + bool DecodeAttributes(DecoderBuffer *in_buffer) override { + if (!DecodePortableAttributes(in_buffer)) { + return false; + } + if (!DecodeDataNeededByPortableTransforms(in_buffer)) { + return false; + } + if (!TransformAttributesToOriginalFormat()) { + return false; + } + return true; + } + + protected: + int32_t GetLocalIdForPointAttribute(int32_t point_attribute_id) const { + const int id_map_size = + static_cast(point_attribute_to_local_id_map_.size()); + if (point_attribute_id >= id_map_size) { + return -1; + } + return point_attribute_to_local_id_map_[point_attribute_id]; + } + virtual bool DecodePortableAttributes(DecoderBuffer *in_buffer) = 0; + virtual bool DecodeDataNeededByPortableTransforms(DecoderBuffer *in_buffer) { + return true; + } + virtual bool TransformAttributesToOriginalFormat() { return true; } + + private: + // List of attribute ids that need to be decoded with this decoder. + std::vector point_attribute_ids_; + + // Map between point attribute id and the local id (i.e., the inverse of the + // |point_attribute_ids_|. + std::vector point_attribute_to_local_id_map_; + + PointCloudDecoder *point_cloud_decoder_; + PointCloud *point_cloud_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_ATTRIBUTES_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/attributes_decoder_interface.h b/third-party/draco/src/draco/compression/attributes/attributes_decoder_interface.h new file mode 100644 index 0000000000..8e5cf52ac3 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/attributes_decoder_interface.h @@ -0,0 +1,62 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_ATTRIBUTES_DECODER_INTERFACE_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_ATTRIBUTES_DECODER_INTERFACE_H_ + +#include + +#include "draco/core/decoder_buffer.h" +#include "draco/point_cloud/point_cloud.h" + +namespace draco { + +class PointCloudDecoder; + +// Interface class for decoding one or more attributes that were encoded with a +// matching AttributesEncoder. It provides only the basic interface +// that is used by the PointCloudDecoder. The actual decoding must be +// implemented in derived classes using the DecodeAttributes() method. +class AttributesDecoderInterface { + public: + AttributesDecoderInterface() = default; + virtual ~AttributesDecoderInterface() = default; + + // Called after all attribute decoders are created. It can be used to perform + // any custom initialization. + virtual bool Init(PointCloudDecoder *decoder, PointCloud *pc) = 0; + + // Decodes any attribute decoder specific data from the |in_buffer|. + virtual bool DecodeAttributesDecoderData(DecoderBuffer *in_buffer) = 0; + + // Decode attribute data from the source buffer. Needs to be implemented by + // the derived classes. + virtual bool DecodeAttributes(DecoderBuffer *in_buffer) = 0; + + virtual int32_t GetAttributeId(int i) const = 0; + virtual int32_t GetNumAttributes() const = 0; + virtual PointCloudDecoder *GetDecoder() const = 0; + + // Returns an attribute containing data processed by the attribute transform. + // (see TransformToPortableFormat() method). This data is guaranteed to be + // same for encoder and decoder and it can be used by predictors. + virtual const PointAttribute *GetPortableAttribute( + int32_t /* point_attribute_id */) { + return nullptr; + } +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_ATTRIBUTES_DECODER_INTERFACE_H_ diff --git a/third-party/draco/src/draco/compression/attributes/attributes_encoder.cc b/third-party/draco/src/draco/compression/attributes/attributes_encoder.cc new file mode 100644 index 0000000000..480e3ff343 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/attributes_encoder.cc @@ -0,0 +1,59 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/attributes_encoder.h" + +#include "draco/core/varint_encoding.h" +#include "draco/draco_features.h" + +namespace draco { + +AttributesEncoder::AttributesEncoder() + : point_cloud_encoder_(nullptr), point_cloud_(nullptr) {} + +AttributesEncoder::AttributesEncoder(int point_attrib_id) + : AttributesEncoder() { + AddAttributeId(point_attrib_id); +} + +bool AttributesEncoder::Init(PointCloudEncoder *encoder, const PointCloud *pc) { + point_cloud_encoder_ = encoder; + point_cloud_ = pc; + return true; +} + +bool AttributesEncoder::EncodeAttributesEncoderData(EncoderBuffer *out_buffer) { + // Encode data about all attributes. + EncodeVarint(num_attributes(), out_buffer); + for (uint32_t i = 0; i < num_attributes(); ++i) { + const int32_t att_id = point_attribute_ids_[i]; + const PointAttribute *const pa = point_cloud_->attribute(att_id); + GeometryAttribute::Type type = pa->attribute_type(); +#ifdef DRACO_TRANSCODER_SUPPORTED + // Attribute types TANGENT, MATERIAL, JOINTS, and WEIGHTS are not supported + // in the official bitstream. They will be encoded as GENERIC. + if (type > GeometryAttribute::GENERIC) { + type = GeometryAttribute::GENERIC; + } +#endif + out_buffer->Encode(static_cast(type)); + out_buffer->Encode(static_cast(pa->data_type())); + out_buffer->Encode(static_cast(pa->num_components())); + out_buffer->Encode(static_cast(pa->normalized())); + EncodeVarint(pa->unique_id(), out_buffer); + } + return true; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/attributes_encoder.h b/third-party/draco/src/draco/compression/attributes/attributes_encoder.h new file mode 100644 index 0000000000..9de846ae6d --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/attributes_encoder.h @@ -0,0 +1,154 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_ATTRIBUTES_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_ATTRIBUTES_ENCODER_H_ + +#include "draco/attributes/point_attribute.h" +#include "draco/core/encoder_buffer.h" +#include "draco/point_cloud/point_cloud.h" + +namespace draco { + +class PointCloudEncoder; + +// Base class for encoding one or more attributes of a PointCloud (or other +// geometry). This base class provides only the basic interface that is used +// by the PointCloudEncoder. +class AttributesEncoder { + public: + AttributesEncoder(); + // Constructs an attribute encoder associated with a given point attribute. + explicit AttributesEncoder(int point_attrib_id); + virtual ~AttributesEncoder() = default; + + // Called after all attribute encoders are created. It can be used to perform + // any custom initialization, including setting up attribute dependencies. + // Note: no data should be encoded in this function, because the decoder may + // process encoders in a different order from the decoder. + virtual bool Init(PointCloudEncoder *encoder, const PointCloud *pc); + + // Encodes data needed by the target attribute decoder. + virtual bool EncodeAttributesEncoderData(EncoderBuffer *out_buffer); + + // Returns a unique identifier of the given encoder type, that is used during + // decoding to construct the corresponding attribute decoder. + virtual uint8_t GetUniqueId() const = 0; + + // Encode attribute data to the target buffer. + virtual bool EncodeAttributes(EncoderBuffer *out_buffer) { + if (!TransformAttributesToPortableFormat()) { + return false; + } + if (!EncodePortableAttributes(out_buffer)) { + return false; + } + // Encode data needed by portable transforms after the attribute is encoded. + // This corresponds to the order in which the data is going to be decoded by + // the decoder. + if (!EncodeDataNeededByPortableTransforms(out_buffer)) { + return false; + } + return true; + } + + // Returns the number of attributes that need to be encoded before the + // specified attribute is encoded. + // Note that the attribute is specified by its point attribute id. + virtual int NumParentAttributes(int32_t /* point_attribute_id */) const { + return 0; + } + + virtual int GetParentAttributeId(int32_t /* point_attribute_id */, + int32_t /* parent_i */) const { + return -1; + } + + // Marks a given attribute as a parent of another attribute. + virtual bool MarkParentAttribute(int32_t /* point_attribute_id */) { + return false; + } + + // Returns an attribute containing data processed by the attribute transform. + // (see TransformToPortableFormat() method). This data is guaranteed to be + // encoded losslessly and it can be safely used for predictors. + virtual const PointAttribute *GetPortableAttribute( + int32_t /* point_attribute_id */) { + return nullptr; + } + + void AddAttributeId(int32_t id) { + point_attribute_ids_.push_back(id); + if (id >= static_cast(point_attribute_to_local_id_map_.size())) { + point_attribute_to_local_id_map_.resize(id + 1, -1); + } + point_attribute_to_local_id_map_[id] = + static_cast(point_attribute_ids_.size()) - 1; + } + + // Sets new attribute point ids (replacing the existing ones). + void SetAttributeIds(const std::vector &point_attribute_ids) { + point_attribute_ids_.clear(); + point_attribute_to_local_id_map_.clear(); + for (int32_t att_id : point_attribute_ids) { + AddAttributeId(att_id); + } + } + + int32_t GetAttributeId(int i) const { return point_attribute_ids_[i]; } + uint32_t num_attributes() const { + return static_cast(point_attribute_ids_.size()); + } + PointCloudEncoder *encoder() const { return point_cloud_encoder_; } + + protected: + // Transforms the input attribute data into a form that should be losslessly + // encoded (transform itself can be lossy). + virtual bool TransformAttributesToPortableFormat() { return true; } + + // Losslessly encodes data of all portable attributes. + // Precondition: All attributes must have been transformed into portable + // format at this point (see TransformAttributesToPortableFormat() method). + virtual bool EncodePortableAttributes(EncoderBuffer *out_buffer) = 0; + + // Encodes any data needed to revert the transform to portable format for each + // attribute (e.g. data needed for dequantization of quantized values). + virtual bool EncodeDataNeededByPortableTransforms(EncoderBuffer *out_buffer) { + return true; + } + + int32_t GetLocalIdForPointAttribute(int32_t point_attribute_id) const { + const int id_map_size = + static_cast(point_attribute_to_local_id_map_.size()); + if (point_attribute_id >= id_map_size) { + return -1; + } + return point_attribute_to_local_id_map_[point_attribute_id]; + } + + private: + // List of attribute ids that need to be encoded with this encoder. + std::vector point_attribute_ids_; + + // Map between point attribute id and the local id (i.e., the inverse of the + // |point_attribute_ids_|. + std::vector point_attribute_to_local_id_map_; + + PointCloudEncoder *point_cloud_encoder_; + const PointCloud *point_cloud_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_ATTRIBUTES_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc b/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc new file mode 100644 index 0000000000..51c41cf7a2 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.cc @@ -0,0 +1,581 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/kd_tree_attributes_decoder.h" + +#include "draco/compression/attributes/kd_tree_attributes_shared.h" +#include "draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h" +#include "draco/compression/point_cloud/algorithms/float_points_tree_decoder.h" +#include "draco/compression/point_cloud/point_cloud_decoder.h" +#include "draco/core/draco_types.h" +#include "draco/core/varint_decoding.h" + +namespace draco { + +// attribute, offset_dimensionality, data_type, data_size, num_components +using AttributeTuple = + std::tuple; + +// Output iterator that is used to decode values directly into the data buffer +// of the modified PointAttribute. +// The extension of this iterator beyond the DT_UINT32 concerns itself only with +// the size of the data for efficiency, not the type. DataType is conveyed in +// but is an unused field populated for any future logic/special casing. +// DT_UINT32 and all other 4-byte types are naturally supported from the size of +// data in the kd tree encoder. DT_UINT16 and DT_UINT8 are supported by way +// of byte copies into a temporary memory buffer. +template +class PointAttributeVectorOutputIterator { + typedef PointAttributeVectorOutputIterator Self; + + public: + PointAttributeVectorOutputIterator( + PointAttributeVectorOutputIterator &&that) = default; + + explicit PointAttributeVectorOutputIterator( + const std::vector &atts) + : attributes_(atts), point_id_(0) { + DRACO_DCHECK_GE(atts.size(), 1); + uint32_t required_decode_bytes = 0; + for (auto index = 0; index < attributes_.size(); index++) { + const AttributeTuple &att = attributes_[index]; + required_decode_bytes = (std::max)(required_decode_bytes, + std::get<3>(att) * std::get<4>(att)); + } + memory_.resize(required_decode_bytes); + data_ = memory_.data(); + } + + const Self &operator++() { + ++point_id_; + return *this; + } + + // We do not want to do ANY copying of this constructor so this particular + // operator is disabled for performance reasons. + // Self operator++(int) { + // Self copy = *this; + // ++point_id_; + // return copy; + // } + + Self &operator*() { return *this; } + // Still needed in some cases. + // TODO(b/199760123): Remove. + // hardcoded to 3 based on legacy usage. + const Self &operator=(const VectorD &val) { + DRACO_DCHECK_EQ(attributes_.size(), 1); // Expect only ONE attribute. + AttributeTuple &att = attributes_[0]; + PointAttribute *attribute = std::get<0>(att); + const AttributeValueIndex avi = attribute->mapped_index(point_id_); + if (avi >= static_cast(attribute->size())) { + return *this; + } + const uint32_t &offset = std::get<1>(att); + DRACO_DCHECK_EQ(offset, 0); // expected to be zero + attribute->SetAttributeValue(avi, &val[0] + offset); + return *this; + } + // Additional operator taking std::vector as argument. + const Self &operator=(const std::vector &val) { + for (auto index = 0; index < attributes_.size(); index++) { + AttributeTuple &att = attributes_[index]; + PointAttribute *attribute = std::get<0>(att); + const AttributeValueIndex avi = attribute->mapped_index(point_id_); + if (avi >= static_cast(attribute->size())) { + return *this; + } + const uint32_t &offset = std::get<1>(att); + const uint32_t &data_size = std::get<3>(att); + const uint32_t &num_components = std::get<4>(att); + const uint32_t *data_source = val.data() + offset; + if (data_size < 4) { // handle uint16_t, uint8_t + // selectively copy data bytes + uint8_t *data_counter = data_; + for (uint32_t index = 0; index < num_components; + index += 1, data_counter += data_size) { + std::memcpy(data_counter, data_source + index, data_size); + } + // redirect to copied data + data_source = reinterpret_cast(data_); + } + attribute->SetAttributeValue(avi, data_source); + } + return *this; + } + + private: + // preallocated memory for buffering different data sizes. Never reallocated. + std::vector memory_; + uint8_t *data_; + std::vector attributes_; + PointIndex point_id_; + + // NO COPY + PointAttributeVectorOutputIterator( + const PointAttributeVectorOutputIterator &that) = delete; + PointAttributeVectorOutputIterator &operator=( + PointAttributeVectorOutputIterator const &) = delete; +}; + +KdTreeAttributesDecoder::KdTreeAttributesDecoder() {} + +bool KdTreeAttributesDecoder::DecodePortableAttributes( + DecoderBuffer *in_buffer) { + if (in_buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 3)) { + // Old bitstream does everything in the + // DecodeDataNeededByPortableTransforms() method. + return true; + } + uint8_t compression_level = 0; + if (!in_buffer->Decode(&compression_level)) { + return false; + } + const int32_t num_points = GetDecoder()->point_cloud()->num_points(); + + // Decode data using the kd tree decoding into integer (portable) attributes. + // We first need to go over all attributes and create a new portable storage + // for those attributes that need it (floating point attributes that have to + // be dequantized after decoding). + + const int num_attributes = GetNumAttributes(); + uint32_t total_dimensionality = 0; // position is a required dimension + std::vector atts(num_attributes); + + for (int i = 0; i < GetNumAttributes(); ++i) { + const int att_id = GetAttributeId(i); + PointAttribute *const att = GetDecoder()->point_cloud()->attribute(att_id); + // All attributes have the same number of values and identity mapping + // between PointIndex and AttributeValueIndex. + att->Reset(num_points); + att->SetIdentityMapping(); + + PointAttribute *target_att = nullptr; + if (att->data_type() == DT_UINT32 || att->data_type() == DT_UINT16 || + att->data_type() == DT_UINT8) { + // We can decode to these attributes directly. + target_att = att; + } else if (att->data_type() == DT_INT32 || att->data_type() == DT_INT16 || + att->data_type() == DT_INT8) { + // Prepare storage for data that is used to convert unsigned values back + // to the signed ones. + for (int c = 0; c < att->num_components(); ++c) { + min_signed_values_.push_back(0); + } + target_att = att; + } else if (att->data_type() == DT_FLOAT32) { + // Create a portable attribute that will hold the decoded data. We will + // dequantize the decoded data to the final attribute later on. + const int num_components = att->num_components(); + GeometryAttribute va; + va.Init(att->attribute_type(), nullptr, num_components, DT_UINT32, false, + num_components * DataTypeLength(DT_UINT32), 0); + std::unique_ptr port_att(new PointAttribute(va)); + port_att->SetIdentityMapping(); + port_att->Reset(num_points); + quantized_portable_attributes_.push_back(std::move(port_att)); + target_att = quantized_portable_attributes_.back().get(); + } else { + // Unsupported type. + return false; + } + // Add attribute to the output iterator used by the core algorithm. + const DataType data_type = target_att->data_type(); + const uint32_t data_size = (std::max)(0, DataTypeLength(data_type)); + const uint32_t num_components = target_att->num_components(); + atts[i] = std::make_tuple(target_att, total_dimensionality, data_type, + data_size, num_components); + total_dimensionality += num_components; + } + typedef PointAttributeVectorOutputIterator OutIt; + OutIt out_it(atts); + + switch (compression_level) { + case 0: { + if (!DecodePoints<0, OutIt>(total_dimensionality, num_points, in_buffer, + &out_it)) { + return false; + } + break; + } + case 1: { + if (!DecodePoints<1, OutIt>(total_dimensionality, num_points, in_buffer, + &out_it)) { + return false; + } + break; + } + case 2: { + if (!DecodePoints<2, OutIt>(total_dimensionality, num_points, in_buffer, + &out_it)) { + return false; + } + break; + } + case 3: { + if (!DecodePoints<3, OutIt>(total_dimensionality, num_points, in_buffer, + &out_it)) { + return false; + } + break; + } + case 4: { + if (!DecodePoints<4, OutIt>(total_dimensionality, num_points, in_buffer, + &out_it)) { + return false; + } + break; + } + case 5: { + if (!DecodePoints<5, OutIt>(total_dimensionality, num_points, in_buffer, + &out_it)) { + return false; + } + break; + } + case 6: { + if (!DecodePoints<6, OutIt>(total_dimensionality, num_points, in_buffer, + &out_it)) { + return false; + } + break; + } + default: + return false; + } + return true; +} + +template +bool KdTreeAttributesDecoder::DecodePoints(int total_dimensionality, + int num_expected_points, + DecoderBuffer *in_buffer, + OutIteratorT *out_iterator) { + DynamicIntegerPointsKdTreeDecoder decoder(total_dimensionality); + if (!decoder.DecodePoints(in_buffer, *out_iterator, num_expected_points) || + decoder.num_decoded_points() != num_expected_points) { + return false; + } + return true; +} + +bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms( + DecoderBuffer *in_buffer) { + if (in_buffer->bitstream_version() >= DRACO_BITSTREAM_VERSION(2, 3)) { + // Decode quantization data for each attribute that need it. + // TODO(ostava): This should be moved to AttributeQuantizationTransform. + std::vector min_value; + for (int i = 0; i < GetNumAttributes(); ++i) { + const int att_id = GetAttributeId(i); + const PointAttribute *const att = + GetDecoder()->point_cloud()->attribute(att_id); + if (att->data_type() == DT_FLOAT32) { + const int num_components = att->num_components(); + min_value.resize(num_components); + if (!in_buffer->Decode(&min_value[0], sizeof(float) * num_components)) { + return false; + } + float max_value_dif; + if (!in_buffer->Decode(&max_value_dif)) { + return false; + } + uint8_t quantization_bits; + if (!in_buffer->Decode(&quantization_bits) || quantization_bits > 31) { + return false; + } + AttributeQuantizationTransform transform; + if (!transform.SetParameters(quantization_bits, min_value.data(), + num_components, max_value_dif)) { + return false; + } + const int num_transforms = + static_cast(attribute_quantization_transforms_.size()); + if (!transform.TransferToAttribute( + quantized_portable_attributes_[num_transforms].get())) { + return false; + } + attribute_quantization_transforms_.push_back(transform); + } + } + + // Decode transform data for signed integer attributes. + for (int i = 0; i < min_signed_values_.size(); ++i) { + int32_t val; + if (!DecodeVarint(&val, in_buffer)) { + return false; + } + min_signed_values_[i] = val; + } + return true; + } +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + // Handle old bitstream + // Figure out the total dimensionality of the point cloud + const uint32_t attribute_count = GetNumAttributes(); + uint32_t total_dimensionality = 0; // position is a required dimension + std::vector atts(attribute_count); + for (auto attribute_index = 0; + static_cast(attribute_index) < attribute_count; + attribute_index += 1) // increment the dimensionality as needed... + { + const int att_id = GetAttributeId(attribute_index); + PointAttribute *const att = GetDecoder()->point_cloud()->attribute(att_id); + const DataType data_type = att->data_type(); + const uint32_t data_size = (std::max)(0, DataTypeLength(data_type)); + const uint32_t num_components = att->num_components(); + if (data_size > 4) { + return false; + } + + atts[attribute_index] = std::make_tuple( + att, total_dimensionality, data_type, data_size, num_components); + // everything is treated as 32bit in the encoder. + total_dimensionality += num_components; + } + + const int att_id = GetAttributeId(0); + PointAttribute *const att = GetDecoder()->point_cloud()->attribute(att_id); + att->SetIdentityMapping(); + // Decode method + uint8_t method; + if (!in_buffer->Decode(&method)) { + return false; + } + if (method == KdTreeAttributesEncodingMethod::kKdTreeQuantizationEncoding) { + // This method only supports one attribute with exactly three components. + if (atts.size() != 1 || std::get<4>(atts[0]) != 3) { + return false; + } + uint8_t compression_level = 0; + if (!in_buffer->Decode(&compression_level)) { + return false; + } + uint32_t num_points = 0; + if (!in_buffer->Decode(&num_points)) { + return false; + } + att->Reset(num_points); + FloatPointsTreeDecoder decoder; + decoder.set_num_points_from_header(num_points); + PointAttributeVectorOutputIterator out_it(atts); + if (!decoder.DecodePointCloud(in_buffer, out_it)) { + return false; + } + } else if (method == KdTreeAttributesEncodingMethod::kKdTreeIntegerEncoding) { + uint8_t compression_level = 0; + if (!in_buffer->Decode(&compression_level)) { + return false; + } + if (6 < compression_level) { + DRACO_LOGE( + "KdTreeAttributesDecoder: compression level %i not supported.\n", + compression_level); + return false; + } + + uint32_t num_points; + if (!in_buffer->Decode(&num_points)) { + return false; + } + + for (auto attribute_index = 0; + static_cast(attribute_index) < attribute_count; + attribute_index += 1) { + const int att_id = GetAttributeId(attribute_index); + PointAttribute *const attr = + GetDecoder()->point_cloud()->attribute(att_id); + attr->Reset(num_points); + attr->SetIdentityMapping(); + } + + PointAttributeVectorOutputIterator out_it(atts); + + switch (compression_level) { + case 0: { + DynamicIntegerPointsKdTreeDecoder<0> decoder(total_dimensionality); + if (!decoder.DecodePoints(in_buffer, out_it)) { + return false; + } + break; + } + case 1: { + DynamicIntegerPointsKdTreeDecoder<1> decoder(total_dimensionality); + if (!decoder.DecodePoints(in_buffer, out_it)) { + return false; + } + break; + } + case 2: { + DynamicIntegerPointsKdTreeDecoder<2> decoder(total_dimensionality); + if (!decoder.DecodePoints(in_buffer, out_it)) { + return false; + } + break; + } + case 3: { + DynamicIntegerPointsKdTreeDecoder<3> decoder(total_dimensionality); + if (!decoder.DecodePoints(in_buffer, out_it)) { + return false; + } + break; + } + case 4: { + DynamicIntegerPointsKdTreeDecoder<4> decoder(total_dimensionality); + if (!decoder.DecodePoints(in_buffer, out_it)) { + return false; + } + break; + } + case 5: { + DynamicIntegerPointsKdTreeDecoder<5> decoder(total_dimensionality); + if (!decoder.DecodePoints(in_buffer, out_it)) { + return false; + } + break; + } + case 6: { + DynamicIntegerPointsKdTreeDecoder<6> decoder(total_dimensionality); + if (!decoder.DecodePoints(in_buffer, out_it)) { + return false; + } + break; + } + default: + return false; + } + } else { + // Invalid method. + return false; + } + return true; +#else + return false; +#endif +} + +template +bool KdTreeAttributesDecoder::TransformAttributeBackToSignedType( + PointAttribute *att, int num_processed_signed_components) { + typedef typename std::make_unsigned::type UnsignedType; + std::vector unsigned_val(att->num_components()); + std::vector signed_val(att->num_components()); + + for (AttributeValueIndex avi(0); avi < static_cast(att->size()); + ++avi) { + att->GetValue(avi, &unsigned_val[0]); + for (int c = 0; c < att->num_components(); ++c) { + // Up-cast |unsigned_val| to int32_t to ensure we don't overflow it for + // smaller data types. But first check that the up-casting does not cause + // signed integer overflow. + if (unsigned_val[c] > std::numeric_limits::max()) { + return false; + } + signed_val[c] = static_cast( + static_cast(unsigned_val[c]) + + min_signed_values_[num_processed_signed_components + c]); + } + att->SetAttributeValue(avi, &signed_val[0]); + } + return true; +} + +bool KdTreeAttributesDecoder::TransformAttributesToOriginalFormat() { + if (quantized_portable_attributes_.empty() && min_signed_values_.empty()) { + return true; + } + int num_processed_quantized_attributes = 0; + int num_processed_signed_components = 0; + // Dequantize attributes that needed it. + for (int i = 0; i < GetNumAttributes(); ++i) { + const int att_id = GetAttributeId(i); + PointAttribute *const att = GetDecoder()->point_cloud()->attribute(att_id); + if (att->data_type() == DT_INT32 || att->data_type() == DT_INT16 || + att->data_type() == DT_INT8) { + std::vector unsigned_val(att->num_components()); + std::vector signed_val(att->num_components()); + // Values are stored as unsigned in the attribute, make them signed again. + if (att->data_type() == DT_INT32) { + if (!TransformAttributeBackToSignedType( + att, num_processed_signed_components)) { + return false; + } + } else if (att->data_type() == DT_INT16) { + if (!TransformAttributeBackToSignedType( + att, num_processed_signed_components)) { + return false; + } + } else if (att->data_type() == DT_INT8) { + if (!TransformAttributeBackToSignedType( + att, num_processed_signed_components)) { + return false; + } + } + num_processed_signed_components += att->num_components(); + } else if (att->data_type() == DT_FLOAT32) { + // TODO(ostava): This code should be probably moved out to attribute + // transform and shared with the SequentialQuantizationAttributeDecoder. + + const PointAttribute *const src_att = + quantized_portable_attributes_[num_processed_quantized_attributes] + .get(); + + const AttributeQuantizationTransform &transform = + attribute_quantization_transforms_ + [num_processed_quantized_attributes]; + + num_processed_quantized_attributes++; + + if (GetDecoder()->options()->GetAttributeBool( + att->attribute_type(), "skip_attribute_transform", false)) { + // Attribute transform should not be performed. In this case, we replace + // the output geometry attribute with the portable attribute. + // TODO(ostava): We can potentially avoid this copy by introducing a new + // mechanism that would allow to use the final attributes as portable + // attributes for predictors that may need them. + att->CopyFrom(*src_att); + continue; + } + + // Convert all quantized values back to floats. + const int32_t max_quantized_value = + (1u << static_cast(transform.quantization_bits())) - 1; + const int num_components = att->num_components(); + const int entry_size = sizeof(float) * num_components; + const std::unique_ptr att_val(new float[num_components]); + int quant_val_id = 0; + int out_byte_pos = 0; + Dequantizer dequantizer; + if (!dequantizer.Init(transform.range(), max_quantized_value)) { + return false; + } + const uint32_t *const portable_attribute_data = + reinterpret_cast( + src_att->GetAddress(AttributeValueIndex(0))); + for (uint32_t i = 0; i < src_att->size(); ++i) { + for (int c = 0; c < num_components; ++c) { + float value = dequantizer.DequantizeFloat( + portable_attribute_data[quant_val_id++]); + value = value + transform.min_value(c); + att_val[c] = value; + } + // Store the floating point value into the attribute buffer. + att->buffer()->Write(out_byte_pos, att_val.get(), entry_size); + out_byte_pos += entry_size; + } + } + } + return true; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.h b/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.h new file mode 100644 index 0000000000..4af367a1a5 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_decoder.h @@ -0,0 +1,50 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_KD_TREE_ATTRIBUTES_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_KD_TREE_ATTRIBUTES_DECODER_H_ + +#include "draco/attributes/attribute_quantization_transform.h" +#include "draco/compression/attributes/attributes_decoder.h" + +namespace draco { + +// Decodes attributes encoded with the KdTreeAttributesEncoder. +class KdTreeAttributesDecoder : public AttributesDecoder { + public: + KdTreeAttributesDecoder(); + + protected: + bool DecodePortableAttributes(DecoderBuffer *in_buffer) override; + bool DecodeDataNeededByPortableTransforms(DecoderBuffer *in_buffer) override; + bool TransformAttributesToOriginalFormat() override; + + private: + template + bool DecodePoints(int total_dimensionality, int num_expected_points, + DecoderBuffer *in_buffer, OutIteratorT *out_iterator); + + template + bool TransformAttributeBackToSignedType(PointAttribute *att, + int num_processed_signed_components); + + std::vector + attribute_quantization_transforms_; + std::vector min_signed_values_; + std::vector> quantized_portable_attributes_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_KD_TREE_ATTRIBUTES_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.cc b/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.cc new file mode 100644 index 0000000000..b70deb9e01 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.cc @@ -0,0 +1,305 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/kd_tree_attributes_encoder.h" + +#include "draco/compression/attributes/kd_tree_attributes_shared.h" +#include "draco/compression/attributes/point_d_vector.h" +#include "draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h" +#include "draco/compression/point_cloud/algorithms/float_points_tree_encoder.h" +#include "draco/compression/point_cloud/point_cloud_encoder.h" +#include "draco/core/varint_encoding.h" + +namespace draco { + +KdTreeAttributesEncoder::KdTreeAttributesEncoder() : num_components_(0) {} + +KdTreeAttributesEncoder::KdTreeAttributesEncoder(int att_id) + : AttributesEncoder(att_id), num_components_(0) {} + +bool KdTreeAttributesEncoder::TransformAttributesToPortableFormat() { + // Convert any of the input attributes into a format that can be processed by + // the kd tree encoder (quantization of floating attributes for now). + const size_t num_points = encoder()->point_cloud()->num_points(); + int num_components = 0; + for (uint32_t i = 0; i < num_attributes(); ++i) { + const int att_id = GetAttributeId(i); + const PointAttribute *const att = + encoder()->point_cloud()->attribute(att_id); + num_components += att->num_components(); + } + num_components_ = num_components; + + // Go over all attributes and quantize them if needed. + for (uint32_t i = 0; i < num_attributes(); ++i) { + const int att_id = GetAttributeId(i); + const PointAttribute *const att = + encoder()->point_cloud()->attribute(att_id); + if (att->data_type() == DT_FLOAT32) { + // Quantization path. + AttributeQuantizationTransform attribute_quantization_transform; + const int quantization_bits = encoder()->options()->GetAttributeInt( + att_id, "quantization_bits", -1); + if (quantization_bits < 1) { + return false; + } + if (encoder()->options()->IsAttributeOptionSet(att_id, + "quantization_origin") && + encoder()->options()->IsAttributeOptionSet(att_id, + "quantization_range")) { + // Quantization settings are explicitly specified in the provided + // options. + std::vector quantization_origin(att->num_components()); + encoder()->options()->GetAttributeVector(att_id, "quantization_origin", + att->num_components(), + &quantization_origin[0]); + const float range = encoder()->options()->GetAttributeFloat( + att_id, "quantization_range", 1.f); + attribute_quantization_transform.SetParameters( + quantization_bits, quantization_origin.data(), + att->num_components(), range); + } else { + // Compute quantization settings from the attribute values. + if (!attribute_quantization_transform.ComputeParameters( + *att, quantization_bits)) { + return false; + } + } + attribute_quantization_transforms_.push_back( + attribute_quantization_transform); + // Store the quantized attribute in an array that will be used when we do + // the actual encoding of the data. + auto portable_att = + attribute_quantization_transform.InitTransformedAttribute(*att, + num_points); + attribute_quantization_transform.TransformAttribute(*att, {}, + portable_att.get()); + quantized_portable_attributes_.push_back(std::move(portable_att)); + } else if (att->data_type() == DT_INT32 || att->data_type() == DT_INT16 || + att->data_type() == DT_INT8) { + // For signed types, find the minimum value for each component. These + // values are going to be used to transform the attribute values to + // unsigned integers that can be processed by the core kd tree algorithm. + std::vector min_value(att->num_components(), + std::numeric_limits::max()); + std::vector act_value(att->num_components()); + for (AttributeValueIndex avi(0); avi < static_cast(att->size()); + ++avi) { + att->ConvertValue(avi, &act_value[0]); + for (int c = 0; c < att->num_components(); ++c) { + if (min_value[c] > act_value[c]) { + min_value[c] = act_value[c]; + } + } + } + for (int c = 0; c < att->num_components(); ++c) { + min_signed_values_.push_back(min_value[c]); + } + } + } + return true; +} + +bool KdTreeAttributesEncoder::EncodeDataNeededByPortableTransforms( + EncoderBuffer *out_buffer) { + // Store quantization settings for all attributes that need it. + for (int i = 0; i < attribute_quantization_transforms_.size(); ++i) { + attribute_quantization_transforms_[i].EncodeParameters(out_buffer); + } + + // Encode data needed for transforming signed integers to unsigned ones. + for (int i = 0; i < min_signed_values_.size(); ++i) { + EncodeVarint(min_signed_values_[i], out_buffer); + } + return true; +} + +bool KdTreeAttributesEncoder::EncodePortableAttributes( + EncoderBuffer *out_buffer) { + // Encode the data using the kd tree encoder algorithm. The data is first + // copied to a PointDVector that provides all the API expected by the core + // encoding algorithm. + + // We limit the maximum value of compression_level to 6 as we don't currently + // have viable algorithms for higher compression levels. + uint8_t compression_level = + std::min(10 - encoder()->options()->GetSpeed(), 6); + DRACO_DCHECK_LE(compression_level, 6); + + if (compression_level == 6 && num_components_ > 15) { + // Don't use compression level for CL >= 6. Axis selection is currently + // encoded using 4 bits. + compression_level = 5; + } + + out_buffer->Encode(compression_level); + + // Init PointDVector. The number of dimensions is equal to the total number + // of dimensions across all attributes. + const int num_points = encoder()->point_cloud()->num_points(); + PointDVector point_vector(num_points, num_components_); + + int num_processed_components = 0; + int num_processed_quantized_attributes = 0; + int num_processed_signed_components = 0; + // Copy data to the point vector. + for (uint32_t i = 0; i < num_attributes(); ++i) { + const int att_id = GetAttributeId(i); + const PointAttribute *const att = + encoder()->point_cloud()->attribute(att_id); + const PointAttribute *source_att = nullptr; + if (att->data_type() == DT_UINT32 || att->data_type() == DT_UINT16 || + att->data_type() == DT_UINT8 || att->data_type() == DT_INT32 || + att->data_type() == DT_INT16 || att->data_type() == DT_INT8) { + // Use the original attribute. + source_att = att; + } else if (att->data_type() == DT_FLOAT32) { + // Use the portable (quantized) attribute instead. + source_att = + quantized_portable_attributes_[num_processed_quantized_attributes] + .get(); + num_processed_quantized_attributes++; + } else { + // Unsupported data type. + return false; + } + + if (source_att == nullptr) { + return false; + } + + // Copy source_att to the vector. + if (source_att->data_type() == DT_UINT32) { + // If the data type is the same as the one used by the point vector, we + // can directly copy individual elements. + for (PointIndex pi(0); pi < num_points; ++pi) { + const AttributeValueIndex avi = source_att->mapped_index(pi); + const uint8_t *const att_value_address = source_att->GetAddress(avi); + point_vector.CopyAttribute(source_att->num_components(), + num_processed_components, pi.value(), + att_value_address); + } + } else if (source_att->data_type() == DT_INT32 || + source_att->data_type() == DT_INT16 || + source_att->data_type() == DT_INT8) { + // Signed values need to be converted to unsigned before they are stored + // in the point vector. + std::vector signed_point(source_att->num_components()); + std::vector unsigned_point(source_att->num_components()); + for (PointIndex pi(0); pi < num_points; ++pi) { + const AttributeValueIndex avi = source_att->mapped_index(pi); + source_att->ConvertValue(avi, &signed_point[0]); + for (int c = 0; c < source_att->num_components(); ++c) { + unsigned_point[c] = + signed_point[c] - + min_signed_values_[num_processed_signed_components + c]; + } + + point_vector.CopyAttribute(source_att->num_components(), + num_processed_components, pi.value(), + &unsigned_point[0]); + } + num_processed_signed_components += source_att->num_components(); + } else { + // If the data type of the attribute is different, we have to convert the + // value before we put it to the point vector. + std::vector point(source_att->num_components()); + for (PointIndex pi(0); pi < num_points; ++pi) { + const AttributeValueIndex avi = source_att->mapped_index(pi); + source_att->ConvertValue(avi, &point[0]); + point_vector.CopyAttribute(source_att->num_components(), + num_processed_components, pi.value(), + point.data()); + } + } + num_processed_components += source_att->num_components(); + } + + // Compute the maximum bit length needed for the kd tree encoding. + int num_bits = 0; + const uint32_t *data = point_vector[0]; + for (int i = 0; i < num_points * num_components_; ++i) { + if (data[i] > 0) { + const int msb = MostSignificantBit(data[i]) + 1; + if (msb > num_bits) { + num_bits = msb; + } + } + } + + switch (compression_level) { + case 6: { + DynamicIntegerPointsKdTreeEncoder<6> points_encoder(num_components_); + if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(), + num_bits, out_buffer)) { + return false; + } + break; + } + case 5: { + DynamicIntegerPointsKdTreeEncoder<5> points_encoder(num_components_); + if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(), + num_bits, out_buffer)) { + return false; + } + break; + } + case 4: { + DynamicIntegerPointsKdTreeEncoder<4> points_encoder(num_components_); + if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(), + num_bits, out_buffer)) { + return false; + } + break; + } + case 3: { + DynamicIntegerPointsKdTreeEncoder<3> points_encoder(num_components_); + if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(), + num_bits, out_buffer)) { + return false; + } + break; + } + case 2: { + DynamicIntegerPointsKdTreeEncoder<2> points_encoder(num_components_); + if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(), + num_bits, out_buffer)) { + return false; + } + break; + } + case 1: { + DynamicIntegerPointsKdTreeEncoder<1> points_encoder(num_components_); + if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(), + num_bits, out_buffer)) { + return false; + } + break; + } + case 0: { + DynamicIntegerPointsKdTreeEncoder<0> points_encoder(num_components_); + if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(), + num_bits, out_buffer)) { + return false; + } + break; + } + // Compression level and/or encoding speed seem wrong. + default: + return false; + } + return true; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.h b/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.h new file mode 100644 index 0000000000..80748e0bf5 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_encoder.h @@ -0,0 +1,51 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_KD_TREE_ATTRIBUTES_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_KD_TREE_ATTRIBUTES_ENCODER_H_ + +#include "draco/attributes/attribute_quantization_transform.h" +#include "draco/compression/attributes/attributes_encoder.h" +#include "draco/compression/config/compression_shared.h" + +namespace draco { + +// Encodes all attributes of a given PointCloud using one of the available +// Kd-tree compression methods. +// See compression/point_cloud/point_cloud_kd_tree_encoder.h for more details. +class KdTreeAttributesEncoder : public AttributesEncoder { + public: + KdTreeAttributesEncoder(); + explicit KdTreeAttributesEncoder(int att_id); + + uint8_t GetUniqueId() const override { return KD_TREE_ATTRIBUTE_ENCODER; } + + protected: + bool TransformAttributesToPortableFormat() override; + bool EncodePortableAttributes(EncoderBuffer *out_buffer) override; + bool EncodeDataNeededByPortableTransforms(EncoderBuffer *out_buffer) override; + + private: + std::vector + attribute_quantization_transforms_; + // Min signed values are used to transform signed integers into unsigned ones + // (by subtracting the min signed value for each component). + std::vector min_signed_values_; + std::vector> quantized_portable_attributes_; + int num_components_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_KD_TREE_ATTRIBUTES_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_shared.h b/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_shared.h new file mode 100644 index 0000000000..94841a91d9 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/kd_tree_attributes_shared.h @@ -0,0 +1,28 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_KD_TREE_ATTRIBUTES_SHARED_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_KD_TREE_ATTRIBUTES_SHARED_H_ + +namespace draco { + +// Defines types of kD-tree compression +enum KdTreeAttributesEncodingMethod { + kKdTreeQuantizationEncoding = 0, + kKdTreeIntegerEncoding +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_KD_TREE_ATTRIBUTES_SHARED_H_ diff --git a/third-party/draco/src/draco/compression/attributes/linear_sequencer.h b/third-party/draco/src/draco/compression/attributes/linear_sequencer.h new file mode 100644 index 0000000000..7d9b526419 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/linear_sequencer.h @@ -0,0 +1,51 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_LINEAR_SEQUENCER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_LINEAR_SEQUENCER_H_ + +#include "draco/compression/attributes/points_sequencer.h" + +namespace draco { + +// A simple sequencer that generates a linear sequence [0, num_points - 1]. +// I.e., the order of the points is preserved for the input data. +class LinearSequencer : public PointsSequencer { + public: + explicit LinearSequencer(int32_t num_points) : num_points_(num_points) {} + + bool UpdatePointToAttributeIndexMapping(PointAttribute *attribute) override { + attribute->SetIdentityMapping(); + return true; + } + + protected: + bool GenerateSequenceInternal() override { + if (num_points_ < 0) { + return false; + } + out_point_ids()->resize(num_points_); + for (int i = 0; i < num_points_; ++i) { + out_point_ids()->at(i) = PointIndex(i); + } + return true; + } + + private: + int32_t num_points_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_LINEAR_SEQUENCER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h b/third-party/draco/src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h new file mode 100644 index 0000000000..9a358e4473 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h @@ -0,0 +1,58 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_MESH_ATTRIBUTE_INDICES_ENCODING_DATA_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_MESH_ATTRIBUTE_INDICES_ENCODING_DATA_H_ + +#include + +#include + +#include "draco/attributes/geometry_indices.h" + +namespace draco { + +// Data used for encoding and decoding of mesh attributes. +struct MeshAttributeIndicesEncodingData { + MeshAttributeIndicesEncodingData() : num_values(0) {} + + void Init(int num_vertices) { + vertex_to_encoded_attribute_value_index_map.resize(num_vertices); + + // We expect to store one value for each vertex. + encoded_attribute_value_index_to_corner_map.reserve(num_vertices); + } + + // Array for storing the corner ids in the order their associated attribute + // entries were encoded/decoded. For every encoded attribute value entry we + // store exactly one corner. I.e., this is the mapping between an encoded + // attribute entry ids and corner ids. This map is needed for example by + // prediction schemes. Note that not all corners are included in this map, + // e.g., if multiple corners share the same attribute value, only one of these + // corners will be usually included. + std::vector encoded_attribute_value_index_to_corner_map; + + // Map for storing encoding order of attribute entries for each vertex. + // i.e. Mapping between vertices and their corresponding attribute entry ids + // that are going to be used by the decoder. + // -1 if an attribute entry hasn't been encoded/decoded yet. + std::vector vertex_to_encoded_attribute_value_index_map; + + // Total number of encoded/decoded attribute entries. + int num_values; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_MESH_ATTRIBUTE_INDICES_ENCODING_DATA_H_ diff --git a/third-party/draco/src/draco/compression/attributes/normal_compression_utils.h b/third-party/draco/src/draco/compression/attributes/normal_compression_utils.h new file mode 100644 index 0000000000..b717d0dbef --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/normal_compression_utils.h @@ -0,0 +1,372 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Utilities for converting unit vectors to octahedral coordinates and back. +// For more details about octahedral coordinates, see for example Cigolle +// et al.'14 “A Survey of Efficient Representations for Independent Unit +// Vectors”. +// +// In short this is motivated by an octahedron inscribed into a sphere. The +// direction of the normal vector can be defined by a point on the octahedron. +// On the right hemisphere (x > 0) this point is projected onto the x = 0 plane, +// that is, the right side of the octahedron forms a diamond like shape. The +// left side of the octahedron is also projected onto the x = 0 plane, however, +// in this case we flap the triangles of the diamond outward. Afterwards we +// shift the resulting square such that all values are positive. +// +// Important values in this file: +// * q: number of quantization bits +// * max_quantized_value: the max value representable with q bits (odd) +// * max_value: max value of the diamond = max_quantized_value - 1 (even) +// * center_value: center of the diamond after shift +// +// Note that the parameter space is somewhat periodic, e.g. (0, 0) == +// (max_value, max_value), which is also why the diamond is one smaller than the +// maximal representable value in order to have an odd range of values. + +#ifndef DRACO_COMPRESSION_ATTRIBUTES_NORMAL_COMPRESSION_UTILS_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_NORMAL_COMPRESSION_UTILS_H_ + +#include + +#include +#include + +#include "draco/core/macros.h" + +namespace draco { + +class OctahedronToolBox { + public: + OctahedronToolBox() + : quantization_bits_(-1), + max_quantized_value_(-1), + max_value_(-1), + dequantization_scale_(1.f), + center_value_(-1) {} + + bool SetQuantizationBits(int32_t q) { + if (q < 2 || q > 30) { + return false; + } + quantization_bits_ = q; + max_quantized_value_ = (1u << quantization_bits_) - 1; + max_value_ = max_quantized_value_ - 1; + dequantization_scale_ = 2.f / max_value_; + center_value_ = max_value_ / 2; + return true; + } + bool IsInitialized() const { return quantization_bits_ != -1; } + + // Convert all edge points in the top left and bottom right quadrants to + // their corresponding position in the bottom left and top right quadrants. + // Convert all corner edge points to the top right corner. + inline void CanonicalizeOctahedralCoords(int32_t s, int32_t t, int32_t *out_s, + int32_t *out_t) const { + if ((s == 0 && t == 0) || (s == 0 && t == max_value_) || + (s == max_value_ && t == 0)) { + s = max_value_; + t = max_value_; + } else if (s == 0 && t > center_value_) { + t = center_value_ - (t - center_value_); + } else if (s == max_value_ && t < center_value_) { + t = center_value_ + (center_value_ - t); + } else if (t == max_value_ && s < center_value_) { + s = center_value_ + (center_value_ - s); + } else if (t == 0 && s > center_value_) { + s = center_value_ - (s - center_value_); + } + + *out_s = s; + *out_t = t; + } + + // Converts an integer vector to octahedral coordinates. + // Precondition: |int_vec| abs sum must equal center value. + inline void IntegerVectorToQuantizedOctahedralCoords(const int32_t *int_vec, + int32_t *out_s, + int32_t *out_t) const { + DRACO_DCHECK_EQ( + std::abs(int_vec[0]) + std::abs(int_vec[1]) + std::abs(int_vec[2]), + center_value_); + int32_t s, t; + if (int_vec[0] >= 0) { + // Right hemisphere. + s = (int_vec[1] + center_value_); + t = (int_vec[2] + center_value_); + } else { + // Left hemisphere. + if (int_vec[1] < 0) { + s = std::abs(int_vec[2]); + } else { + s = (max_value_ - std::abs(int_vec[2])); + } + if (int_vec[2] < 0) { + t = std::abs(int_vec[1]); + } else { + t = (max_value_ - std::abs(int_vec[1])); + } + } + CanonicalizeOctahedralCoords(s, t, out_s, out_t); + } + + template + void FloatVectorToQuantizedOctahedralCoords(const T *vector, int32_t *out_s, + int32_t *out_t) const { + const double abs_sum = std::abs(static_cast(vector[0])) + + std::abs(static_cast(vector[1])) + + std::abs(static_cast(vector[2])); + + // Adjust values such that abs sum equals 1. + double scaled_vector[3]; + if (abs_sum > 1e-6) { + // Scale needed to project the vector to the surface of an octahedron. + const double scale = 1.0 / abs_sum; + scaled_vector[0] = vector[0] * scale; + scaled_vector[1] = vector[1] * scale; + scaled_vector[2] = vector[2] * scale; + } else { + scaled_vector[0] = 1.0; + scaled_vector[1] = 0; + scaled_vector[2] = 0; + } + + // Scale vector such that the sum equals the center value. + int32_t int_vec[3]; + int_vec[0] = + static_cast(floor(scaled_vector[0] * center_value_ + 0.5)); + int_vec[1] = + static_cast(floor(scaled_vector[1] * center_value_ + 0.5)); + // Make sure the sum is exactly the center value. + int_vec[2] = center_value_ - std::abs(int_vec[0]) - std::abs(int_vec[1]); + if (int_vec[2] < 0) { + // If the sum of first two coordinates is too large, we need to decrease + // the length of one of the coordinates. + if (int_vec[1] > 0) { + int_vec[1] += int_vec[2]; + } else { + int_vec[1] -= int_vec[2]; + } + int_vec[2] = 0; + } + // Take care of the sign. + if (scaled_vector[2] < 0) { + int_vec[2] *= -1; + } + + IntegerVectorToQuantizedOctahedralCoords(int_vec, out_s, out_t); + } + + // Normalize |vec| such that its abs sum is equal to the center value; + template + void CanonicalizeIntegerVector(T *vec) const { + static_assert(std::is_integral::value, "T must be an integral type."); + static_assert(std::is_signed::value, "T must be a signed type."); + const int64_t abs_sum = static_cast(std::abs(vec[0])) + + static_cast(std::abs(vec[1])) + + static_cast(std::abs(vec[2])); + + if (abs_sum == 0) { + vec[0] = center_value_; // vec[1] == v[2] == 0 + } else { + vec[0] = + (static_cast(vec[0]) * static_cast(center_value_)) / + abs_sum; + vec[1] = + (static_cast(vec[1]) * static_cast(center_value_)) / + abs_sum; + if (vec[2] >= 0) { + vec[2] = center_value_ - std::abs(vec[0]) - std::abs(vec[1]); + } else { + vec[2] = -(center_value_ - std::abs(vec[0]) - std::abs(vec[1])); + } + } + } + + inline void QuantizedOctahedralCoordsToUnitVector(int32_t in_s, int32_t in_t, + float *out_vector) const { + OctahedralCoordsToUnitVector(in_s * dequantization_scale_ - 1.f, + in_t * dequantization_scale_ - 1.f, + out_vector); + } + + // |s| and |t| are expected to be signed values. + inline bool IsInDiamond(const int32_t &s, const int32_t &t) const { + // Expect center already at origin. + DRACO_DCHECK_LE(s, center_value_); + DRACO_DCHECK_LE(t, center_value_); + DRACO_DCHECK_GE(s, -center_value_); + DRACO_DCHECK_GE(t, -center_value_); + const uint32_t st = + static_cast(std::abs(s)) + static_cast(std::abs(t)); + return st <= center_value_; + } + + void InvertDiamond(int32_t *s, int32_t *t) const { + // Expect center already at origin. + DRACO_DCHECK_LE(*s, center_value_); + DRACO_DCHECK_LE(*t, center_value_); + DRACO_DCHECK_GE(*s, -center_value_); + DRACO_DCHECK_GE(*t, -center_value_); + int32_t sign_s = 0; + int32_t sign_t = 0; + if (*s >= 0 && *t >= 0) { + sign_s = 1; + sign_t = 1; + } else if (*s <= 0 && *t <= 0) { + sign_s = -1; + sign_t = -1; + } else { + sign_s = (*s > 0) ? 1 : -1; + sign_t = (*t > 0) ? 1 : -1; + } + + // Perform the addition and subtraction using unsigned integers to avoid + // signed integer overflows for bad data. Note that the result will be + // unchanged for non-overflowing cases. + const uint32_t corner_point_s = sign_s * center_value_; + const uint32_t corner_point_t = sign_t * center_value_; + uint32_t us = *s; + uint32_t ut = *t; + us = us + us - corner_point_s; + ut = ut + ut - corner_point_t; + if (sign_s * sign_t >= 0) { + uint32_t temp = us; + us = -ut; + ut = -temp; + } else { + std::swap(us, ut); + } + us = us + corner_point_s; + ut = ut + corner_point_t; + + *s = us; + *t = ut; + *s /= 2; + *t /= 2; + } + + void InvertDirection(int32_t *s, int32_t *t) const { + // Expect center already at origin. + DRACO_DCHECK_LE(*s, center_value_); + DRACO_DCHECK_LE(*t, center_value_); + DRACO_DCHECK_GE(*s, -center_value_); + DRACO_DCHECK_GE(*t, -center_value_); + *s *= -1; + *t *= -1; + this->InvertDiamond(s, t); + } + + // For correction values. + int32_t ModMax(int32_t x) const { + if (x > this->center_value()) { + return x - this->max_quantized_value(); + } + if (x < -this->center_value()) { + return x + this->max_quantized_value(); + } + return x; + } + + // For correction values. + int32_t MakePositive(int32_t x) const { + DRACO_DCHECK_LE(x, this->center_value() * 2); + if (x < 0) { + return x + this->max_quantized_value(); + } + return x; + } + + int32_t quantization_bits() const { return quantization_bits_; } + int32_t max_quantized_value() const { return max_quantized_value_; } + int32_t max_value() const { return max_value_; } + int32_t center_value() const { return center_value_; } + + private: + inline void OctahedralCoordsToUnitVector(float in_s_scaled, float in_t_scaled, + float *out_vector) const { + // Background about the encoding: + // A normal is encoded in a normalized space depicted below. The + // encoding correponds to an octahedron that is unwrapped to a 2D plane. + // During encoding, a normal is projected to the surface of the octahedron + // and the projection is then unwrapped to the 2D plane. Decoding is the + // reverse of this process. + // All points in the central diamond are located on triangles on the + // right "hemisphere" of the octahedron while all points outside of the + // diamond are on the left hemisphere (basically, they would have to be + // wrapped along the diagonal edges to form the octahedron). The central + // point corresponds to the right most vertex of the octahedron and all + // corners of the plane correspond to the left most vertex of the + // octahedron. + // + // t + // ^ *-----*-----* + // | | /|\ | + // | / | \ | + // | / | \ | + // | / | \ | + // *-----*---- * + // | \ | / | + // | \ | / | + // | \ | / | + // | \|/ | + // *-----*-----* --> s + + // Note that the input |in_s_scaled| and |in_t_scaled| are already scaled to + // <-1, 1> range. This way, the central point is at coordinate (0, 0). + float y = in_s_scaled; + float z = in_t_scaled; + + // Remaining coordinate can be computed by projecting the (y, z) values onto + // the surface of the octahedron. + const float x = 1.f - std::abs(y) - std::abs(z); + + // |x| is essentially a signed distance from the diagonal edges of the + // diamond shown on the figure above. It is positive for all points in the + // diamond (right hemisphere) and negative for all points outside the + // diamond (left hemisphere). For all points on the left hemisphere we need + // to update their (y, z) coordinates to account for the wrapping along + // the edges of the diamond. + float x_offset = -x; + x_offset = x_offset < 0 ? 0 : x_offset; + + // This will do nothing for the points on the right hemisphere but it will + // mirror the (y, z) location along the nearest diagonal edge of the + // diamond. + y += y < 0 ? x_offset : -x_offset; + z += z < 0 ? x_offset : -x_offset; + + // Normalize the computed vector. + const float norm_squared = x * x + y * y + z * z; + if (norm_squared < 1e-6) { + out_vector[0] = 0; + out_vector[1] = 0; + out_vector[2] = 0; + } else { + const float d = 1.0f / std::sqrt(norm_squared); + out_vector[0] = x * d; + out_vector[1] = y * d; + out_vector[2] = z * d; + } + } + + int32_t quantization_bits_; + int32_t max_quantized_value_; + int32_t max_value_; + float dequantization_scale_; + int32_t center_value_; +}; +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_NORMAL_COMPRESSION_UTILS_H_ diff --git a/third-party/draco/src/draco/compression/attributes/point_d_vector.h b/third-party/draco/src/draco/compression/attributes/point_d_vector.h new file mode 100644 index 0000000000..6ceb454ae0 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/point_d_vector.h @@ -0,0 +1,287 @@ +// Copyright 2018 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef DRACO_COMPRESSION_ATTRIBUTES_POINT_D_VECTOR_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_POINT_D_VECTOR_H_ + +#include +#include +#include +#include +#include + +#include "draco/core/macros.h" + +namespace draco { + +// The main class of this file is PointDVector providing an interface similar to +// std::vector for arbitrary number of dimensions (without a template +// argument). PointDVectorIterator is a random access iterator, which allows for +// compatibility with existing algorithms. PseudoPointD provides for a view on +// the individual items in a contiguous block of memory, which is compatible +// with the swap function and is returned by a dereference of +// PointDVectorIterator. Swap functions provide for compatibility/specialization +// that allows these classes to work with currently utilized STL functions. + +// This class allows for swap functionality from the RandomIterator +// It seems problematic to bring this inside PointDVector due to templating. +template +class PseudoPointD { + public: + PseudoPointD(internal_t *mem, internal_t dimension) + : mem_(mem), dimension_(dimension) {} + + // Specifically copies referenced memory + void swap(PseudoPointD &other) noexcept { + for (internal_t dim = 0; dim < dimension_; dim += 1) { + std::swap(mem_[dim], other.mem_[dim]); + } + } + + PseudoPointD(const PseudoPointD &other) + : mem_(other.mem_), dimension_(other.dimension_) {} + + const internal_t &operator[](const size_t &n) const { + DRACO_DCHECK_LT(n, dimension_); + return mem_[n]; + } + internal_t &operator[](const size_t &n) { + DRACO_DCHECK_LT(n, dimension_); + return mem_[n]; + } + + bool operator==(const PseudoPointD &other) const { + for (auto dim = 0; dim < dimension_; dim += 1) { + if (mem_[dim] != other.mem_[dim]) { + return false; + } + } + return true; + } + bool operator!=(const PseudoPointD &other) const { + return !this->operator==(other); + } + + private: + internal_t *const mem_; + const internal_t dimension_; +}; + +// It seems problematic to bring this inside PointDVector due to templating. +template +void swap(draco::PseudoPointD &&a, + draco::PseudoPointD &&b) noexcept { + a.swap(b); +}; +template +void swap(draco::PseudoPointD &a, + draco::PseudoPointD &b) noexcept { + a.swap(b); +}; + +template +class PointDVector { + public: + PointDVector(const uint32_t n_items, const uint32_t dimensionality) + : n_items_(n_items), + dimensionality_(dimensionality), + item_size_bytes_(dimensionality * sizeof(internal_t)), + data_(n_items * dimensionality), + data0_(data_.data()) {} + // random access iterator + class PointDVectorIterator { + friend class PointDVector; + + public: + // Iterator traits expected by std libraries. + using iterator_category = std::random_access_iterator_tag; + using value_type = size_t; + using difference_type = size_t; + using pointer = PointDVector *; + using reference = PointDVector &; + + // std::iter_swap is called inside of std::partition and needs this + // specialized support + PseudoPointD operator*() const { + return PseudoPointD(vec_->data0_ + item_ * dimensionality_, + dimensionality_); + } + const PointDVectorIterator &operator++() { + item_ += 1; + return *this; + } + const PointDVectorIterator &operator--() { + item_ -= 1; + return *this; + } + PointDVectorIterator operator++(int32_t) { + PointDVectorIterator copy(*this); + item_ += 1; + return copy; + } + PointDVectorIterator operator--(int32_t) { + PointDVectorIterator copy(*this); + item_ -= 1; + return copy; + } + PointDVectorIterator &operator=(const PointDVectorIterator &other) { + this->item_ = other.item_; + return *this; + } + + bool operator==(const PointDVectorIterator &ref) const { + return item_ == ref.item_; + } + bool operator!=(const PointDVectorIterator &ref) const { + return item_ != ref.item_; + } + bool operator<(const PointDVectorIterator &ref) const { + return item_ < ref.item_; + } + bool operator>(const PointDVectorIterator &ref) const { + return item_ > ref.item_; + } + bool operator<=(const PointDVectorIterator &ref) const { + return item_ <= ref.item_; + } + bool operator>=(const PointDVectorIterator &ref) const { + return item_ >= ref.item_; + } + + PointDVectorIterator operator+(const int32_t &add) const { + PointDVectorIterator copy(vec_, item_ + add); + return copy; + } + PointDVectorIterator &operator+=(const int32_t &add) { + item_ += add; + return *this; + } + PointDVectorIterator operator-(const int32_t &sub) const { + PointDVectorIterator copy(vec_, item_ - sub); + return copy; + } + size_t operator-(const PointDVectorIterator &sub) const { + return (item_ - sub.item_); + } + + PointDVectorIterator &operator-=(const int32_t &sub) { + item_ -= sub; + return *this; + } + + internal_t *operator[](const size_t &n) const { + return vec_->data0_ + (item_ + n) * dimensionality_; + } + + protected: + explicit PointDVectorIterator(PointDVector *vec, size_t start_item) + : item_(start_item), vec_(vec), dimensionality_(vec->dimensionality_) {} + + private: + size_t item_; // this counts the item that should be referenced. + PointDVector *const vec_; // the thing that we're iterating on + const uint32_t dimensionality_; // local copy from vec_ + }; + + PointDVectorIterator begin() { return PointDVectorIterator(this, 0); } + PointDVectorIterator end() { return PointDVectorIterator(this, n_items_); } + + // operator[] allows for unprotected user-side usage of operator[] on the + // return value AS IF it were a natively indexable type like Point3* + internal_t *operator[](const uint32_t index) { + DRACO_DCHECK_LT(index, n_items_); + return data0_ + index * dimensionality_; + } + const internal_t *operator[](const uint32_t index) const { + DRACO_DCHECK_LT(index, n_items_); + return data0_ + index * dimensionality_; + } + + uint32_t size() const { return n_items_; } + size_t GetBufferSize() const { return data_.size(); } + + // copy a single contiguous 'item' from one PointDVector into this one. + void CopyItem(const PointDVector &source, const internal_t source_index, + const internal_t destination_index) { + DRACO_DCHECK(&source != this || + (&source == this && source_index != destination_index)); + DRACO_DCHECK_LT(destination_index, n_items_); + DRACO_DCHECK_LT(source_index, source.n_items_); + + // DRACO_DCHECK_EQ(source.n_items_, n_items_); // not technically necessary + DRACO_DCHECK_EQ(source.dimensionality_, dimensionality_); + + const internal_t *ref = source[source_index]; + internal_t *const dest = this->operator[](destination_index); + std::memcpy(dest, ref, item_size_bytes_); + } + + // Copy data directly off of an attribute buffer interleaved into internal + // memory. + void CopyAttribute( + // The dimensionality of the attribute being integrated + const internal_t attribute_dimensionality, + // The offset in dimensions to insert this attribute. + const internal_t offset_dimensionality, const internal_t index, + // The direct pointer to the data + const void *const attribute_item_data) { + // chunk copy + const size_t copy_size = sizeof(internal_t) * attribute_dimensionality; + + // a multiply and add can be optimized away with an iterator + std::memcpy(data0_ + index * dimensionality_ + offset_dimensionality, + attribute_item_data, copy_size); + } + // Copy data off of a contiguous buffer interleaved into internal memory + void CopyAttribute( + // The dimensionality of the attribute being integrated + const internal_t attribute_dimensionality, + // The offset in dimensions to insert this attribute. + const internal_t offset_dimensionality, + const internal_t *const attribute_mem) { + DRACO_DCHECK_LT(offset_dimensionality, + dimensionality_ - attribute_dimensionality); + // degenerate case block copy the whole buffer. + if (dimensionality_ == attribute_dimensionality) { + DRACO_DCHECK_EQ(offset_dimensionality, 0); + const size_t copy_size = + sizeof(internal_t) * attribute_dimensionality * n_items_; + std::memcpy(data0_, attribute_mem, copy_size); + } else { // chunk copy + const size_t copy_size = sizeof(internal_t) * attribute_dimensionality; + internal_t *internal_data; + const internal_t *attribute_data; + internal_t item; + for (internal_data = data0_ + offset_dimensionality, + attribute_data = attribute_mem, item = 0; + item < n_items_; internal_data += dimensionality_, + attribute_data += attribute_dimensionality, item += 1) { + std::memcpy(internal_data, attribute_data, copy_size); + } + } + } + + private: + // internal parameters. + const uint32_t n_items_; + const uint32_t dimensionality_; // The dimension of the points in the buffer + const uint32_t item_size_bytes_; + std::vector data_; // contiguously stored data. Never resized. + internal_t *const data0_; // raw pointer to base data. +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_POINT_D_VECTOR_H_ diff --git a/third-party/draco/src/draco/compression/attributes/point_d_vector_test.cc b/third-party/draco/src/draco/compression/attributes/point_d_vector_test.cc new file mode 100644 index 0000000000..59f28f80b0 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/point_d_vector_test.cc @@ -0,0 +1,360 @@ +// Copyright 2018 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/point_d_vector.h" + +#include "draco/compression/point_cloud/algorithms/point_cloud_types.h" +#include "draco/core/draco_test_base.h" + +namespace draco { + +class PointDVectorTest : public ::testing::Test { + protected: + template + void TestIntegrity() {} + template + void TestSize() { + for (uint32_t n_items = 0; n_items <= 10; ++n_items) { + for (uint32_t dimensionality = 1; dimensionality <= 10; + ++dimensionality) { + draco::PointDVector var(n_items, dimensionality); + ASSERT_EQ(n_items, var.size()); + ASSERT_EQ(n_items * dimensionality, var.GetBufferSize()); + } + } + } + template + void TestContentsContiguous() { + for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) { + for (uint32_t dimensionality = 1; dimensionality < 10; + dimensionality += 2) { + for (uint32_t att_dimensionality = 1; + att_dimensionality <= dimensionality; att_dimensionality += 2) { + for (uint32_t offset_dimensionality = 0; + offset_dimensionality < dimensionality - att_dimensionality; + ++offset_dimensionality) { + PointDVector var(n_items, dimensionality); + + std::vector att(n_items * att_dimensionality); + for (PT val = 0; val < n_items; val += 1) { + for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) { + att[val * att_dimensionality + att_dim] = val; + } + } + const PT *const attribute_data = att.data(); + + var.CopyAttribute(att_dimensionality, offset_dimensionality, + attribute_data); + + for (PT val = 0; val < n_items; val += 1) { + for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) { + ASSERT_EQ(var[val][offset_dimensionality + att_dim], val); + } + } + } + } + } + } + } + template + void TestContentsDiscrete() { + for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) { + for (uint32_t dimensionality = 1; dimensionality < 10; + dimensionality += 2) { + for (uint32_t att_dimensionality = 1; + att_dimensionality <= dimensionality; att_dimensionality += 2) { + for (uint32_t offset_dimensionality = 0; + offset_dimensionality < dimensionality - att_dimensionality; + ++offset_dimensionality) { + PointDVector var(n_items, dimensionality); + + std::vector att(n_items * att_dimensionality); + for (PT val = 0; val < n_items; val += 1) { + for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) { + att[val * att_dimensionality + att_dim] = val; + } + } + const PT *const attribute_data = att.data(); + + for (PT item = 0; item < n_items; item += 1) { + var.CopyAttribute(att_dimensionality, offset_dimensionality, item, + attribute_data + item * att_dimensionality); + } + + for (PT val = 0; val < n_items; val += 1) { + for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) { + ASSERT_EQ(var[val][offset_dimensionality + att_dim], val); + } + } + } + } + } + } + } + + template + void TestContentsCopy() { + for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) { + for (uint32_t dimensionality = 1; dimensionality < 10; + dimensionality += 2) { + for (uint32_t att_dimensionality = 1; + att_dimensionality <= dimensionality; att_dimensionality += 2) { + for (uint32_t offset_dimensionality = 0; + offset_dimensionality < dimensionality - att_dimensionality; + ++offset_dimensionality) { + PointDVector var(n_items, dimensionality); + PointDVector dest(n_items, dimensionality); + + std::vector att(n_items * att_dimensionality); + for (PT val = 0; val < n_items; val += 1) { + for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) { + att[val * att_dimensionality + att_dim] = val; + } + } + const PT *const attribute_data = att.data(); + + var.CopyAttribute(att_dimensionality, offset_dimensionality, + attribute_data); + + for (PT item = 0; item < n_items; item += 1) { + dest.CopyItem(var, item, item); + } + + for (PT val = 0; val < n_items; val += 1) { + for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) { + ASSERT_EQ(var[val][offset_dimensionality + att_dim], val); + ASSERT_EQ(dest[val][offset_dimensionality + att_dim], val); + } + } + } + } + } + } + } + template + void TestIterator() { + for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) { + for (uint32_t dimensionality = 1; dimensionality < 10; + dimensionality += 2) { + for (uint32_t att_dimensionality = 1; + att_dimensionality <= dimensionality; att_dimensionality += 2) { + for (uint32_t offset_dimensionality = 0; + offset_dimensionality < dimensionality - att_dimensionality; + ++offset_dimensionality) { + PointDVector var(n_items, dimensionality); + PointDVector dest(n_items, dimensionality); + + std::vector att(n_items * att_dimensionality); + for (PT val = 0; val < n_items; val += 1) { + for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) { + att[val * att_dimensionality + att_dim] = val; + } + } + const PT *const attribute_data = att.data(); + + var.CopyAttribute(att_dimensionality, offset_dimensionality, + attribute_data); + + for (PT item = 0; item < n_items; item += 1) { + dest.CopyItem(var, item, item); + } + + auto V0 = var.begin(); + auto VE = var.end(); + auto D0 = dest.begin(); + auto DE = dest.end(); + + while (V0 != VE && D0 != DE) { + ASSERT_EQ(*D0, *V0); // compare PseudoPointD + // verify elemental values + for (auto index = 0; index < dimensionality; index += 1) { + ASSERT_EQ((*D0)[index], (*V0)[index]); + } + ++V0; + ++D0; + } + + for (PT val = 0; val < n_items; val += 1) { + for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) { + ASSERT_EQ(var[val][offset_dimensionality + att_dim], val); + ASSERT_EQ(dest[val][offset_dimensionality + att_dim], val); + } + } + } + } + } + } + } + template + void TestPoint3Iterator() { + for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) { + const uint32_t dimensionality = 3; + // for (uint32_t dimensionality = 1; dimensionality < 10; + // dimensionality += 2) { + const uint32_t att_dimensionality = 3; + // for (uint32_t att_dimensionality = 1; + // att_dimensionality <= dimensionality; att_dimensionality += 2) { + for (uint32_t offset_dimensionality = 0; + offset_dimensionality < dimensionality - att_dimensionality; + ++offset_dimensionality) { + PointDVector var(n_items, dimensionality); + PointDVector dest(n_items, dimensionality); + + std::vector att(n_items * att_dimensionality); + std::vector att3(n_items); + for (PT val = 0; val < n_items; val += 1) { + att3[val][0] = val; + att3[val][1] = val; + att3[val][2] = val; + for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) { + att[val * att_dimensionality + att_dim] = val; + } + } + const PT *const attribute_data = att.data(); + + var.CopyAttribute(att_dimensionality, offset_dimensionality, + attribute_data); + + for (PT item = 0; item < n_items; item += 1) { + dest.CopyItem(var, item, item); + } + + auto aV0 = att3.begin(); + auto aVE = att3.end(); + auto V0 = var.begin(); + auto VE = var.end(); + auto D0 = dest.begin(); + auto DE = dest.end(); + + while (aV0 != aVE && V0 != VE && D0 != DE) { + ASSERT_EQ(*D0, *V0); // compare PseudoPointD + // verify elemental values + for (auto index = 0; index < dimensionality; index += 1) { + ASSERT_EQ((*D0)[index], (*V0)[index]); + ASSERT_EQ((*D0)[index], (*aV0)[index]); + ASSERT_EQ((*aV0)[index], (*V0)[index]); + } + ++aV0; + ++V0; + ++D0; + } + + for (PT val = 0; val < n_items; val += 1) { + for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) { + ASSERT_EQ(var[val][offset_dimensionality + att_dim], val); + ASSERT_EQ(dest[val][offset_dimensionality + att_dim], val); + } + } + } + } + } + + void TestPseudoPointDSwap() { + draco::Point3ui val = {0, 1, 2}; + draco::Point3ui dest = {10, 11, 12}; + draco::PseudoPointD val_src1(&val[0], 3); + draco::PseudoPointD dest_src1(&dest[0], 3); + + ASSERT_EQ(val_src1[0], 0); + ASSERT_EQ(val_src1[1], 1); + ASSERT_EQ(val_src1[2], 2); + ASSERT_EQ(dest_src1[0], 10); + ASSERT_EQ(dest_src1[1], 11); + ASSERT_EQ(dest_src1[2], 12); + + ASSERT_NE(val_src1, dest_src1); + + swap(val_src1, dest_src1); + + ASSERT_EQ(dest_src1[0], 0); + ASSERT_EQ(dest_src1[1], 1); + ASSERT_EQ(dest_src1[2], 2); + ASSERT_EQ(val_src1[0], 10); + ASSERT_EQ(val_src1[1], 11); + ASSERT_EQ(val_src1[2], 12); + + ASSERT_NE(val_src1, dest_src1); + } + void TestPseudoPointDEquality() { + draco::Point3ui val = {0, 1, 2}; + draco::Point3ui dest = {0, 1, 2}; + draco::PseudoPointD val_src1(&val[0], 3); + draco::PseudoPointD val_src2(&val[0], 3); + draco::PseudoPointD dest_src1(&dest[0], 3); + draco::PseudoPointD dest_src2(&dest[0], 3); + + ASSERT_EQ(val_src1, val_src1); + ASSERT_EQ(val_src1, val_src2); + ASSERT_EQ(dest_src1, val_src1); + ASSERT_EQ(dest_src1, val_src2); + ASSERT_EQ(val_src2, val_src1); + ASSERT_EQ(val_src2, val_src2); + ASSERT_EQ(dest_src2, val_src1); + ASSERT_EQ(dest_src2, val_src2); + + for (auto i = 0; i < 3; i++) { + ASSERT_EQ(val_src1[i], val_src1[i]); + ASSERT_EQ(val_src1[i], val_src2[i]); + ASSERT_EQ(dest_src1[i], val_src1[i]); + ASSERT_EQ(dest_src1[i], val_src2[i]); + ASSERT_EQ(val_src2[i], val_src1[i]); + ASSERT_EQ(val_src2[i], val_src2[i]); + ASSERT_EQ(dest_src2[i], val_src1[i]); + ASSERT_EQ(dest_src2[i], val_src2[i]); + } + } + void TestPseudoPointDInequality() { + draco::Point3ui val = {0, 1, 2}; + draco::Point3ui dest = {1, 2, 3}; + draco::PseudoPointD val_src1(&val[0], 3); + draco::PseudoPointD val_src2(&val[0], 3); + draco::PseudoPointD dest_src1(&dest[0], 3); + draco::PseudoPointD dest_src2(&dest[0], 3); + + ASSERT_EQ(val_src1, val_src1); + ASSERT_EQ(val_src1, val_src2); + ASSERT_NE(dest_src1, val_src1); + ASSERT_NE(dest_src1, val_src2); + ASSERT_EQ(val_src2, val_src1); + ASSERT_EQ(val_src2, val_src2); + ASSERT_NE(dest_src2, val_src1); + ASSERT_NE(dest_src2, val_src2); + + for (auto i = 0; i < 3; i++) { + ASSERT_EQ(val_src1[i], val_src1[i]); + ASSERT_EQ(val_src1[i], val_src2[i]); + ASSERT_NE(dest_src1[i], val_src1[i]); + ASSERT_NE(dest_src1[i], val_src2[i]); + ASSERT_EQ(val_src2[i], val_src1[i]); + ASSERT_EQ(val_src2[i], val_src2[i]); + ASSERT_NE(dest_src2[i], val_src1[i]); + ASSERT_NE(dest_src2[i], val_src2[i]); + } + } +}; + +TEST_F(PointDVectorTest, VectorTest) { + TestSize(); + TestContentsDiscrete(); + TestContentsContiguous(); + TestContentsCopy(); + TestIterator(); + TestPoint3Iterator(); +} +TEST_F(PointDVectorTest, PseudoPointDTest) { + TestPseudoPointDSwap(); + TestPseudoPointDEquality(); + TestPseudoPointDInequality(); +} +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/points_sequencer.h b/third-party/draco/src/draco/compression/attributes/points_sequencer.h new file mode 100644 index 0000000000..2f4f7e16d1 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/points_sequencer.h @@ -0,0 +1,63 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_POINTS_SEQUENCER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_POINTS_SEQUENCER_H_ + +#include + +#include "draco/attributes/point_attribute.h" + +namespace draco { + +// Class for generating a sequence of point ids that can be used to encode +// or decode attribute values in a specific order. +// See sequential_attribute_encoders/decoders_controller.h for more details. +class PointsSequencer { + public: + PointsSequencer() : out_point_ids_(nullptr) {} + virtual ~PointsSequencer() = default; + + // Fills the |out_point_ids| with the generated sequence of point ids. + bool GenerateSequence(std::vector *out_point_ids) { + out_point_ids_ = out_point_ids; + return GenerateSequenceInternal(); + } + + // Appends a point to the sequence. + void AddPointId(PointIndex point_id) { out_point_ids_->push_back(point_id); } + + // Sets the correct mapping between point ids and value ids. I.e., the inverse + // of the |out_point_ids|. In general, |out_point_ids_| does not contain + // sufficient information to compute the inverse map, because not all point + // ids are necessarily contained within the map. + // Must be implemented for sequencers that are used by attribute decoders. + virtual bool UpdatePointToAttributeIndexMapping(PointAttribute * /* attr */) { + return false; + } + + protected: + // Method that needs to be implemented by the derived classes. The + // implementation is responsible for filling |out_point_ids_| with the valid + // sequence of point ids. + virtual bool GenerateSequenceInternal() = 0; + std::vector *out_point_ids() const { return out_point_ids_; } + + private: + std::vector *out_point_ids_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_POINTS_SEQUENCER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h new file mode 100644 index 0000000000..17899d0540 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h @@ -0,0 +1,236 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_CONSTRAINED_MULTI_PARALLELOGRAM_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_CONSTRAINED_MULTI_PARALLELOGRAM_DECODER_H_ + +#include +#include + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h" +#include "draco/compression/bit_coders/rans_bit_decoder.h" +#include "draco/core/math_utils.h" +#include "draco/core/varint_decoding.h" +#include "draco/draco_features.h" + +namespace draco { + +// Decoder for predictions encoded with the constrained multi-parallelogram +// encoder. See the corresponding encoder for more details about the prediction +// method. +template +class MeshPredictionSchemeConstrainedMultiParallelogramDecoder + : public MeshPredictionSchemeDecoder { + public: + using CorrType = + typename PredictionSchemeDecoder::CorrType; + using CornerTable = typename MeshDataT::CornerTable; + + explicit MeshPredictionSchemeConstrainedMultiParallelogramDecoder( + const PointAttribute *attribute) + : MeshPredictionSchemeDecoder( + attribute), + selected_mode_(Mode::OPTIMAL_MULTI_PARALLELOGRAM) {} + MeshPredictionSchemeConstrainedMultiParallelogramDecoder( + const PointAttribute *attribute, const TransformT &transform, + const MeshDataT &mesh_data) + : MeshPredictionSchemeDecoder( + attribute, transform, mesh_data), + selected_mode_(Mode::OPTIMAL_MULTI_PARALLELOGRAM) {} + + bool ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data, + int size, int num_components, + const PointIndex *entry_to_point_id_map) override; + + bool DecodePredictionData(DecoderBuffer *buffer) override; + + PredictionSchemeMethod GetPredictionMethod() const override { + return MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM; + } + + bool IsInitialized() const override { + return this->mesh_data().IsInitialized(); + } + + private: + typedef constrained_multi_parallelogram::Mode Mode; + static constexpr int kMaxNumParallelograms = + constrained_multi_parallelogram::kMaxNumParallelograms; + // Crease edges are used to store whether any given edge should be used for + // parallelogram prediction or not. New values are added in the order in which + // the edges are processed. For better compression, the flags are stored in + // in separate contexts based on the number of available parallelograms at a + // given vertex. + std::vector is_crease_edge_[kMaxNumParallelograms]; + Mode selected_mode_; +}; + +template +bool MeshPredictionSchemeConstrainedMultiParallelogramDecoder< + DataTypeT, TransformT, MeshDataT>:: + ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data, + int /* size */, int num_components, + const PointIndex * /* entry_to_point_id_map */) { + this->transform().Init(num_components); + + // Predicted values for all simple parallelograms encountered at any given + // vertex. + std::vector pred_vals[kMaxNumParallelograms]; + for (int i = 0; i < kMaxNumParallelograms; ++i) { + pred_vals[i].resize(num_components, 0); + } + this->transform().ComputeOriginalValue(pred_vals[0].data(), in_corr, + out_data); + + const CornerTable *const table = this->mesh_data().corner_table(); + const std::vector *const vertex_to_data_map = + this->mesh_data().vertex_to_data_map(); + + // Current position in the |is_crease_edge_| array for each context. + std::vector is_crease_edge_pos(kMaxNumParallelograms, 0); + + // Used to store predicted value for multi-parallelogram prediction. + std::vector multi_pred_vals(num_components); + + const int corner_map_size = + static_cast(this->mesh_data().data_to_corner_map()->size()); + for (int p = 1; p < corner_map_size; ++p) { + const CornerIndex start_corner_id = + this->mesh_data().data_to_corner_map()->at(p); + + CornerIndex corner_id(start_corner_id); + int num_parallelograms = 0; + bool first_pass = true; + while (corner_id != kInvalidCornerIndex) { + if (ComputeParallelogramPrediction( + p, corner_id, table, *vertex_to_data_map, out_data, + num_components, &(pred_vals[num_parallelograms][0]))) { + // Parallelogram prediction applied and stored in + // |pred_vals[num_parallelograms]| + ++num_parallelograms; + // Stop processing when we reach the maximum number of allowed + // parallelograms. + if (num_parallelograms == kMaxNumParallelograms) { + break; + } + } + + // Proceed to the next corner attached to the vertex. First swing left + // and if we reach a boundary, swing right from the start corner. + if (first_pass) { + corner_id = table->SwingLeft(corner_id); + } else { + corner_id = table->SwingRight(corner_id); + } + if (corner_id == start_corner_id) { + break; + } + if (corner_id == kInvalidCornerIndex && first_pass) { + first_pass = false; + corner_id = table->SwingRight(start_corner_id); + } + } + + // Check which of the available parallelograms are actually used and compute + // the final predicted value. + int num_used_parallelograms = 0; + if (num_parallelograms > 0) { + for (int i = 0; i < num_components; ++i) { + multi_pred_vals[i] = 0; + } + // Check which parallelograms are actually used. + for (int i = 0; i < num_parallelograms; ++i) { + const int context = num_parallelograms - 1; + const int pos = is_crease_edge_pos[context]++; + if (is_crease_edge_[context].size() <= pos) { + return false; + } + const bool is_crease = is_crease_edge_[context][pos]; + if (!is_crease) { + ++num_used_parallelograms; + for (int j = 0; j < num_components; ++j) { + multi_pred_vals[j] = + AddAsUnsigned(multi_pred_vals[j], pred_vals[i][j]); + } + } + } + } + const int dst_offset = p * num_components; + if (num_used_parallelograms == 0) { + // No parallelogram was valid. + // We use the last decoded point as a reference. + const int src_offset = (p - 1) * num_components; + this->transform().ComputeOriginalValue( + out_data + src_offset, in_corr + dst_offset, out_data + dst_offset); + } else { + // Compute the correction from the predicted value. + for (int c = 0; c < num_components; ++c) { + multi_pred_vals[c] /= num_used_parallelograms; + } + this->transform().ComputeOriginalValue( + multi_pred_vals.data(), in_corr + dst_offset, out_data + dst_offset); + } + } + return true; +} + +template +bool MeshPredictionSchemeConstrainedMultiParallelogramDecoder< + DataTypeT, TransformT, MeshDataT>::DecodePredictionData(DecoderBuffer + *buffer) { +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) { + // Decode prediction mode. + uint8_t mode; + if (!buffer->Decode(&mode)) { + return false; + } + + if (mode != Mode::OPTIMAL_MULTI_PARALLELOGRAM) { + // Unsupported mode. + return false; + } + } +#endif + + // Encode selected edges using separate rans bit coder for each context. + for (int i = 0; i < kMaxNumParallelograms; ++i) { + uint32_t num_flags; + if (!DecodeVarint(&num_flags, buffer)) { + return false; + } + if (num_flags > this->mesh_data().corner_table()->num_corners()) { + return false; + } + if (num_flags > 0) { + is_crease_edge_[i].resize(num_flags); + RAnsBitDecoder decoder; + if (!decoder.StartDecoding(buffer)) { + return false; + } + for (uint32_t j = 0; j < num_flags; ++j) { + is_crease_edge_[i][j] = decoder.DecodeNextBit(); + } + decoder.EndDecoding(); + } + } + return MeshPredictionSchemeDecoder::DecodePredictionData(buffer); +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_CONSTRAINED_MULTI_PARALLELOGRAM_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h new file mode 100644 index 0000000000..8845b94962 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h @@ -0,0 +1,413 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_CONSTRAINED_MULTI_PARALLELOGRAM_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_CONSTRAINED_MULTI_PARALLELOGRAM_ENCODER_H_ + +#include +#include + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h" +#include "draco/compression/bit_coders/rans_bit_encoder.h" +#include "draco/compression/entropy/shannon_entropy.h" +#include "draco/core/varint_encoding.h" + +namespace draco { + +// Compared to standard multi-parallelogram, constrained multi-parallelogram can +// explicitly select which of the available parallelograms are going to be used +// for the prediction by marking crease edges between two triangles. This +// requires storing extra data, but it allows the predictor to avoid using +// parallelograms that would lead to poor predictions. For improved efficiency, +// our current implementation limits the maximum number of used parallelograms +// to four, which covers >95% of the cases (on average, there are only two +// parallelograms available for any given vertex). +// All bits of the explicitly chosen configuration are stored together in a +// single context chosen by the total number of parallelograms available to +// choose from. +template +class MeshPredictionSchemeConstrainedMultiParallelogramEncoder + : public MeshPredictionSchemeEncoder { + public: + using CorrType = + typename PredictionSchemeEncoder::CorrType; + using CornerTable = typename MeshDataT::CornerTable; + + explicit MeshPredictionSchemeConstrainedMultiParallelogramEncoder( + const PointAttribute *attribute) + : MeshPredictionSchemeEncoder( + attribute), + selected_mode_(Mode::OPTIMAL_MULTI_PARALLELOGRAM) {} + MeshPredictionSchemeConstrainedMultiParallelogramEncoder( + const PointAttribute *attribute, const TransformT &transform, + const MeshDataT &mesh_data) + : MeshPredictionSchemeEncoder( + attribute, transform, mesh_data), + selected_mode_(Mode::OPTIMAL_MULTI_PARALLELOGRAM) {} + + bool ComputeCorrectionValues( + const DataTypeT *in_data, CorrType *out_corr, int size, + int num_components, const PointIndex *entry_to_point_id_map) override; + + bool EncodePredictionData(EncoderBuffer *buffer) override; + + PredictionSchemeMethod GetPredictionMethod() const override { + return MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM; + } + + bool IsInitialized() const override { + return this->mesh_data().IsInitialized(); + } + + private: + // Function used to compute number of bits needed to store overhead of the + // predictor. In this case, we consider overhead to be all bits that mark + // whether a parallelogram should be used for prediction or not. The input + // to this method is the total number of parallelograms that were evaluated so + // far(total_parallelogram), and the number of parallelograms we decided to + // use for prediction (total_used_parallelograms). + // Returns number of bits required to store the overhead. + int64_t ComputeOverheadBits(int64_t total_used_parallelograms, + int64_t total_parallelogram) const { + // For now we assume RAns coding for the bits where the total required size + // is directly correlated to the binary entropy of the input stream. + // TODO(ostava): This should be generalized in case we use other binary + // coding scheme. + const double entropy = ComputeBinaryShannonEntropy( + static_cast(total_parallelogram), + static_cast(total_used_parallelograms)); + + // Round up to the nearest full bit. + return static_cast( + ceil(static_cast(total_parallelogram) * entropy)); + } + + // Struct that contains data used for measuring the error of each available + // parallelogram configuration. + struct Error { + Error() : num_bits(0), residual_error(0) {} + + // Primary metric: number of bits required to store the data as a result of + // the selected prediction configuration. + int num_bits; + // Secondary metric: absolute difference of residuals for the given + // configuration. + int residual_error; + + bool operator<(const Error &e) const { + if (num_bits < e.num_bits) { + return true; + } + if (num_bits > e.num_bits) { + return false; + } + return residual_error < e.residual_error; + } + }; + + // Computes error for predicting |predicted_val| instead of |actual_val|. + // Error is computed as the number of bits needed to encode the difference + // between the values. + Error ComputeError(const DataTypeT *predicted_val, + const DataTypeT *actual_val, int *out_residuals, + int num_components) { + Error error; + + for (int i = 0; i < num_components; ++i) { + const int dif = (predicted_val[i] - actual_val[i]); + error.residual_error += std::abs(dif); + out_residuals[i] = dif; + // Entropy needs unsigned symbols, so convert the signed difference to an + // unsigned symbol. + entropy_symbols_[i] = ConvertSignedIntToSymbol(dif); + } + + // Generate entropy data for case that this configuration was used. + // Note that the entropy stream is NOT updated in this case. + const auto entropy_data = + entropy_tracker_.Peek(entropy_symbols_.data(), num_components); + + error.num_bits = entropy_tracker_.GetNumberOfDataBits(entropy_data) + + entropy_tracker_.GetNumberOfRAnsTableBits(entropy_data); + return error; + } + + typedef constrained_multi_parallelogram::Mode Mode; + static constexpr int kMaxNumParallelograms = + constrained_multi_parallelogram::kMaxNumParallelograms; + // Crease edges are used to store whether any given edge should be used for + // parallelogram prediction or not. New values are added in the order in which + // the edges are processed. For better compression, the flags are stored in + // in separate contexts based on the number of available parallelograms at a + // given vertex. + // TODO(draco-eng) reconsider std::vector (performance/space). + std::vector is_crease_edge_[kMaxNumParallelograms]; + Mode selected_mode_; + + ShannonEntropyTracker entropy_tracker_; + + // Temporary storage for symbols that are fed into the |entropy_stream|. + // Always contains only |num_components| entries. + std::vector entropy_symbols_; +}; + +template +bool MeshPredictionSchemeConstrainedMultiParallelogramEncoder< + DataTypeT, TransformT, MeshDataT>:: + ComputeCorrectionValues(const DataTypeT *in_data, CorrType *out_corr, + int size, int num_components, + const PointIndex * /* entry_to_point_id_map */) { + this->transform().Init(in_data, size, num_components); + const CornerTable *const table = this->mesh_data().corner_table(); + const std::vector *const vertex_to_data_map = + this->mesh_data().vertex_to_data_map(); + + // Predicted values for all simple parallelograms encountered at any given + // vertex. + std::vector pred_vals[kMaxNumParallelograms]; + for (int i = 0; i < kMaxNumParallelograms; ++i) { + pred_vals[i].resize(num_components); + } + // Used to store predicted value for various multi-parallelogram predictions + // (combinations of simple parallelogram predictions). + std::vector multi_pred_vals(num_components); + entropy_symbols_.resize(num_components); + + // Struct for holding data about prediction configuration for different sets + // of used parallelograms. + struct PredictionConfiguration { + PredictionConfiguration() + : error(), configuration(0), num_used_parallelograms(0) {} + Error error; + uint8_t configuration; // Bitfield, 1 use parallelogram, 0 don't use it. + int num_used_parallelograms; + std::vector predicted_value; + std::vector residuals; + }; + + // Bit-field used for computing permutations of excluded edges + // (parallelograms). + bool excluded_parallelograms[kMaxNumParallelograms]; + + // Data about the number of used parallelogram and total number of available + // parallelogram for each context. Used to compute overhead needed for storing + // the parallelogram choices made by the encoder. + int64_t total_used_parallelograms[kMaxNumParallelograms] = {0}; + int64_t total_parallelograms[kMaxNumParallelograms] = {0}; + + std::vector current_residuals(num_components); + + // We start processing the vertices from the end because this prediction uses + // data from previous entries that could be overwritten when an entry is + // processed. + for (int p = + static_cast(this->mesh_data().data_to_corner_map()->size()) - 1; + p > 0; --p) { + const CornerIndex start_corner_id = + this->mesh_data().data_to_corner_map()->at(p); + + // Go over all corners attached to the vertex and compute the predicted + // value from the parallelograms defined by their opposite faces. + CornerIndex corner_id(start_corner_id); + int num_parallelograms = 0; + bool first_pass = true; + while (corner_id != kInvalidCornerIndex) { + if (ComputeParallelogramPrediction( + p, corner_id, table, *vertex_to_data_map, in_data, num_components, + &(pred_vals[num_parallelograms][0]))) { + // Parallelogram prediction applied and stored in + // |pred_vals[num_parallelograms]| + ++num_parallelograms; + // Stop processing when we reach the maximum number of allowed + // parallelograms. + if (num_parallelograms == kMaxNumParallelograms) { + break; + } + } + + // Proceed to the next corner attached to the vertex. First swing left + // and if we reach a boundary, swing right from the start corner. + if (first_pass) { + corner_id = table->SwingLeft(corner_id); + } else { + corner_id = table->SwingRight(corner_id); + } + if (corner_id == start_corner_id) { + break; + } + if (corner_id == kInvalidCornerIndex && first_pass) { + first_pass = false; + corner_id = table->SwingRight(start_corner_id); + } + } + + // Offset to the target (destination) vertex. + const int dst_offset = p * num_components; + Error error; + + // Compute all prediction errors for all possible configurations of + // available parallelograms. + + // Variable for holding the best configuration that has been found so far. + PredictionConfiguration best_prediction; + + // Compute delta coding error (configuration when no parallelogram is + // selected). + const int src_offset = (p - 1) * num_components; + error = ComputeError(in_data + src_offset, in_data + dst_offset, + ¤t_residuals[0], num_components); + + if (num_parallelograms > 0) { + total_parallelograms[num_parallelograms - 1] += num_parallelograms; + const int64_t new_overhead_bits = + ComputeOverheadBits(total_used_parallelograms[num_parallelograms - 1], + total_parallelograms[num_parallelograms - 1]); + error.num_bits += new_overhead_bits; + } + + best_prediction.error = error; + best_prediction.configuration = 0; + best_prediction.num_used_parallelograms = 0; + best_prediction.predicted_value.assign( + in_data + src_offset, in_data + src_offset + num_components); + best_prediction.residuals.assign(current_residuals.begin(), + current_residuals.end()); + + // Compute prediction error for different cases of used parallelograms. + for (int num_used_parallelograms = 1; + num_used_parallelograms <= num_parallelograms; + ++num_used_parallelograms) { + // Mark all parallelograms as excluded. + std::fill(excluded_parallelograms, + excluded_parallelograms + num_parallelograms, true); + // TODO(draco-eng) maybe this should be another std::fill. + // Mark the first |num_used_parallelograms| as not excluded. + for (int j = 0; j < num_used_parallelograms; ++j) { + excluded_parallelograms[j] = false; + } + // Permute over the excluded edges and compute error for each + // configuration (permutation of excluded parallelograms). + do { + // Reset the multi-parallelogram predicted values. + for (int j = 0; j < num_components; ++j) { + multi_pred_vals[j] = 0; + } + uint8_t configuration = 0; + for (int j = 0; j < num_parallelograms; ++j) { + if (excluded_parallelograms[j]) { + continue; + } + for (int c = 0; c < num_components; ++c) { + multi_pred_vals[c] += pred_vals[j][c]; + } + // Set jth bit of the configuration. + configuration |= (1 << j); + } + + for (int j = 0; j < num_components; ++j) { + multi_pred_vals[j] /= num_used_parallelograms; + } + error = ComputeError(multi_pred_vals.data(), in_data + dst_offset, + ¤t_residuals[0], num_components); + const int64_t new_overhead_bits = ComputeOverheadBits( + total_used_parallelograms[num_parallelograms - 1] + + num_used_parallelograms, + total_parallelograms[num_parallelograms - 1]); + + // Add overhead bits to the total error. + error.num_bits += new_overhead_bits; + if (error < best_prediction.error) { + best_prediction.error = error; + best_prediction.configuration = configuration; + best_prediction.num_used_parallelograms = num_used_parallelograms; + best_prediction.predicted_value.assign(multi_pred_vals.begin(), + multi_pred_vals.end()); + best_prediction.residuals.assign(current_residuals.begin(), + current_residuals.end()); + } + } while ( + std::next_permutation(excluded_parallelograms, + excluded_parallelograms + num_parallelograms)); + } + if (num_parallelograms > 0) { + total_used_parallelograms[num_parallelograms - 1] += + best_prediction.num_used_parallelograms; + } + + // Update the entropy stream by adding selected residuals as symbols to the + // stream. + for (int i = 0; i < num_components; ++i) { + entropy_symbols_[i] = + ConvertSignedIntToSymbol(best_prediction.residuals[i]); + } + entropy_tracker_.Push(entropy_symbols_.data(), num_components); + + for (int i = 0; i < num_parallelograms; ++i) { + if ((best_prediction.configuration & (1 << i)) == 0) { + // Parallelogram not used, mark the edge as crease. + is_crease_edge_[num_parallelograms - 1].push_back(true); + } else { + // Parallelogram used. Add it to the predicted value and mark the + // edge as not a crease. + is_crease_edge_[num_parallelograms - 1].push_back(false); + } + } + this->transform().ComputeCorrection(in_data + dst_offset, + best_prediction.predicted_value.data(), + out_corr + dst_offset); + } + // First element is always fixed because it cannot be predicted. + for (int i = 0; i < num_components; ++i) { + pred_vals[0][i] = static_cast(0); + } + this->transform().ComputeCorrection(in_data, pred_vals[0].data(), out_corr); + return true; +} + +template +bool MeshPredictionSchemeConstrainedMultiParallelogramEncoder< + DataTypeT, TransformT, MeshDataT>::EncodePredictionData(EncoderBuffer + *buffer) { + // Encode selected edges using separate rans bit coder for each context. + for (int i = 0; i < kMaxNumParallelograms; ++i) { + // |i| is the context based on the number of available parallelograms, which + // is always equal to |i + 1|. + const int num_used_parallelograms = i + 1; + EncodeVarint(is_crease_edge_[i].size(), buffer); + if (is_crease_edge_[i].size()) { + RAnsBitEncoder encoder; + encoder.StartEncoding(); + // Encode the crease edge flags in the reverse vertex order that is needed + // by the decoder. Note that for the currently supported mode, each vertex + // has exactly |num_used_parallelograms| edges that need to be encoded. + for (int j = static_cast(is_crease_edge_[i].size()) - + num_used_parallelograms; + j >= 0; j -= num_used_parallelograms) { + // Go over all edges of the current vertex. + for (int k = 0; k < num_used_parallelograms; ++k) { + encoder.EncodeBit(is_crease_edge_[i][j + k]); + } + } + encoder.EndEncoding(buffer); + } + } + return MeshPredictionSchemeEncoder::EncodePredictionData(buffer); +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_CONSTRAINED_MULTI_PARALLELOGRAM_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h new file mode 100644 index 0000000000..c7a4e351ae --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h @@ -0,0 +1,34 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_CONSTRAINED_MULTI_PARALLELOGRAM_SHARED_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_CONSTRAINED_MULTI_PARALLELOGRAM_SHARED_H_ + +namespace draco { + +// Data shared between constrained multi-parallelogram encoder and decoder. +namespace constrained_multi_parallelogram { + +enum Mode { + // Selects the optimal multi-parallelogram from up to 4 available + // parallelograms. + OPTIMAL_MULTI_PARALLELOGRAM = 0, +}; + +static constexpr int kMaxNumParallelograms = 4; + +} // namespace constrained_multi_parallelogram +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_CONSTRAINED_MULTI_PARALLELOGRAM_SHARED_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h new file mode 100644 index 0000000000..2960a5e71b --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h @@ -0,0 +1,72 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_DATA_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_DATA_H_ + +#include "draco/mesh/corner_table.h" +#include "draco/mesh/mesh.h" + +namespace draco { + +// Class stores data about the connectivity data of the mesh and information +// about how the connectivity was encoded/decoded. +template +class MeshPredictionSchemeData { + public: + typedef CornerTableT CornerTable; + MeshPredictionSchemeData() + : mesh_(nullptr), + corner_table_(nullptr), + vertex_to_data_map_(nullptr), + data_to_corner_map_(nullptr) {} + + void Set(const Mesh *mesh, const CornerTable *table, + const std::vector *data_to_corner_map, + const std::vector *vertex_to_data_map) { + mesh_ = mesh; + corner_table_ = table; + data_to_corner_map_ = data_to_corner_map; + vertex_to_data_map_ = vertex_to_data_map; + } + + const Mesh *mesh() const { return mesh_; } + const CornerTable *corner_table() const { return corner_table_; } + const std::vector *vertex_to_data_map() const { + return vertex_to_data_map_; + } + const std::vector *data_to_corner_map() const { + return data_to_corner_map_; + } + bool IsInitialized() const { + return mesh_ != nullptr && corner_table_ != nullptr && + vertex_to_data_map_ != nullptr && data_to_corner_map_ != nullptr; + } + + private: + const Mesh *mesh_; + const CornerTable *corner_table_; + + // Mapping between vertices and their encoding order. I.e. when an attribute + // entry on a given vertex was encoded. + const std::vector *vertex_to_data_map_; + + // Array that stores which corner was processed when a given attribute entry + // was encoded or decoded. + const std::vector *data_to_corner_map_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_DATA_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h new file mode 100644 index 0000000000..6694a981c1 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h @@ -0,0 +1,46 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_DECODER_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h" + +namespace draco { + +// Base class for all mesh prediction scheme decoders that use the mesh +// connectivity data. |MeshDataT| can be any class that provides the same +// interface as the PredictionSchemeMeshData class. +template +class MeshPredictionSchemeDecoder + : public PredictionSchemeDecoder { + public: + typedef MeshDataT MeshData; + MeshPredictionSchemeDecoder(const PointAttribute *attribute, + const TransformT &transform, + const MeshDataT &mesh_data) + : PredictionSchemeDecoder(attribute, transform), + mesh_data_(mesh_data) {} + + protected: + const MeshData &mesh_data() const { return mesh_data_; } + + private: + MeshData mesh_data_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h new file mode 100644 index 0000000000..ab3c81a390 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h @@ -0,0 +1,46 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_ENCODER_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h" + +namespace draco { + +// Base class for all mesh prediction scheme encoders that use the mesh +// connectivity data. |MeshDataT| can be any class that provides the same +// interface as the PredictionSchemeMeshData class. +template +class MeshPredictionSchemeEncoder + : public PredictionSchemeEncoder { + public: + typedef MeshDataT MeshData; + MeshPredictionSchemeEncoder(const PointAttribute *attribute, + const TransformT &transform, + const MeshDataT &mesh_data) + : PredictionSchemeEncoder(attribute, transform), + mesh_data_(mesh_data) {} + + protected: + const MeshData &mesh_data() const { return mesh_data_; } + + private: + MeshData mesh_data_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h new file mode 100644 index 0000000000..badea22f37 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h @@ -0,0 +1,176 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_DECODER_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h" +#include "draco/compression/bit_coders/rans_bit_decoder.h" +#include "draco/draco_features.h" + +namespace draco { + +// See MeshPredictionSchemeGeometricNormalEncoder for documentation. +template +class MeshPredictionSchemeGeometricNormalDecoder + : public MeshPredictionSchemeDecoder { + public: + using CorrType = typename MeshPredictionSchemeDecoder::CorrType; + MeshPredictionSchemeGeometricNormalDecoder(const PointAttribute *attribute, + const TransformT &transform, + const MeshDataT &mesh_data) + : MeshPredictionSchemeDecoder( + attribute, transform, mesh_data), + predictor_(mesh_data) {} + + private: + MeshPredictionSchemeGeometricNormalDecoder() {} + + public: + bool ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data, + int size, int num_components, + const PointIndex *entry_to_point_id_map) override; + + bool DecodePredictionData(DecoderBuffer *buffer) override; + + PredictionSchemeMethod GetPredictionMethod() const override { + return MESH_PREDICTION_GEOMETRIC_NORMAL; + } + + bool IsInitialized() const override { + if (!predictor_.IsInitialized()) { + return false; + } + if (!this->mesh_data().IsInitialized()) { + return false; + } + if (!octahedron_tool_box_.IsInitialized()) { + return false; + } + return true; + } + + int GetNumParentAttributes() const override { return 1; } + + GeometryAttribute::Type GetParentAttributeType(int i) const override { + DRACO_DCHECK_EQ(i, 0); + (void)i; + return GeometryAttribute::POSITION; + } + + bool SetParentAttribute(const PointAttribute *att) override { + if (att->attribute_type() != GeometryAttribute::POSITION) { + return false; // Invalid attribute type. + } + if (att->num_components() != 3) { + return false; // Currently works only for 3 component positions. + } + predictor_.SetPositionAttribute(*att); + return true; + } + void SetQuantizationBits(int q) { + octahedron_tool_box_.SetQuantizationBits(q); + } + + private: + MeshPredictionSchemeGeometricNormalPredictorArea + predictor_; + OctahedronToolBox octahedron_tool_box_; + RAnsBitDecoder flip_normal_bit_decoder_; +}; + +template +bool MeshPredictionSchemeGeometricNormalDecoder< + DataTypeT, TransformT, + MeshDataT>::ComputeOriginalValues(const CorrType *in_corr, + DataTypeT *out_data, int /* size */, + int num_components, + const PointIndex *entry_to_point_id_map) { + this->SetQuantizationBits(this->transform().quantization_bits()); + predictor_.SetEntryToPointIdMap(entry_to_point_id_map); + DRACO_DCHECK(this->IsInitialized()); + + // Expecting in_data in octahedral coordinates, i.e., portable attribute. + DRACO_DCHECK_EQ(num_components, 2); + + const int corner_map_size = + static_cast(this->mesh_data().data_to_corner_map()->size()); + + VectorD pred_normal_3d; + int32_t pred_normal_oct[2]; + + for (int data_id = 0; data_id < corner_map_size; ++data_id) { + const CornerIndex corner_id = + this->mesh_data().data_to_corner_map()->at(data_id); + predictor_.ComputePredictedValue(corner_id, pred_normal_3d.data()); + + // Compute predicted octahedral coordinates. + octahedron_tool_box_.CanonicalizeIntegerVector(pred_normal_3d.data()); + DRACO_DCHECK_EQ(pred_normal_3d.AbsSum(), + octahedron_tool_box_.center_value()); + if (flip_normal_bit_decoder_.DecodeNextBit()) { + pred_normal_3d = -pred_normal_3d; + } + octahedron_tool_box_.IntegerVectorToQuantizedOctahedralCoords( + pred_normal_3d.data(), pred_normal_oct, pred_normal_oct + 1); + + const int data_offset = data_id * 2; + this->transform().ComputeOriginalValue( + pred_normal_oct, in_corr + data_offset, out_data + data_offset); + } + flip_normal_bit_decoder_.EndDecoding(); + return true; +} + +template +bool MeshPredictionSchemeGeometricNormalDecoder< + DataTypeT, TransformT, MeshDataT>::DecodePredictionData(DecoderBuffer + *buffer) { + // Get data needed for transform + if (!this->transform().DecodeTransformData(buffer)) { + return false; + } + +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) { + uint8_t prediction_mode; + if (!buffer->Decode(&prediction_mode)) { + return false; + } + if (prediction_mode > TRIANGLE_AREA) { + // Invalid prediction mode. + return false; + } + + if (!predictor_.SetNormalPredictionMode( + NormalPredictionMode(prediction_mode))) { + return false; + } + } +#endif + + // Init normal flips. + if (!flip_normal_bit_decoder_.StartDecoding(buffer)) { + return false; + } + + return true; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h new file mode 100644 index 0000000000..cf146f83ac --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h @@ -0,0 +1,180 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_ENCODER_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h" +#include "draco/compression/bit_coders/rans_bit_encoder.h" +#include "draco/compression/config/compression_shared.h" + +namespace draco { + +// Prediction scheme for normals based on the underlying geometry. +// At a smooth vertices normals are computed by weighting the normals of +// adjacent faces with the area of these faces. At seams, the same approach +// applies for seam corners. +template +class MeshPredictionSchemeGeometricNormalEncoder + : public MeshPredictionSchemeEncoder { + public: + using CorrType = typename MeshPredictionSchemeEncoder::CorrType; + MeshPredictionSchemeGeometricNormalEncoder(const PointAttribute *attribute, + const TransformT &transform, + const MeshDataT &mesh_data) + : MeshPredictionSchemeEncoder( + attribute, transform, mesh_data), + predictor_(mesh_data) {} + + bool ComputeCorrectionValues( + const DataTypeT *in_data, CorrType *out_corr, int size, + int num_components, const PointIndex *entry_to_point_id_map) override; + + bool EncodePredictionData(EncoderBuffer *buffer) override; + + PredictionSchemeMethod GetPredictionMethod() const override { + return MESH_PREDICTION_GEOMETRIC_NORMAL; + } + + bool IsInitialized() const override { + if (!predictor_.IsInitialized()) { + return false; + } + if (!this->mesh_data().IsInitialized()) { + return false; + } + return true; + } + + int GetNumParentAttributes() const override { return 1; } + + GeometryAttribute::Type GetParentAttributeType(int i) const override { + DRACO_DCHECK_EQ(i, 0); + (void)i; + return GeometryAttribute::POSITION; + } + + bool SetParentAttribute(const PointAttribute *att) override { + if (att->attribute_type() != GeometryAttribute::POSITION) { + return false; // Invalid attribute type. + } + if (att->num_components() != 3) { + return false; // Currently works only for 3 component positions. + } + predictor_.SetPositionAttribute(*att); + return true; + } + + private: + void SetQuantizationBits(int q) { + DRACO_DCHECK_GE(q, 2); + DRACO_DCHECK_LE(q, 30); + octahedron_tool_box_.SetQuantizationBits(q); + } + MeshPredictionSchemeGeometricNormalPredictorArea + predictor_; + + OctahedronToolBox octahedron_tool_box_; + RAnsBitEncoder flip_normal_bit_encoder_; +}; + +template +bool MeshPredictionSchemeGeometricNormalEncoder:: + ComputeCorrectionValues(const DataTypeT *in_data, CorrType *out_corr, + int size, int num_components, + const PointIndex *entry_to_point_id_map) { + this->SetQuantizationBits(this->transform().quantization_bits()); + predictor_.SetEntryToPointIdMap(entry_to_point_id_map); + DRACO_DCHECK(this->IsInitialized()); + // Expecting in_data in octahedral coordinates, i.e., portable attribute. + DRACO_DCHECK_EQ(num_components, 2); + + flip_normal_bit_encoder_.StartEncoding(); + + const int corner_map_size = + static_cast(this->mesh_data().data_to_corner_map()->size()); + + VectorD pred_normal_3d; + VectorD pos_pred_normal_oct; + VectorD neg_pred_normal_oct; + VectorD pos_correction; + VectorD neg_correction; + for (int data_id = 0; data_id < corner_map_size; ++data_id) { + const CornerIndex corner_id = + this->mesh_data().data_to_corner_map()->at(data_id); + predictor_.ComputePredictedValue(corner_id, pred_normal_3d.data()); + + // Compute predicted octahedral coordinates. + octahedron_tool_box_.CanonicalizeIntegerVector(pred_normal_3d.data()); + DRACO_DCHECK_EQ(pred_normal_3d.AbsSum(), + octahedron_tool_box_.center_value()); + + // Compute octahedral coordinates for both possible directions. + octahedron_tool_box_.IntegerVectorToQuantizedOctahedralCoords( + pred_normal_3d.data(), pos_pred_normal_oct.data(), + pos_pred_normal_oct.data() + 1); + pred_normal_3d = -pred_normal_3d; + octahedron_tool_box_.IntegerVectorToQuantizedOctahedralCoords( + pred_normal_3d.data(), neg_pred_normal_oct.data(), + neg_pred_normal_oct.data() + 1); + + // Choose the one with the best correction value. + const int data_offset = data_id * 2; + this->transform().ComputeCorrection(in_data + data_offset, + pos_pred_normal_oct.data(), + pos_correction.data()); + this->transform().ComputeCorrection(in_data + data_offset, + neg_pred_normal_oct.data(), + neg_correction.data()); + pos_correction[0] = octahedron_tool_box_.ModMax(pos_correction[0]); + pos_correction[1] = octahedron_tool_box_.ModMax(pos_correction[1]); + neg_correction[0] = octahedron_tool_box_.ModMax(neg_correction[0]); + neg_correction[1] = octahedron_tool_box_.ModMax(neg_correction[1]); + if (pos_correction.AbsSum() < neg_correction.AbsSum()) { + flip_normal_bit_encoder_.EncodeBit(false); + (out_corr + data_offset)[0] = + octahedron_tool_box_.MakePositive(pos_correction[0]); + (out_corr + data_offset)[1] = + octahedron_tool_box_.MakePositive(pos_correction[1]); + } else { + flip_normal_bit_encoder_.EncodeBit(true); + (out_corr + data_offset)[0] = + octahedron_tool_box_.MakePositive(neg_correction[0]); + (out_corr + data_offset)[1] = + octahedron_tool_box_.MakePositive(neg_correction[1]); + } + } + return true; +} + +template +bool MeshPredictionSchemeGeometricNormalEncoder< + DataTypeT, TransformT, MeshDataT>::EncodePredictionData(EncoderBuffer + *buffer) { + if (!this->transform().EncodeTransformData(buffer)) { + return false; + } + + // Encode normal flips. + flip_normal_bit_encoder_.EndEncoding(buffer); + return true; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h new file mode 100644 index 0000000000..775eded6b5 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h @@ -0,0 +1,117 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_PREDICTOR_AREA_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_PREDICTOR_AREA_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h" + +namespace draco { + +// This predictor estimates the normal via the surrounding triangles of the +// given corner. Triangles are weighted according to their area. +template +class MeshPredictionSchemeGeometricNormalPredictorArea + : public MeshPredictionSchemeGeometricNormalPredictorBase< + DataTypeT, TransformT, MeshDataT> { + typedef MeshPredictionSchemeGeometricNormalPredictorBase< + DataTypeT, TransformT, MeshDataT> + Base; + + public: + explicit MeshPredictionSchemeGeometricNormalPredictorArea(const MeshDataT &md) + : Base(md) { + this->SetNormalPredictionMode(TRIANGLE_AREA); + }; + virtual ~MeshPredictionSchemeGeometricNormalPredictorArea() {} + + // Computes predicted octahedral coordinates on a given corner. + void ComputePredictedValue(CornerIndex corner_id, + DataTypeT *prediction) override { + DRACO_DCHECK(this->IsInitialized()); + typedef typename MeshDataT::CornerTable CornerTable; + const CornerTable *const corner_table = this->mesh_data_.corner_table(); + // Going to compute the predicted normal from the surrounding triangles + // according to the connectivity of the given corner table. + VertexCornersIterator cit(corner_table, corner_id); + // Position of central vertex does not change in loop. + const VectorD pos_cent = this->GetPositionForCorner(corner_id); + // Computing normals for triangles and adding them up. + + VectorD normal; + CornerIndex c_next, c_prev; + while (!cit.End()) { + // Getting corners. + if (this->normal_prediction_mode_ == ONE_TRIANGLE) { + c_next = corner_table->Next(corner_id); + c_prev = corner_table->Previous(corner_id); + } else { + c_next = corner_table->Next(cit.Corner()); + c_prev = corner_table->Previous(cit.Corner()); + } + const VectorD pos_next = this->GetPositionForCorner(c_next); + const VectorD pos_prev = this->GetPositionForCorner(c_prev); + + // Computing delta vectors to next and prev. + const VectorD delta_next = pos_next - pos_cent; + const VectorD delta_prev = pos_prev - pos_cent; + + // Computing cross product. + const VectorD cross = CrossProduct(delta_next, delta_prev); + + // Prevent signed integer overflows by doing math as unsigned. + auto normal_data = reinterpret_cast(normal.data()); + auto cross_data = reinterpret_cast(cross.data()); + normal_data[0] = normal_data[0] + cross_data[0]; + normal_data[1] = normal_data[1] + cross_data[1]; + normal_data[2] = normal_data[2] + cross_data[2]; + + cit.Next(); + } + + // Convert to int32_t, make sure entries are not too large. + constexpr int64_t upper_bound = 1 << 29; + if (this->normal_prediction_mode_ == ONE_TRIANGLE) { + const int32_t abs_sum = static_cast(normal.AbsSum()); + if (abs_sum > upper_bound) { + const int64_t quotient = abs_sum / upper_bound; + normal = normal / quotient; + } + } else { + const int64_t abs_sum = normal.AbsSum(); + if (abs_sum > upper_bound) { + const int64_t quotient = abs_sum / upper_bound; + normal = normal / quotient; + } + } + DRACO_DCHECK_LE(normal.AbsSum(), upper_bound); + prediction[0] = static_cast(normal[0]); + prediction[1] = static_cast(normal[1]); + prediction[2] = static_cast(normal[2]); + } + bool SetNormalPredictionMode(NormalPredictionMode mode) override { + if (mode == ONE_TRIANGLE) { + this->normal_prediction_mode_ = mode; + return true; + } else if (mode == TRIANGLE_AREA) { + this->normal_prediction_mode_ = mode; + return true; + } + return false; + } +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_PREDICTOR_AREA_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h new file mode 100644 index 0000000000..a554dda967 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h @@ -0,0 +1,96 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_PREDICTOR_BASE_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_PREDICTOR_BASE_H_ + +#include + +#include "draco/attributes/point_attribute.h" +#include "draco/compression/attributes/normal_compression_utils.h" +#include "draco/compression/config/compression_shared.h" +#include "draco/core/math_utils.h" +#include "draco/core/vector_d.h" +#include "draco/mesh/corner_table.h" +#include "draco/mesh/corner_table_iterators.h" + +namespace draco { + +// Base class for geometric normal predictors using position attribute. +template +class MeshPredictionSchemeGeometricNormalPredictorBase { + protected: + explicit MeshPredictionSchemeGeometricNormalPredictorBase(const MeshDataT &md) + : pos_attribute_(nullptr), + entry_to_point_id_map_(nullptr), + mesh_data_(md) {} + virtual ~MeshPredictionSchemeGeometricNormalPredictorBase() {} + + public: + void SetPositionAttribute(const PointAttribute &position_attribute) { + pos_attribute_ = &position_attribute; + } + void SetEntryToPointIdMap(const PointIndex *map) { + entry_to_point_id_map_ = map; + } + bool IsInitialized() const { + if (pos_attribute_ == nullptr) { + return false; + } + if (entry_to_point_id_map_ == nullptr) { + return false; + } + return true; + } + + virtual bool SetNormalPredictionMode(NormalPredictionMode mode) = 0; + virtual NormalPredictionMode GetNormalPredictionMode() const { + return normal_prediction_mode_; + } + + protected: + VectorD GetPositionForDataId(int data_id) const { + DRACO_DCHECK(this->IsInitialized()); + const auto point_id = entry_to_point_id_map_[data_id]; + const auto pos_val_id = pos_attribute_->mapped_index(point_id); + VectorD pos; + pos_attribute_->ConvertValue(pos_val_id, &pos[0]); + return pos; + } + VectorD GetPositionForCorner(CornerIndex ci) const { + DRACO_DCHECK(this->IsInitialized()); + const auto corner_table = mesh_data_.corner_table(); + const auto vert_id = corner_table->Vertex(ci).value(); + const auto data_id = mesh_data_.vertex_to_data_map()->at(vert_id); + return GetPositionForDataId(data_id); + } + VectorD GetOctahedralCoordForDataId(int data_id, + const DataTypeT *data) const { + DRACO_DCHECK(this->IsInitialized()); + const int data_offset = data_id * 2; + return VectorD(data[data_offset], data[data_offset + 1]); + } + // Computes predicted octahedral coordinates on a given corner. + virtual void ComputePredictedValue(CornerIndex corner_id, + DataTypeT *prediction) = 0; + + const PointAttribute *pos_attribute_; + const PointIndex *entry_to_point_id_map_; + MeshDataT mesh_data_; + NormalPredictionMode normal_prediction_mode_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_GEOMETRIC_NORMAL_PREDICTOR_BASE_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h new file mode 100644 index 0000000000..9825c72619 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h @@ -0,0 +1,128 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_MULTI_PARALLELOGRAM_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_MULTI_PARALLELOGRAM_DECODER_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h" +#include "draco/core/math_utils.h" +#include "draco/draco_features.h" + +namespace draco { + +// Decoder for predictions encoded by multi-parallelogram encoding scheme. +// See the corresponding encoder for method description. +template +class MeshPredictionSchemeMultiParallelogramDecoder + : public MeshPredictionSchemeDecoder { + public: + using CorrType = + typename PredictionSchemeDecoder::CorrType; + using CornerTable = typename MeshDataT::CornerTable; + + explicit MeshPredictionSchemeMultiParallelogramDecoder( + const PointAttribute *attribute) + : MeshPredictionSchemeDecoder( + attribute) {} + MeshPredictionSchemeMultiParallelogramDecoder(const PointAttribute *attribute, + const TransformT &transform, + const MeshDataT &mesh_data) + : MeshPredictionSchemeDecoder( + attribute, transform, mesh_data) {} + + bool ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data, + int size, int num_components, + const PointIndex *entry_to_point_id_map) override; + PredictionSchemeMethod GetPredictionMethod() const override { + return MESH_PREDICTION_MULTI_PARALLELOGRAM; + } + + bool IsInitialized() const override { + return this->mesh_data().IsInitialized(); + } +}; + +template +bool MeshPredictionSchemeMultiParallelogramDecoder:: + ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data, + int /* size */, int num_components, + const PointIndex * /* entry_to_point_id_map */) { + this->transform().Init(num_components); + + // For storage of prediction values (already initialized to zero). + std::unique_ptr pred_vals(new DataTypeT[num_components]()); + std::unique_ptr parallelogram_pred_vals( + new DataTypeT[num_components]()); + + this->transform().ComputeOriginalValue(pred_vals.get(), in_corr, out_data); + + const CornerTable *const table = this->mesh_data().corner_table(); + const std::vector *const vertex_to_data_map = + this->mesh_data().vertex_to_data_map(); + + const int corner_map_size = + static_cast(this->mesh_data().data_to_corner_map()->size()); + for (int p = 1; p < corner_map_size; ++p) { + const CornerIndex start_corner_id = + this->mesh_data().data_to_corner_map()->at(p); + + CornerIndex corner_id(start_corner_id); + int num_parallelograms = 0; + for (int i = 0; i < num_components; ++i) { + pred_vals[i] = static_cast(0); + } + while (corner_id != kInvalidCornerIndex) { + if (ComputeParallelogramPrediction( + p, corner_id, table, *vertex_to_data_map, out_data, + num_components, parallelogram_pred_vals.get())) { + for (int c = 0; c < num_components; ++c) { + pred_vals[c] = + AddAsUnsigned(pred_vals[c], parallelogram_pred_vals[c]); + } + ++num_parallelograms; + } + + // Proceed to the next corner attached to the vertex. + corner_id = table->SwingRight(corner_id); + if (corner_id == start_corner_id) { + corner_id = kInvalidCornerIndex; + } + } + + const int dst_offset = p * num_components; + if (num_parallelograms == 0) { + // No parallelogram was valid. + // We use the last decoded point as a reference. + const int src_offset = (p - 1) * num_components; + this->transform().ComputeOriginalValue( + out_data + src_offset, in_corr + dst_offset, out_data + dst_offset); + } else { + // Compute the correction from the predicted value. + for (int c = 0; c < num_components; ++c) { + pred_vals[c] /= num_parallelograms; + } + this->transform().ComputeOriginalValue( + pred_vals.get(), in_corr + dst_offset, out_data + dst_offset); + } + } + return true; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_MULTI_PARALLELOGRAM_DECODER_H_ +#endif diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h new file mode 100644 index 0000000000..301b357d41 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h @@ -0,0 +1,133 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_MULTI_PARALLELOGRAM_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_MULTI_PARALLELOGRAM_ENCODER_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h" + +namespace draco { + +// Multi parallelogram prediction predicts attribute values using information +// from all opposite faces to the predicted vertex, compared to the standard +// prediction scheme, where only one opposite face is used (see +// prediction_scheme_parallelogram.h). This approach is generally slower than +// the standard parallelogram prediction, but it usually results in better +// prediction (5 - 20% based on the quantization level. Better gains can be +// achieved when more aggressive quantization is used). +template +class MeshPredictionSchemeMultiParallelogramEncoder + : public MeshPredictionSchemeEncoder { + public: + using CorrType = + typename PredictionSchemeEncoder::CorrType; + using CornerTable = typename MeshDataT::CornerTable; + + explicit MeshPredictionSchemeMultiParallelogramEncoder( + const PointAttribute *attribute) + : MeshPredictionSchemeEncoder( + attribute) {} + MeshPredictionSchemeMultiParallelogramEncoder(const PointAttribute *attribute, + const TransformT &transform, + const MeshDataT &mesh_data) + : MeshPredictionSchemeEncoder( + attribute, transform, mesh_data) {} + + bool ComputeCorrectionValues( + const DataTypeT *in_data, CorrType *out_corr, int size, + int num_components, const PointIndex *entry_to_point_id_map) override; + PredictionSchemeMethod GetPredictionMethod() const override { + return MESH_PREDICTION_MULTI_PARALLELOGRAM; + } + + bool IsInitialized() const override { + return this->mesh_data().IsInitialized(); + } +}; + +template +bool MeshPredictionSchemeMultiParallelogramEncoder:: + ComputeCorrectionValues(const DataTypeT *in_data, CorrType *out_corr, + int size, int num_components, + const PointIndex * /* entry_to_point_id_map */) { + this->transform().Init(in_data, size, num_components); + const CornerTable *const table = this->mesh_data().corner_table(); + const std::vector *const vertex_to_data_map = + this->mesh_data().vertex_to_data_map(); + + // For storage of prediction values (already initialized to zero). + std::unique_ptr pred_vals(new DataTypeT[num_components]()); + std::unique_ptr parallelogram_pred_vals( + new DataTypeT[num_components]()); + + // We start processing from the end because this prediction uses data from + // previous entries that could be overwritten when an entry is processed. + for (int p = + static_cast(this->mesh_data().data_to_corner_map()->size() - 1); + p > 0; --p) { + const CornerIndex start_corner_id = + this->mesh_data().data_to_corner_map()->at(p); + + // Go over all corners attached to the vertex and compute the predicted + // value from the parallelograms defined by their opposite faces. + CornerIndex corner_id(start_corner_id); + int num_parallelograms = 0; + for (int i = 0; i < num_components; ++i) { + pred_vals[i] = static_cast(0); + } + while (corner_id != kInvalidCornerIndex) { + if (ComputeParallelogramPrediction( + p, corner_id, table, *vertex_to_data_map, in_data, num_components, + parallelogram_pred_vals.get())) { + for (int c = 0; c < num_components; ++c) { + pred_vals[c] += parallelogram_pred_vals[c]; + } + ++num_parallelograms; + } + + // Proceed to the next corner attached to the vertex. + corner_id = table->SwingRight(corner_id); + if (corner_id == start_corner_id) { + corner_id = kInvalidCornerIndex; + } + } + const int dst_offset = p * num_components; + if (num_parallelograms == 0) { + // No parallelogram was valid. + // We use the last encoded point as a reference. + const int src_offset = (p - 1) * num_components; + this->transform().ComputeCorrection( + in_data + dst_offset, in_data + src_offset, out_corr + dst_offset); + } else { + // Compute the correction from the predicted value. + for (int c = 0; c < num_components; ++c) { + pred_vals[c] /= num_parallelograms; + } + this->transform().ComputeCorrection(in_data + dst_offset, pred_vals.get(), + out_corr + dst_offset); + } + } + // First element is always fixed because it cannot be predicted. + for (int i = 0; i < num_components; ++i) { + pred_vals[i] = static_cast(0); + } + this->transform().ComputeCorrection(in_data, pred_vals.get(), out_corr); + return true; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_MULTI_PARALLELOGRAM_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h new file mode 100644 index 0000000000..4d47ddf306 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h @@ -0,0 +1,98 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_PARALLELOGRAM_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_PARALLELOGRAM_DECODER_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h" + +namespace draco { + +// Decoder for attribute values encoded with the standard parallelogram +// prediction. See the description of the corresponding encoder for more +// details. +template +class MeshPredictionSchemeParallelogramDecoder + : public MeshPredictionSchemeDecoder { + public: + using CorrType = + typename PredictionSchemeDecoder::CorrType; + using CornerTable = typename MeshDataT::CornerTable; + explicit MeshPredictionSchemeParallelogramDecoder( + const PointAttribute *attribute) + : MeshPredictionSchemeDecoder( + attribute) {} + MeshPredictionSchemeParallelogramDecoder(const PointAttribute *attribute, + const TransformT &transform, + const MeshDataT &mesh_data) + : MeshPredictionSchemeDecoder( + attribute, transform, mesh_data) {} + + bool ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data, + int size, int num_components, + const PointIndex *entry_to_point_id_map) override; + PredictionSchemeMethod GetPredictionMethod() const override { + return MESH_PREDICTION_PARALLELOGRAM; + } + + bool IsInitialized() const override { + return this->mesh_data().IsInitialized(); + } +}; + +template +bool MeshPredictionSchemeParallelogramDecoder:: + ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data, + int /* size */, int num_components, + const PointIndex * /* entry_to_point_id_map */) { + this->transform().Init(num_components); + + const CornerTable *const table = this->mesh_data().corner_table(); + const std::vector *const vertex_to_data_map = + this->mesh_data().vertex_to_data_map(); + + // For storage of prediction values (already initialized to zero). + std::unique_ptr pred_vals(new DataTypeT[num_components]()); + + // Restore the first value. + this->transform().ComputeOriginalValue(pred_vals.get(), in_corr, out_data); + + const int corner_map_size = + static_cast(this->mesh_data().data_to_corner_map()->size()); + for (int p = 1; p < corner_map_size; ++p) { + const CornerIndex corner_id = this->mesh_data().data_to_corner_map()->at(p); + const int dst_offset = p * num_components; + if (!ComputeParallelogramPrediction(p, corner_id, table, + *vertex_to_data_map, out_data, + num_components, pred_vals.get())) { + // Parallelogram could not be computed, Possible because some of the + // vertices are not valid (not encoded yet). + // We use the last encoded point as a reference (delta coding). + const int src_offset = (p - 1) * num_components; + this->transform().ComputeOriginalValue( + out_data + src_offset, in_corr + dst_offset, out_data + dst_offset); + } else { + // Apply the parallelogram prediction. + this->transform().ComputeOriginalValue( + pred_vals.get(), in_corr + dst_offset, out_data + dst_offset); + } + } + return true; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_PARALLELOGRAM_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h new file mode 100644 index 0000000000..f00801932c --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h @@ -0,0 +1,111 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_PARALLELOGRAM_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_PARALLELOGRAM_ENCODER_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h" + +namespace draco { + +// Parallelogram prediction predicts an attribute value V from three vertices +// on the opposite face to the predicted vertex. The values on the three +// vertices are used to construct a parallelogram V' = O - A - B, where O is the +// value on the opposite vertex, and A, B are values on the shared vertices: +// V +// / \ +// / \ +// / \ +// A-------B +// \ / +// \ / +// \ / +// O +// +template +class MeshPredictionSchemeParallelogramEncoder + : public MeshPredictionSchemeEncoder { + public: + using CorrType = + typename PredictionSchemeEncoder::CorrType; + using CornerTable = typename MeshDataT::CornerTable; + explicit MeshPredictionSchemeParallelogramEncoder( + const PointAttribute *attribute) + : MeshPredictionSchemeEncoder( + attribute) {} + MeshPredictionSchemeParallelogramEncoder(const PointAttribute *attribute, + const TransformT &transform, + const MeshDataT &mesh_data) + : MeshPredictionSchemeEncoder( + attribute, transform, mesh_data) {} + + bool ComputeCorrectionValues( + const DataTypeT *in_data, CorrType *out_corr, int size, + int num_components, const PointIndex *entry_to_point_id_map) override; + PredictionSchemeMethod GetPredictionMethod() const override { + return MESH_PREDICTION_PARALLELOGRAM; + } + + bool IsInitialized() const override { + return this->mesh_data().IsInitialized(); + } +}; + +template +bool MeshPredictionSchemeParallelogramEncoder:: + ComputeCorrectionValues(const DataTypeT *in_data, CorrType *out_corr, + int size, int num_components, + const PointIndex * /* entry_to_point_id_map */) { + this->transform().Init(in_data, size, num_components); + // For storage of prediction values (already initialized to zero). + std::unique_ptr pred_vals(new DataTypeT[num_components]()); + + // We start processing from the end because this prediction uses data from + // previous entries that could be overwritten when an entry is processed. + const CornerTable *const table = this->mesh_data().corner_table(); + const std::vector *const vertex_to_data_map = + this->mesh_data().vertex_to_data_map(); + for (int p = + static_cast(this->mesh_data().data_to_corner_map()->size() - 1); + p > 0; --p) { + const CornerIndex corner_id = this->mesh_data().data_to_corner_map()->at(p); + const int dst_offset = p * num_components; + if (!ComputeParallelogramPrediction(p, corner_id, table, + *vertex_to_data_map, in_data, + num_components, pred_vals.get())) { + // Parallelogram could not be computed, Possible because some of the + // vertices are not valid (not encoded yet). + // We use the last encoded point as a reference (delta coding). + const int src_offset = (p - 1) * num_components; + this->transform().ComputeCorrection( + in_data + dst_offset, in_data + src_offset, out_corr + dst_offset); + } else { + // Apply the parallelogram prediction. + this->transform().ComputeCorrection(in_data + dst_offset, pred_vals.get(), + out_corr + dst_offset); + } + } + // First element is always fixed because it cannot be predicted. + for (int i = 0; i < num_components; ++i) { + pred_vals[i] = static_cast(0); + } + this->transform().ComputeCorrection(in_data, pred_vals.get(), out_corr); + return true; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_PARALLELOGRAM_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h new file mode 100644 index 0000000000..fd10fb524b --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h @@ -0,0 +1,78 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Shared functionality for different parallelogram prediction schemes. + +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_PARALLELOGRAM_SHARED_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_PARALLELOGRAM_SHARED_H_ + +#include "draco/mesh/corner_table.h" +#include "draco/mesh/mesh.h" + +namespace draco { + +// TODO(draco-eng) consolidate Vertex/next/previous queries to one call +// (performance). +template +inline void GetParallelogramEntries( + const CornerIndex ci, const CornerTableT *table, + const std::vector &vertex_to_data_map, int *opp_entry, + int *next_entry, int *prev_entry) { + // One vertex of the input |table| correspond to exactly one attribute value + // entry. The |table| can be either CornerTable for per-vertex attributes, + // or MeshAttributeCornerTable for attributes with interior seams. + *opp_entry = vertex_to_data_map[table->Vertex(ci).value()]; + *next_entry = vertex_to_data_map[table->Vertex(table->Next(ci)).value()]; + *prev_entry = vertex_to_data_map[table->Vertex(table->Previous(ci)).value()]; +} + +// Computes parallelogram prediction for a given corner and data entry id. +// The prediction is stored in |out_prediction|. +// Function returns false when the prediction couldn't be computed, e.g. because +// not all entry points were available. +template +inline bool ComputeParallelogramPrediction( + int data_entry_id, const CornerIndex ci, const CornerTableT *table, + const std::vector &vertex_to_data_map, const DataTypeT *in_data, + int num_components, DataTypeT *out_prediction) { + const CornerIndex oci = table->Opposite(ci); + if (oci == kInvalidCornerIndex) { + return false; + } + int vert_opp, vert_next, vert_prev; + GetParallelogramEntries(oci, table, vertex_to_data_map, + &vert_opp, &vert_next, &vert_prev); + if (vert_opp < data_entry_id && vert_next < data_entry_id && + vert_prev < data_entry_id) { + // Apply the parallelogram prediction. + const int v_opp_off = vert_opp * num_components; + const int v_next_off = vert_next * num_components; + const int v_prev_off = vert_prev * num_components; + for (int c = 0; c < num_components; ++c) { + const int64_t in_data_next_off = in_data[v_next_off + c]; + const int64_t in_data_prev_off = in_data[v_prev_off + c]; + const int64_t in_data_opp_off = in_data[v_opp_off + c]; + const int64_t result = + (in_data_next_off + in_data_prev_off) - in_data_opp_off; + + out_prediction[c] = static_cast(result); + } + return true; + } + return false; // Not all data is available for prediction +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_PARALLELOGRAM_SHARED_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h new file mode 100644 index 0000000000..865af6ddf9 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h @@ -0,0 +1,372 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_DECODER_H_ + +#include + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h" +#include "draco/compression/bit_coders/rans_bit_decoder.h" +#include "draco/core/varint_decoding.h" +#include "draco/core/vector_d.h" +#include "draco/draco_features.h" +#include "draco/mesh/corner_table.h" + +namespace draco { + +// Decoder for predictions of UV coordinates encoded by our specialized texture +// coordinate predictor. See the corresponding encoder for more details. Note +// that this predictor is not portable and should not be used anymore. See +// MeshPredictionSchemeTexCoordsPortableEncoder/Decoder for a portable version +// of this prediction scheme. +template +class MeshPredictionSchemeTexCoordsDecoder + : public MeshPredictionSchemeDecoder { + public: + using CorrType = typename MeshPredictionSchemeDecoder::CorrType; + MeshPredictionSchemeTexCoordsDecoder(const PointAttribute *attribute, + const TransformT &transform, + const MeshDataT &mesh_data, int version) + : MeshPredictionSchemeDecoder( + attribute, transform, mesh_data), + pos_attribute_(nullptr), + entry_to_point_id_map_(nullptr), + num_components_(0), + version_(version) {} + + bool ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data, + int size, int num_components, + const PointIndex *entry_to_point_id_map) override; + + bool DecodePredictionData(DecoderBuffer *buffer) override; + + PredictionSchemeMethod GetPredictionMethod() const override { + return MESH_PREDICTION_TEX_COORDS_DEPRECATED; + } + + bool IsInitialized() const override { + if (pos_attribute_ == nullptr) { + return false; + } + if (!this->mesh_data().IsInitialized()) { + return false; + } + return true; + } + + int GetNumParentAttributes() const override { return 1; } + + GeometryAttribute::Type GetParentAttributeType(int i) const override { + DRACO_DCHECK_EQ(i, 0); + (void)i; + return GeometryAttribute::POSITION; + } + + bool SetParentAttribute(const PointAttribute *att) override { + if (att == nullptr) { + return false; + } + if (att->attribute_type() != GeometryAttribute::POSITION) { + return false; // Invalid attribute type. + } + if (att->num_components() != 3) { + return false; // Currently works only for 3 component positions. + } + pos_attribute_ = att; + return true; + } + + protected: + Vector3f GetPositionForEntryId(int entry_id) const { + const PointIndex point_id = entry_to_point_id_map_[entry_id]; + Vector3f pos; + pos_attribute_->ConvertValue(pos_attribute_->mapped_index(point_id), + &pos[0]); + return pos; + } + + Vector2f GetTexCoordForEntryId(int entry_id, const DataTypeT *data) const { + const int data_offset = entry_id * num_components_; + return Vector2f(static_cast(data[data_offset]), + static_cast(data[data_offset + 1])); + } + + bool ComputePredictedValue(CornerIndex corner_id, const DataTypeT *data, + int data_id); + + private: + const PointAttribute *pos_attribute_; + const PointIndex *entry_to_point_id_map_; + std::unique_ptr predicted_value_; + int num_components_; + // Encoded / decoded array of UV flips. + std::vector orientations_; + int version_; +}; + +template +bool MeshPredictionSchemeTexCoordsDecoder:: + ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data, + int /* size */, int num_components, + const PointIndex *entry_to_point_id_map) { + if (num_components != 2) { + // Corrupt/malformed input. Two output components are req'd. + return false; + } + num_components_ = num_components; + entry_to_point_id_map_ = entry_to_point_id_map; + predicted_value_ = + std::unique_ptr(new DataTypeT[num_components]); + this->transform().Init(num_components); + + const int corner_map_size = + static_cast(this->mesh_data().data_to_corner_map()->size()); + for (int p = 0; p < corner_map_size; ++p) { + const CornerIndex corner_id = this->mesh_data().data_to_corner_map()->at(p); + if (!ComputePredictedValue(corner_id, out_data, p)) { + return false; + } + + const int dst_offset = p * num_components; + this->transform().ComputeOriginalValue( + predicted_value_.get(), in_corr + dst_offset, out_data + dst_offset); + } + return true; +} + +template +bool MeshPredictionSchemeTexCoordsDecoder:: + DecodePredictionData(DecoderBuffer *buffer) { + // Decode the delta coded orientations. + uint32_t num_orientations = 0; + if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) { + if (!buffer->Decode(&num_orientations)) { + return false; + } + } else { + if (!DecodeVarint(&num_orientations, buffer)) { + return false; + } + } + if (num_orientations == 0) { + return false; + } + if (num_orientations > this->mesh_data().corner_table()->num_corners()) { + // We can't have more orientations than the maximum number of decoded + // values. + return false; + } + orientations_.resize(num_orientations); + bool last_orientation = true; + RAnsBitDecoder decoder; + if (!decoder.StartDecoding(buffer)) { + return false; + } + for (uint32_t i = 0; i < num_orientations; ++i) { + if (!decoder.DecodeNextBit()) { + last_orientation = !last_orientation; + } + orientations_[i] = last_orientation; + } + decoder.EndDecoding(); + return MeshPredictionSchemeDecoder::DecodePredictionData(buffer); +} + +template +bool MeshPredictionSchemeTexCoordsDecoder:: + ComputePredictedValue(CornerIndex corner_id, const DataTypeT *data, + int data_id) { + // Compute the predicted UV coordinate from the positions on all corners + // of the processed triangle. For the best prediction, the UV coordinates + // on the next/previous corners need to be already encoded/decoded. + const CornerIndex next_corner_id = + this->mesh_data().corner_table()->Next(corner_id); + const CornerIndex prev_corner_id = + this->mesh_data().corner_table()->Previous(corner_id); + // Get the encoded data ids from the next and previous corners. + // The data id is the encoding order of the UV coordinates. + int next_data_id, prev_data_id; + + int next_vert_id, prev_vert_id; + next_vert_id = + this->mesh_data().corner_table()->Vertex(next_corner_id).value(); + prev_vert_id = + this->mesh_data().corner_table()->Vertex(prev_corner_id).value(); + + next_data_id = this->mesh_data().vertex_to_data_map()->at(next_vert_id); + prev_data_id = this->mesh_data().vertex_to_data_map()->at(prev_vert_id); + + if (prev_data_id < data_id && next_data_id < data_id) { + // Both other corners have available UV coordinates for prediction. + const Vector2f n_uv = GetTexCoordForEntryId(next_data_id, data); + const Vector2f p_uv = GetTexCoordForEntryId(prev_data_id, data); + if (p_uv == n_uv) { + // We cannot do a reliable prediction on degenerated UV triangles. + // Technically floats > INT_MAX are undefined, but compilers will + // convert those values to INT_MIN. We are being explicit here for asan. + for (const int i : {0, 1}) { + if (std::isnan(p_uv[i]) || static_cast(p_uv[i]) > INT_MAX || + static_cast(p_uv[i]) < INT_MIN) { + predicted_value_[i] = INT_MIN; + } else { + predicted_value_[i] = static_cast(p_uv[i]); + } + } + return true; + } + + // Get positions at all corners. + const Vector3f tip_pos = GetPositionForEntryId(data_id); + const Vector3f next_pos = GetPositionForEntryId(next_data_id); + const Vector3f prev_pos = GetPositionForEntryId(prev_data_id); + // Use the positions of the above triangle to predict the texture coordinate + // on the tip corner C. + // Convert the triangle into a new coordinate system defined by orthogonal + // bases vectors S, T, where S is vector prev_pos - next_pos and T is an + // perpendicular vector to S in the same plane as vector the + // tip_pos - next_pos. + // The transformed triangle in the new coordinate system is then going to + // be represented as: + // + // 1 ^ + // | + // | + // | C + // | / \ + // | / \ + // |/ \ + // N--------------P + // 0 1 + // + // Where next_pos point (N) is at position (0, 0), prev_pos point (P) is + // at (1, 0). Our goal is to compute the position of the tip_pos point (C) + // in this new coordinate space (s, t). + // + const Vector3f pn = prev_pos - next_pos; + const Vector3f cn = tip_pos - next_pos; + const float pn_norm2_squared = pn.SquaredNorm(); + // Coordinate s of the tip corner C is simply the dot product of the + // normalized vectors |pn| and |cn| (normalized by the length of |pn|). + // Since both of these vectors are normalized, we don't need to perform the + // normalization explicitly and instead we can just use the squared norm + // of |pn| as a denominator of the resulting dot product of non normalized + // vectors. + float s, t; + // |pn_norm2_squared| can be exactly 0 when the next_pos and prev_pos are + // the same positions (e.g. because they were quantized to the same + // location). + if (version_ < DRACO_BITSTREAM_VERSION(1, 2) || pn_norm2_squared > 0) { + s = pn.Dot(cn) / pn_norm2_squared; + // To get the coordinate t, we can use formula: + // t = |C-N - (P-N) * s| / |P-N| + // Do not use std::sqrt to avoid changes in the bitstream. + t = sqrt((cn - pn * s).SquaredNorm() / pn_norm2_squared); + } else { + s = 0; + t = 0; + } + + // Now we need to transform the point (s, t) to the texture coordinate space + // UV. We know the UV coordinates on points N and P (N_UV and P_UV). Lets + // denote P_UV - N_UV = PN_UV. PN_UV is then 2 dimensional vector that can + // be used to define transformation from the normalized coordinate system + // to the texture coordinate system using a 3x3 affine matrix M: + // + // M = | PN_UV[0] -PN_UV[1] N_UV[0] | + // | PN_UV[1] PN_UV[0] N_UV[1] | + // | 0 0 1 | + // + // The predicted point C_UV in the texture space is then equal to + // C_UV = M * (s, t, 1). Because the triangle in UV space may be flipped + // around the PN_UV axis, we also need to consider point C_UV' = M * (s, -t) + // as the prediction. + const Vector2f pn_uv = p_uv - n_uv; + const float pnus = pn_uv[0] * s + n_uv[0]; + const float pnut = pn_uv[0] * t; + const float pnvs = pn_uv[1] * s + n_uv[1]; + const float pnvt = pn_uv[1] * t; + Vector2f predicted_uv; + if (orientations_.empty()) { + return false; + } + + // When decoding the data, we already know which orientation to use. + const bool orientation = orientations_.back(); + orientations_.pop_back(); + if (orientation) { + predicted_uv = Vector2f(pnus - pnvt, pnvs + pnut); + } else { + predicted_uv = Vector2f(pnus + pnvt, pnvs - pnut); + } + if (std::is_integral::value) { + // Round the predicted value for integer types. + // Technically floats > INT_MAX are undefined, but compilers will + // convert those values to INT_MIN. We are being explicit here for asan. + const double u = floor(predicted_uv[0] + 0.5); + if (std::isnan(u) || u > INT_MAX || u < INT_MIN) { + predicted_value_[0] = INT_MIN; + } else { + predicted_value_[0] = static_cast(u); + } + const double v = floor(predicted_uv[1] + 0.5); + if (std::isnan(v) || v > INT_MAX || v < INT_MIN) { + predicted_value_[1] = INT_MIN; + } else { + predicted_value_[1] = static_cast(v); + } + } else { + predicted_value_[0] = static_cast(predicted_uv[0]); + predicted_value_[1] = static_cast(predicted_uv[1]); + } + + return true; + } + // Else we don't have available textures on both corners. For such case we + // can't use positions for predicting the uv value and we resort to delta + // coding. + int data_offset = 0; + if (prev_data_id < data_id) { + // Use the value on the previous corner as the prediction. + data_offset = prev_data_id * num_components_; + } + if (next_data_id < data_id) { + // Use the value on the next corner as the prediction. + data_offset = next_data_id * num_components_; + } else { + // None of the other corners have a valid value. Use the last encoded value + // as the prediction if possible. + if (data_id > 0) { + data_offset = (data_id - 1) * num_components_; + } else { + // We are encoding the first value. Predict 0. + for (int i = 0; i < num_components_; ++i) { + predicted_value_[i] = 0; + } + return true; + } + } + for (int i = 0; i < num_components_; ++i) { + predicted_value_[i] = data[data_offset + i]; + } + return true; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_DECODER_H_ +#endif diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h new file mode 100644 index 0000000000..813b72ae35 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h @@ -0,0 +1,318 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_ENCODER_H_ + +#include + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h" +#include "draco/compression/bit_coders/rans_bit_encoder.h" +#include "draco/core/varint_encoding.h" +#include "draco/core/vector_d.h" +#include "draco/mesh/corner_table.h" + +namespace draco { + +// Prediction scheme designed for predicting texture coordinates from known +// spatial position of vertices. For good parametrization, the ratios between +// triangle edge lengths should be about the same in both the spatial and UV +// coordinate spaces, which makes the positions a good predictor for the UV +// coordinates. +template +class MeshPredictionSchemeTexCoordsEncoder + : public MeshPredictionSchemeEncoder { + public: + using CorrType = typename MeshPredictionSchemeEncoder::CorrType; + MeshPredictionSchemeTexCoordsEncoder(const PointAttribute *attribute, + const TransformT &transform, + const MeshDataT &mesh_data) + : MeshPredictionSchemeEncoder( + attribute, transform, mesh_data), + pos_attribute_(nullptr), + entry_to_point_id_map_(nullptr), + num_components_(0) {} + + bool ComputeCorrectionValues( + const DataTypeT *in_data, CorrType *out_corr, int size, + int num_components, const PointIndex *entry_to_point_id_map) override; + + bool EncodePredictionData(EncoderBuffer *buffer) override; + + PredictionSchemeMethod GetPredictionMethod() const override { + return MESH_PREDICTION_TEX_COORDS_DEPRECATED; + } + + bool IsInitialized() const override { + if (pos_attribute_ == nullptr) { + return false; + } + if (!this->mesh_data().IsInitialized()) { + return false; + } + return true; + } + + int GetNumParentAttributes() const override { return 1; } + + GeometryAttribute::Type GetParentAttributeType(int i) const override { + DRACO_DCHECK_EQ(i, 0); + (void)i; + return GeometryAttribute::POSITION; + } + + bool SetParentAttribute(const PointAttribute *att) override { + if (att->attribute_type() != GeometryAttribute::POSITION) { + return false; // Invalid attribute type. + } + if (att->num_components() != 3) { + return false; // Currently works only for 3 component positions. + } + pos_attribute_ = att; + return true; + } + + protected: + Vector3f GetPositionForEntryId(int entry_id) const { + const PointIndex point_id = entry_to_point_id_map_[entry_id]; + Vector3f pos; + pos_attribute_->ConvertValue(pos_attribute_->mapped_index(point_id), + &pos[0]); + return pos; + } + + Vector2f GetTexCoordForEntryId(int entry_id, const DataTypeT *data) const { + const int data_offset = entry_id * num_components_; + return Vector2f(static_cast(data[data_offset]), + static_cast(data[data_offset + 1])); + } + + void ComputePredictedValue(CornerIndex corner_id, const DataTypeT *data, + int data_id); + + private: + const PointAttribute *pos_attribute_; + const PointIndex *entry_to_point_id_map_; + std::unique_ptr predicted_value_; + int num_components_; + // Encoded / decoded array of UV flips. + std::vector orientations_; +}; + +template +bool MeshPredictionSchemeTexCoordsEncoder:: + ComputeCorrectionValues(const DataTypeT *in_data, CorrType *out_corr, + int size, int num_components, + const PointIndex *entry_to_point_id_map) { + num_components_ = num_components; + entry_to_point_id_map_ = entry_to_point_id_map; + predicted_value_ = + std::unique_ptr(new DataTypeT[num_components]); + this->transform().Init(in_data, size, num_components); + // We start processing from the end because this prediction uses data from + // previous entries that could be overwritten when an entry is processed. + for (int p = + static_cast(this->mesh_data().data_to_corner_map()->size()) - 1; + p >= 0; --p) { + const CornerIndex corner_id = this->mesh_data().data_to_corner_map()->at(p); + ComputePredictedValue(corner_id, in_data, p); + + const int dst_offset = p * num_components; + this->transform().ComputeCorrection( + in_data + dst_offset, predicted_value_.get(), out_corr + dst_offset); + } + return true; +} + +template +bool MeshPredictionSchemeTexCoordsEncoder:: + EncodePredictionData(EncoderBuffer *buffer) { + // Encode the delta-coded orientations using arithmetic coding. + const uint32_t num_orientations = static_cast(orientations_.size()); + EncodeVarint(num_orientations, buffer); + bool last_orientation = true; + RAnsBitEncoder encoder; + encoder.StartEncoding(); + for (bool orientation : orientations_) { + encoder.EncodeBit(orientation == last_orientation); + last_orientation = orientation; + } + encoder.EndEncoding(buffer); + return MeshPredictionSchemeEncoder::EncodePredictionData(buffer); +} + +template +void MeshPredictionSchemeTexCoordsEncoder:: + ComputePredictedValue(CornerIndex corner_id, const DataTypeT *data, + int data_id) { + // Compute the predicted UV coordinate from the positions on all corners + // of the processed triangle. For the best prediction, the UV coordinates + // on the next/previous corners need to be already encoded/decoded. + const CornerIndex next_corner_id = + this->mesh_data().corner_table()->Next(corner_id); + const CornerIndex prev_corner_id = + this->mesh_data().corner_table()->Previous(corner_id); + // Get the encoded data ids from the next and previous corners. + // The data id is the encoding order of the UV coordinates. + int next_data_id, prev_data_id; + + int next_vert_id, prev_vert_id; + next_vert_id = + this->mesh_data().corner_table()->Vertex(next_corner_id).value(); + prev_vert_id = + this->mesh_data().corner_table()->Vertex(prev_corner_id).value(); + + next_data_id = this->mesh_data().vertex_to_data_map()->at(next_vert_id); + prev_data_id = this->mesh_data().vertex_to_data_map()->at(prev_vert_id); + + if (prev_data_id < data_id && next_data_id < data_id) { + // Both other corners have available UV coordinates for prediction. + const Vector2f n_uv = GetTexCoordForEntryId(next_data_id, data); + const Vector2f p_uv = GetTexCoordForEntryId(prev_data_id, data); + if (p_uv == n_uv) { + // We cannot do a reliable prediction on degenerated UV triangles. + predicted_value_[0] = static_cast(p_uv[0]); + predicted_value_[1] = static_cast(p_uv[1]); + return; + } + + // Get positions at all corners. + const Vector3f tip_pos = GetPositionForEntryId(data_id); + const Vector3f next_pos = GetPositionForEntryId(next_data_id); + const Vector3f prev_pos = GetPositionForEntryId(prev_data_id); + // Use the positions of the above triangle to predict the texture coordinate + // on the tip corner C. + // Convert the triangle into a new coordinate system defined by orthogonal + // bases vectors S, T, where S is vector prev_pos - next_pos and T is an + // perpendicular vector to S in the same plane as vector the + // tip_pos - next_pos. + // The transformed triangle in the new coordinate system is then going to + // be represented as: + // + // 1 ^ + // | + // | + // | C + // | / \ + // | / \ + // |/ \ + // N--------------P + // 0 1 + // + // Where next_pos point (N) is at position (0, 0), prev_pos point (P) is + // at (1, 0). Our goal is to compute the position of the tip_pos point (C) + // in this new coordinate space (s, t). + // + const Vector3f pn = prev_pos - next_pos; + const Vector3f cn = tip_pos - next_pos; + const float pn_norm2_squared = pn.SquaredNorm(); + // Coordinate s of the tip corner C is simply the dot product of the + // normalized vectors |pn| and |cn| (normalized by the length of |pn|). + // Since both of these vectors are normalized, we don't need to perform the + // normalization explicitly and instead we can just use the squared norm + // of |pn| as a denominator of the resulting dot product of non normalized + // vectors. + float s, t; + // |pn_norm2_squared| can be exactly 0 when the next_pos and prev_pos are + // the same positions (e.g. because they were quantized to the same + // location). + if (pn_norm2_squared > 0) { + s = pn.Dot(cn) / pn_norm2_squared; + // To get the coordinate t, we can use formula: + // t = |C-N - (P-N) * s| / |P-N| + // Do not use std::sqrt to avoid changes in the bitstream. + t = sqrt((cn - pn * s).SquaredNorm() / pn_norm2_squared); + } else { + s = 0; + t = 0; + } + + // Now we need to transform the point (s, t) to the texture coordinate space + // UV. We know the UV coordinates on points N and P (N_UV and P_UV). Lets + // denote P_UV - N_UV = PN_UV. PN_UV is then 2 dimensional vector that can + // be used to define transformation from the normalized coordinate system + // to the texture coordinate system using a 3x3 affine matrix M: + // + // M = | PN_UV[0] -PN_UV[1] N_UV[0] | + // | PN_UV[1] PN_UV[0] N_UV[1] | + // | 0 0 1 | + // + // The predicted point C_UV in the texture space is then equal to + // C_UV = M * (s, t, 1). Because the triangle in UV space may be flipped + // around the PN_UV axis, we also need to consider point C_UV' = M * (s, -t) + // as the prediction. + const Vector2f pn_uv = p_uv - n_uv; + const float pnus = pn_uv[0] * s + n_uv[0]; + const float pnut = pn_uv[0] * t; + const float pnvs = pn_uv[1] * s + n_uv[1]; + const float pnvt = pn_uv[1] * t; + Vector2f predicted_uv; + + // When encoding compute both possible vectors and determine which one + // results in a better prediction. + const Vector2f predicted_uv_0(pnus - pnvt, pnvs + pnut); + const Vector2f predicted_uv_1(pnus + pnvt, pnvs - pnut); + const Vector2f c_uv = GetTexCoordForEntryId(data_id, data); + if ((c_uv - predicted_uv_0).SquaredNorm() < + (c_uv - predicted_uv_1).SquaredNorm()) { + predicted_uv = predicted_uv_0; + orientations_.push_back(true); + } else { + predicted_uv = predicted_uv_1; + orientations_.push_back(false); + } + if (std::is_integral::value) { + // Round the predicted value for integer types. + predicted_value_[0] = static_cast(floor(predicted_uv[0] + 0.5)); + predicted_value_[1] = static_cast(floor(predicted_uv[1] + 0.5)); + } else { + predicted_value_[0] = static_cast(predicted_uv[0]); + predicted_value_[1] = static_cast(predicted_uv[1]); + } + return; + } + // Else we don't have available textures on both corners. For such case we + // can't use positions for predicting the uv value and we resort to delta + // coding. + int data_offset = 0; + if (prev_data_id < data_id) { + // Use the value on the previous corner as the prediction. + data_offset = prev_data_id * num_components_; + } + if (next_data_id < data_id) { + // Use the value on the next corner as the prediction. + data_offset = next_data_id * num_components_; + } else { + // None of the other corners have a valid value. Use the last encoded value + // as the prediction if possible. + if (data_id > 0) { + data_offset = (data_id - 1) * num_components_; + } else { + // We are encoding the first value. Predict 0. + for (int i = 0; i < num_components_; ++i) { + predicted_value_[i] = 0; + } + return; + } + } + for (int i = 0; i < num_components_; ++i) { + predicted_value_[i] = data[data_offset + i]; + } +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h new file mode 100644 index 0000000000..83d4966393 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h @@ -0,0 +1,143 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_PORTABLE_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_PORTABLE_DECODER_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h" +#include "draco/compression/bit_coders/rans_bit_decoder.h" + +namespace draco { + +// Decoder for predictions of UV coordinates encoded by our specialized and +// portable texture coordinate predictor. See the corresponding encoder for more +// details. +template +class MeshPredictionSchemeTexCoordsPortableDecoder + : public MeshPredictionSchemeDecoder { + public: + using CorrType = typename MeshPredictionSchemeDecoder::CorrType; + MeshPredictionSchemeTexCoordsPortableDecoder(const PointAttribute *attribute, + const TransformT &transform, + const MeshDataT &mesh_data) + : MeshPredictionSchemeDecoder( + attribute, transform, mesh_data), + predictor_(mesh_data) {} + + bool ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data, + int size, int num_components, + const PointIndex *entry_to_point_id_map) override; + + bool DecodePredictionData(DecoderBuffer *buffer) override; + + PredictionSchemeMethod GetPredictionMethod() const override { + return MESH_PREDICTION_TEX_COORDS_PORTABLE; + } + + bool IsInitialized() const override { + if (!predictor_.IsInitialized()) { + return false; + } + if (!this->mesh_data().IsInitialized()) { + return false; + } + return true; + } + + int GetNumParentAttributes() const override { return 1; } + + GeometryAttribute::Type GetParentAttributeType(int i) const override { + DRACO_DCHECK_EQ(i, 0); + (void)i; + return GeometryAttribute::POSITION; + } + + bool SetParentAttribute(const PointAttribute *att) override { + if (!att || att->attribute_type() != GeometryAttribute::POSITION) { + return false; // Invalid attribute type. + } + if (att->num_components() != 3) { + return false; // Currently works only for 3 component positions. + } + predictor_.SetPositionAttribute(*att); + return true; + } + + private: + MeshPredictionSchemeTexCoordsPortablePredictor + predictor_; +}; + +template +bool MeshPredictionSchemeTexCoordsPortableDecoder< + DataTypeT, TransformT, + MeshDataT>::ComputeOriginalValues(const CorrType *in_corr, + DataTypeT *out_data, int /* size */, + int num_components, + const PointIndex *entry_to_point_id_map) { + if (num_components != MeshPredictionSchemeTexCoordsPortablePredictor< + DataTypeT, MeshDataT>::kNumComponents) { + return false; + } + predictor_.SetEntryToPointIdMap(entry_to_point_id_map); + this->transform().Init(num_components); + + const int corner_map_size = + static_cast(this->mesh_data().data_to_corner_map()->size()); + for (int p = 0; p < corner_map_size; ++p) { + const CornerIndex corner_id = this->mesh_data().data_to_corner_map()->at(p); + if (!predictor_.template ComputePredictedValue(corner_id, out_data, + p)) { + return false; + } + + const int dst_offset = p * num_components; + this->transform().ComputeOriginalValue(predictor_.predicted_value(), + in_corr + dst_offset, + out_data + dst_offset); + } + return true; +} + +template +bool MeshPredictionSchemeTexCoordsPortableDecoder< + DataTypeT, TransformT, MeshDataT>::DecodePredictionData(DecoderBuffer + *buffer) { + // Decode the delta coded orientations. + int32_t num_orientations = 0; + if (!buffer->Decode(&num_orientations) || num_orientations < 0) { + return false; + } + predictor_.ResizeOrientations(num_orientations); + bool last_orientation = true; + RAnsBitDecoder decoder; + if (!decoder.StartDecoding(buffer)) { + return false; + } + for (int i = 0; i < num_orientations; ++i) { + if (!decoder.DecodeNextBit()) { + last_orientation = !last_orientation; + } + predictor_.set_orientation(i, last_orientation); + } + decoder.EndDecoding(); + return MeshPredictionSchemeDecoder::DecodePredictionData(buffer); +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_PORTABLE_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h new file mode 100644 index 0000000000..44fcc7a6a2 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h @@ -0,0 +1,136 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_PORTABLE_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_PORTABLE_ENCODER_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h" +#include "draco/compression/bit_coders/rans_bit_encoder.h" + +namespace draco { + +// Prediction scheme designed for predicting texture coordinates from known +// spatial position of vertices. For isometric parametrizations, the ratios +// between triangle edge lengths should be about the same in both the spatial +// and UV coordinate spaces, which makes the positions a good predictor for the +// UV coordinates. Note that this may not be the optimal approach for other +// parametrizations such as projective ones. +template +class MeshPredictionSchemeTexCoordsPortableEncoder + : public MeshPredictionSchemeEncoder { + public: + using CorrType = typename MeshPredictionSchemeEncoder::CorrType; + MeshPredictionSchemeTexCoordsPortableEncoder(const PointAttribute *attribute, + const TransformT &transform, + const MeshDataT &mesh_data) + : MeshPredictionSchemeEncoder( + attribute, transform, mesh_data), + predictor_(mesh_data) {} + + bool ComputeCorrectionValues( + const DataTypeT *in_data, CorrType *out_corr, int size, + int num_components, const PointIndex *entry_to_point_id_map) override; + + bool EncodePredictionData(EncoderBuffer *buffer) override; + + PredictionSchemeMethod GetPredictionMethod() const override { + return MESH_PREDICTION_TEX_COORDS_PORTABLE; + } + + bool IsInitialized() const override { + if (!predictor_.IsInitialized()) { + return false; + } + if (!this->mesh_data().IsInitialized()) { + return false; + } + return true; + } + + int GetNumParentAttributes() const override { return 1; } + + GeometryAttribute::Type GetParentAttributeType(int i) const override { + DRACO_DCHECK_EQ(i, 0); + (void)i; + return GeometryAttribute::POSITION; + } + + bool SetParentAttribute(const PointAttribute *att) override { + if (att->attribute_type() != GeometryAttribute::POSITION) { + return false; // Invalid attribute type. + } + if (att->num_components() != 3) { + return false; // Currently works only for 3 component positions. + } + predictor_.SetPositionAttribute(*att); + return true; + } + + private: + MeshPredictionSchemeTexCoordsPortablePredictor + predictor_; +}; + +template +bool MeshPredictionSchemeTexCoordsPortableEncoder:: + ComputeCorrectionValues(const DataTypeT *in_data, CorrType *out_corr, + int size, int num_components, + const PointIndex *entry_to_point_id_map) { + predictor_.SetEntryToPointIdMap(entry_to_point_id_map); + this->transform().Init(in_data, size, num_components); + // We start processing from the end because this prediction uses data from + // previous entries that could be overwritten when an entry is processed. + for (int p = + static_cast(this->mesh_data().data_to_corner_map()->size() - 1); + p >= 0; --p) { + const CornerIndex corner_id = this->mesh_data().data_to_corner_map()->at(p); + if (!predictor_.template ComputePredictedValue(corner_id, in_data, + p)) { + return false; + } + + const int dst_offset = p * num_components; + this->transform().ComputeCorrection(in_data + dst_offset, + predictor_.predicted_value(), + out_corr + dst_offset); + } + return true; +} + +template +bool MeshPredictionSchemeTexCoordsPortableEncoder< + DataTypeT, TransformT, MeshDataT>::EncodePredictionData(EncoderBuffer + *buffer) { + // Encode the delta-coded orientations using arithmetic coding. + const int32_t num_orientations = predictor_.num_orientations(); + buffer->Encode(num_orientations); + bool last_orientation = true; + RAnsBitEncoder encoder; + encoder.StartEncoding(); + for (int i = 0; i < num_orientations; ++i) { + const bool orientation = predictor_.orientation(i); + encoder.EncodeBit(orientation == last_orientation); + last_orientation = orientation; + } + encoder.EndEncoding(buffer); + return MeshPredictionSchemeEncoder::EncodePredictionData(buffer); +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_PORTABLE_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h new file mode 100644 index 0000000000..985a5918f8 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h @@ -0,0 +1,282 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_PORTABLE_PREDICTOR_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_PORTABLE_PREDICTOR_H_ + +#include + +#include +#include + +#include "draco/attributes/point_attribute.h" +#include "draco/core/math_utils.h" +#include "draco/core/vector_d.h" +#include "draco/mesh/corner_table.h" + +namespace draco { + +// Predictor functionality used for portable UV prediction by both encoder and +// decoder. +template +class MeshPredictionSchemeTexCoordsPortablePredictor { + public: + static constexpr int kNumComponents = 2; + + explicit MeshPredictionSchemeTexCoordsPortablePredictor(const MeshDataT &md) + : pos_attribute_(nullptr), + entry_to_point_id_map_(nullptr), + mesh_data_(md) {} + void SetPositionAttribute(const PointAttribute &position_attribute) { + pos_attribute_ = &position_attribute; + } + void SetEntryToPointIdMap(const PointIndex *map) { + entry_to_point_id_map_ = map; + } + bool IsInitialized() const { return pos_attribute_ != nullptr; } + + VectorD GetPositionForEntryId(int entry_id) const { + const PointIndex point_id = entry_to_point_id_map_[entry_id]; + VectorD pos; + pos_attribute_->ConvertValue(pos_attribute_->mapped_index(point_id), + &pos[0]); + return pos; + } + + VectorD GetTexCoordForEntryId(int entry_id, + const DataTypeT *data) const { + const int data_offset = entry_id * kNumComponents; + return VectorD(data[data_offset], data[data_offset + 1]); + } + + // Computes predicted UV coordinates on a given corner. The coordinates are + // stored in |predicted_value_| member. + template + bool ComputePredictedValue(CornerIndex corner_id, const DataTypeT *data, + int data_id); + + const DataTypeT *predicted_value() const { return predicted_value_; } + bool orientation(int i) const { return orientations_[i]; } + void set_orientation(int i, bool v) { orientations_[i] = v; } + size_t num_orientations() const { return orientations_.size(); } + void ResizeOrientations(int num_orientations) { + orientations_.resize(num_orientations); + } + + private: + const PointAttribute *pos_attribute_; + const PointIndex *entry_to_point_id_map_; + DataTypeT predicted_value_[kNumComponents]; + // Encoded / decoded array of UV flips. + // TODO(ostava): We should remove this and replace this with in-place encoding + // and decoding to avoid unnecessary copy. + std::vector orientations_; + MeshDataT mesh_data_; +}; + +template +template +bool MeshPredictionSchemeTexCoordsPortablePredictor< + DataTypeT, MeshDataT>::ComputePredictedValue(CornerIndex corner_id, + const DataTypeT *data, + int data_id) { + // Compute the predicted UV coordinate from the positions on all corners + // of the processed triangle. For the best prediction, the UV coordinates + // on the next/previous corners need to be already encoded/decoded. + const CornerIndex next_corner_id = mesh_data_.corner_table()->Next(corner_id); + const CornerIndex prev_corner_id = + mesh_data_.corner_table()->Previous(corner_id); + // Get the encoded data ids from the next and previous corners. + // The data id is the encoding order of the UV coordinates. + int next_data_id, prev_data_id; + + int next_vert_id, prev_vert_id; + next_vert_id = mesh_data_.corner_table()->Vertex(next_corner_id).value(); + prev_vert_id = mesh_data_.corner_table()->Vertex(prev_corner_id).value(); + + next_data_id = mesh_data_.vertex_to_data_map()->at(next_vert_id); + prev_data_id = mesh_data_.vertex_to_data_map()->at(prev_vert_id); + + typedef VectorD Vec2; + typedef VectorD Vec3; + typedef VectorD Vec2u; + + if (prev_data_id < data_id && next_data_id < data_id) { + // Both other corners have available UV coordinates for prediction. + const Vec2 n_uv = GetTexCoordForEntryId(next_data_id, data); + const Vec2 p_uv = GetTexCoordForEntryId(prev_data_id, data); + if (p_uv == n_uv) { + // We cannot do a reliable prediction on degenerated UV triangles. + predicted_value_[0] = p_uv[0]; + predicted_value_[1] = p_uv[1]; + return true; + } + + // Get positions at all corners. + const Vec3 tip_pos = GetPositionForEntryId(data_id); + const Vec3 next_pos = GetPositionForEntryId(next_data_id); + const Vec3 prev_pos = GetPositionForEntryId(prev_data_id); + // We use the positions of the above triangle to predict the texture + // coordinate on the tip corner C. + // To convert the triangle into the UV coordinate system we first compute + // position X on the vector |prev_pos - next_pos| that is the projection of + // point C onto vector |prev_pos - next_pos|: + // + // C + // /. \ + // / . \ + // / . \ + // N---X----------P + // + // Where next_pos is point (N), prev_pos is point (P) and tip_pos is the + // position of predicted coordinate (C). + // + const Vec3 pn = prev_pos - next_pos; + const uint64_t pn_norm2_squared = pn.SquaredNorm(); + if (pn_norm2_squared != 0) { + // Compute the projection of C onto PN by computing dot product of CN with + // PN and normalizing it by length of PN. This gives us a factor |s| where + // |s = PN.Dot(CN) / PN.SquaredNorm2()|. This factor can be used to + // compute X in UV space |X_UV| as |X_UV = N_UV + s * PN_UV|. + const Vec3 cn = tip_pos - next_pos; + const int64_t cn_dot_pn = pn.Dot(cn); + + const Vec2 pn_uv = p_uv - n_uv; + // Because we perform all computations with integers, we don't explicitly + // compute the normalized factor |s|, but rather we perform all operations + // over UV vectors in a non-normalized coordinate system scaled with a + // scaling factor |pn_norm2_squared|: + // + // x_uv = X_UV * PN.Norm2Squared() + // + const int64_t n_uv_absmax_element = + std::max(std::abs(n_uv[0]), std::abs(n_uv[1])); + if (n_uv_absmax_element > + std::numeric_limits::max() / pn_norm2_squared) { + // Return false if the below multiplication would overflow. + return false; + } + const int64_t pn_uv_absmax_element = + std::max(std::abs(pn_uv[0]), std::abs(pn_uv[1])); + if (std::abs(cn_dot_pn) > + std::numeric_limits::max() / pn_uv_absmax_element) { + // Return false if squared length calculation would overflow. + return false; + } + const Vec2 x_uv = n_uv * pn_norm2_squared + (cn_dot_pn * pn_uv); + const int64_t pn_absmax_element = + std::max(std::max(std::abs(pn[0]), std::abs(pn[1])), std::abs(pn[2])); + if (std::abs(cn_dot_pn) > + std::numeric_limits::max() / pn_absmax_element) { + // Return false if squared length calculation would overflow. + return false; + } + + // Compute squared length of vector CX in position coordinate system: + const Vec3 x_pos = next_pos + (cn_dot_pn * pn) / pn_norm2_squared; + const uint64_t cx_norm2_squared = (tip_pos - x_pos).SquaredNorm(); + + // Compute vector CX_UV in the uv space by rotating vector PN_UV by 90 + // degrees and scaling it with factor CX.Norm2() / PN.Norm2(): + // + // CX_UV = (CX.Norm2() / PN.Norm2()) * Rot(PN_UV) + // + // To preserve precision, we perform all operations in scaled space as + // explained above, so we want the final vector to be: + // + // cx_uv = CX_UV * PN.Norm2Squared() + // + // We can then rewrite the formula as: + // + // cx_uv = CX.Norm2() * PN.Norm2() * Rot(PN_UV) + // + Vec2 cx_uv(pn_uv[1], -pn_uv[0]); // Rotated PN_UV. + // Compute CX.Norm2() * PN.Norm2() + const uint64_t norm_squared = + IntSqrt(cx_norm2_squared * pn_norm2_squared); + // Final cx_uv in the scaled coordinate space. + cx_uv = cx_uv * norm_squared; + + // Predicted uv coordinate is then computed by either adding or + // subtracting CX_UV to/from X_UV. + Vec2 predicted_uv; + if (is_encoder_t) { + // When encoding, compute both possible vectors and determine which one + // results in a better prediction. + // Both vectors need to be transformed back from the scaled space to + // the real UV coordinate space. + const Vec2 predicted_uv_0((x_uv + cx_uv) / pn_norm2_squared); + const Vec2 predicted_uv_1((x_uv - cx_uv) / pn_norm2_squared); + const Vec2 c_uv = GetTexCoordForEntryId(data_id, data); + if ((c_uv - predicted_uv_0).SquaredNorm() < + (c_uv - predicted_uv_1).SquaredNorm()) { + predicted_uv = predicted_uv_0; + orientations_.push_back(true); + } else { + predicted_uv = predicted_uv_1; + orientations_.push_back(false); + } + } else { + // When decoding the data, we already know which orientation to use. + if (orientations_.empty()) { + return false; + } + const bool orientation = orientations_.back(); + orientations_.pop_back(); + // Perform operations in unsigned type to avoid signed integer overflow. + // Note that the result will be the same (for non-overflowing values). + if (orientation) { + predicted_uv = Vec2(Vec2u(x_uv) + Vec2u(cx_uv)) / pn_norm2_squared; + } else { + predicted_uv = Vec2(Vec2u(x_uv) - Vec2u(cx_uv)) / pn_norm2_squared; + } + } + predicted_value_[0] = static_cast(predicted_uv[0]); + predicted_value_[1] = static_cast(predicted_uv[1]); + return true; + } + } + // Else we don't have available textures on both corners or the position data + // is invalid. For such cases we can't use positions for predicting the uv + // value and we resort to delta coding. + int data_offset = 0; + if (prev_data_id < data_id) { + // Use the value on the previous corner as the prediction. + data_offset = prev_data_id * kNumComponents; + } + if (next_data_id < data_id) { + // Use the value on the next corner as the prediction. + data_offset = next_data_id * kNumComponents; + } else { + // None of the other corners have a valid value. Use the last encoded value + // as the prediction if possible. + if (data_id > 0) { + data_offset = (data_id - 1) * kNumComponents; + } else { + // We are encoding the first value. Predict 0. + for (int i = 0; i < kNumComponents; ++i) { + predicted_value_[i] = 0; + } + return true; + } + } + for (int i = 0; i < kNumComponents; ++i) { + predicted_value_[i] = data[data_offset + i]; + } + return true; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_PORTABLE_PREDICTOR_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h new file mode 100644 index 0000000000..064e1b44fe --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h @@ -0,0 +1,90 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_H_ + +#include + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h" + +// Prediction schemes can be used during encoding and decoding of vertex +// attributes to predict attribute values based on the previously +// encoded/decoded data. The differences between the original and predicted +// attribute values are used to compute correction values that can be usually +// encoded with fewer bits compared to the original data. +namespace draco { + +// Abstract base class for typed prediction schemes. It provides basic access +// to the encoded attribute and to the supplied prediction transform. +template > +class PredictionSchemeDecoder : public PredictionSchemeTypedDecoderInterface< + DataTypeT, typename TransformT::CorrType> { + public: + typedef DataTypeT DataType; + typedef TransformT Transform; + // Correction type needs to be defined in the prediction transform class. + typedef typename Transform::CorrType CorrType; + explicit PredictionSchemeDecoder(const PointAttribute *attribute) + : PredictionSchemeDecoder(attribute, Transform()) {} + PredictionSchemeDecoder(const PointAttribute *attribute, + const Transform &transform) + : attribute_(attribute), transform_(transform) {} + + bool DecodePredictionData(DecoderBuffer *buffer) override { + if (!transform_.DecodeTransformData(buffer)) { + return false; + } + return true; + } + + const PointAttribute *GetAttribute() const override { return attribute(); } + + // Returns the number of parent attributes that are needed for the prediction. + int GetNumParentAttributes() const override { return 0; } + + // Returns the type of each of the parent attribute. + GeometryAttribute::Type GetParentAttributeType(int /* i */) const override { + return GeometryAttribute::INVALID; + } + + // Sets the required parent attribute. + bool SetParentAttribute(const PointAttribute * /* att */) override { + return false; + } + + bool AreCorrectionsPositive() override { + return transform_.AreCorrectionsPositive(); + } + + PredictionSchemeTransformType GetTransformType() const override { + return transform_.GetType(); + } + + protected: + inline const PointAttribute *attribute() const { return attribute_; } + inline const Transform &transform() const { return transform_; } + inline Transform &transform() { return transform_; } + + private: + const PointAttribute *attribute_; + Transform transform_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h new file mode 100644 index 0000000000..cf2a6ba6b3 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h @@ -0,0 +1,194 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Functions for creating prediction schemes for decoders using the provided +// prediction method id. + +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_FACTORY_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_FACTORY_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h" +#include "draco/draco_features.h" +#ifdef DRACO_NORMAL_ENCODING_SUPPORTED +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h" +#endif +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h" +#include "draco/compression/mesh/mesh_decoder.h" + +namespace draco { + +// Factory class for creating mesh prediction schemes. The factory implements +// operator() that is used to create an appropriate mesh prediction scheme in +// CreateMeshPredictionScheme() function in prediction_scheme_factory.h +template +struct MeshPredictionSchemeDecoderFactory { + // Operator () specialized for the wrap transform. Wrap transform can be used + // for all mesh prediction schemes. The specialization is done in compile time + // to prevent instantiations of unneeded combinations of prediction schemes + + // prediction transforms. + template + struct DispatchFunctor { + std::unique_ptr> operator()( + PredictionSchemeMethod method, const PointAttribute *attribute, + const TransformT &transform, const MeshDataT &mesh_data, + uint16_t bitstream_version) { + if (method == MESH_PREDICTION_PARALLELOGRAM) { + return std::unique_ptr>( + new MeshPredictionSchemeParallelogramDecoder( + attribute, transform, mesh_data)); + } +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + else if (method == MESH_PREDICTION_MULTI_PARALLELOGRAM) { + return std::unique_ptr>( + new MeshPredictionSchemeMultiParallelogramDecoder< + DataTypeT, TransformT, MeshDataT>(attribute, transform, + mesh_data)); + } +#endif + else if (method == MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM) { + return std::unique_ptr>( + new MeshPredictionSchemeConstrainedMultiParallelogramDecoder< + DataTypeT, TransformT, MeshDataT>(attribute, transform, + mesh_data)); + } +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + else if (method == MESH_PREDICTION_TEX_COORDS_DEPRECATED) { + return std::unique_ptr>( + new MeshPredictionSchemeTexCoordsDecoder( + attribute, transform, mesh_data, bitstream_version)); + } +#endif + else if (method == MESH_PREDICTION_TEX_COORDS_PORTABLE) { + return std::unique_ptr>( + new MeshPredictionSchemeTexCoordsPortableDecoder< + DataTypeT, TransformT, MeshDataT>(attribute, transform, + mesh_data)); + } +#ifdef DRACO_NORMAL_ENCODING_SUPPORTED + else if (method == MESH_PREDICTION_GEOMETRIC_NORMAL) { + return std::unique_ptr>( + new MeshPredictionSchemeGeometricNormalDecoder< + DataTypeT, TransformT, MeshDataT>(attribute, transform, + mesh_data)); + } +#endif + return nullptr; + } + }; + +#ifdef DRACO_NORMAL_ENCODING_SUPPORTED + // Operator () specialized for normal octahedron transforms. These transforms + // are currently used only by the geometric normal prediction scheme (the + // transform is also used by delta coding, but delta predictor is not + // constructed in this function). + template + struct DispatchFunctor { + std::unique_ptr> operator()( + PredictionSchemeMethod method, const PointAttribute *attribute, + const TransformT &transform, const MeshDataT &mesh_data, + uint16_t bitstream_version) { + if (method == MESH_PREDICTION_GEOMETRIC_NORMAL) { + return std::unique_ptr>( + new MeshPredictionSchemeGeometricNormalDecoder< + DataTypeT, TransformT, MeshDataT>(attribute, transform, + mesh_data)); + } + return nullptr; + } + }; + template + struct DispatchFunctor { + std::unique_ptr> operator()( + PredictionSchemeMethod method, const PointAttribute *attribute, + const TransformT &transform, const MeshDataT &mesh_data, + uint16_t bitstream_version) { + if (method == MESH_PREDICTION_GEOMETRIC_NORMAL) { + return std::unique_ptr>( + new MeshPredictionSchemeGeometricNormalDecoder< + DataTypeT, TransformT, MeshDataT>(attribute, transform, + mesh_data)); + } + return nullptr; + } + }; +#endif + + template + std::unique_ptr> operator()( + PredictionSchemeMethod method, const PointAttribute *attribute, + const TransformT &transform, const MeshDataT &mesh_data, + uint16_t bitstream_version) { + return DispatchFunctor()( + method, attribute, transform, mesh_data, bitstream_version); + } +}; + +// Creates a prediction scheme for a given decoder and given prediction method. +// The prediction schemes are automatically initialized with decoder specific +// data if needed. +template +std::unique_ptr> +CreatePredictionSchemeForDecoder(PredictionSchemeMethod method, int att_id, + const PointCloudDecoder *decoder, + const TransformT &transform) { + if (method == PREDICTION_NONE) { + return nullptr; + } + const PointAttribute *const att = decoder->point_cloud()->attribute(att_id); + if (decoder->GetGeometryType() == TRIANGULAR_MESH) { + // Cast the decoder to mesh decoder. This is not necessarily safe if there + // is some other decoder decides to use TRIANGULAR_MESH as the return type, + // but unfortunately there is not nice work around for this without using + // RTTI (double dispatch and similar concepts will not work because of the + // template nature of the prediction schemes). + const MeshDecoder *const mesh_decoder = + static_cast(decoder); + + auto ret = CreateMeshPredictionScheme< + MeshDecoder, PredictionSchemeDecoder, + MeshPredictionSchemeDecoderFactory>( + mesh_decoder, method, att_id, transform, decoder->bitstream_version()); + if (ret) { + return ret; + } + // Otherwise try to create another prediction scheme. + } + // Create delta decoder. + return std::unique_ptr>( + new PredictionSchemeDeltaDecoder(att, transform)); +} + +// Create a prediction scheme using a default transform constructor. +template +std::unique_ptr> +CreatePredictionSchemeForDecoder(PredictionSchemeMethod method, int att_id, + const PointCloudDecoder *decoder) { + return CreatePredictionSchemeForDecoder( + method, att_id, decoder, TransformT()); +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_FACTORY_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h new file mode 100644 index 0000000000..6f19f7fdb9 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h @@ -0,0 +1,53 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_INTERFACE_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_INTERFACE_H_ + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h" +#include "draco/core/decoder_buffer.h" + +// Prediction schemes can be used during encoding and decoding of attributes +// to predict attribute values based on the previously encoded/decoded data. +// See prediction_scheme.h for more details. +namespace draco { + +// Abstract interface for all prediction schemes used during attribute encoding. +class PredictionSchemeDecoderInterface : public PredictionSchemeInterface { + public: + // Method that can be used to decode any prediction scheme specific data + // from the input buffer. + virtual bool DecodePredictionData(DecoderBuffer *buffer) = 0; +}; + +// A specialized version of the prediction scheme interface for specific +// input and output data types. +// |entry_to_point_id_map| is the mapping between value entries to point ids +// of the associated point cloud, where one entry is defined as |num_components| +// values of the |in_data|. +// DataTypeT is the data type of input and predicted values. +// CorrTypeT is the data type used for storing corrected values. +template +class PredictionSchemeTypedDecoderInterface + : public PredictionSchemeDecoderInterface { + public: + // Reverts changes made by the prediction scheme during encoding. + virtual bool ComputeOriginalValues( + const CorrTypeT *in_corr, DataTypeT *out_data, int size, + int num_components, const PointIndex *entry_to_point_id_map) = 0; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODER_INTERFACE_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h new file mode 100644 index 0000000000..47c1532ad9 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h @@ -0,0 +1,65 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODING_TRANSFORM_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODING_TRANSFORM_H_ + +#include "draco/compression/config/compression_shared.h" +#include "draco/core/decoder_buffer.h" + +namespace draco { + +// PredictionSchemeDecodingTransform is used to transform predicted values and +// correction values into the final original attribute values. +// DataTypeT is the data type of predicted values. +// CorrTypeT is the data type used for storing corrected values. It allows +// transforms to store corrections into a different type or format compared to +// the predicted data. +template +class PredictionSchemeDecodingTransform { + public: + typedef CorrTypeT CorrType; + PredictionSchemeDecodingTransform() : num_components_(0) {} + + void Init(int num_components) { num_components_ = num_components; } + + // Computes the original value from the input predicted value and the decoded + // corrections. The default implementation is equal to std:plus. + inline void ComputeOriginalValue(const DataTypeT *predicted_vals, + const CorrTypeT *corr_vals, + DataTypeT *out_original_vals) const { + static_assert(std::is_same::value, + "For the default prediction transform, correction and input " + "data must be of the same type."); + for (int i = 0; i < num_components_; ++i) { + out_original_vals[i] = predicted_vals[i] + corr_vals[i]; + } + } + + // Decodes any transform specific data. Called before Init() method. + bool DecodeTransformData(DecoderBuffer * /* buffer */) { return true; } + + // Should return true if all corrected values are guaranteed to be positive. + bool AreCorrectionsPositive() const { return false; } + + protected: + int num_components() const { return num_components_; } + + private: + int num_components_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DECODING_TRANSFORM_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h new file mode 100644 index 0000000000..ae72c71208 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h @@ -0,0 +1,65 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DELTA_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DELTA_DECODER_H_ + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h" + +namespace draco { + +// Decoder for values encoded with delta coding. See the corresponding encoder +// for more details. +template +class PredictionSchemeDeltaDecoder + : public PredictionSchemeDecoder { + public: + using CorrType = + typename PredictionSchemeDecoder::CorrType; + // Initialized the prediction scheme. + explicit PredictionSchemeDeltaDecoder(const PointAttribute *attribute) + : PredictionSchemeDecoder(attribute) {} + PredictionSchemeDeltaDecoder(const PointAttribute *attribute, + const TransformT &transform) + : PredictionSchemeDecoder(attribute, transform) {} + + bool ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data, + int size, int num_components, + const PointIndex *entry_to_point_id_map) override; + PredictionSchemeMethod GetPredictionMethod() const override { + return PREDICTION_DIFFERENCE; + } + bool IsInitialized() const override { return true; } +}; + +template +bool PredictionSchemeDeltaDecoder::ComputeOriginalValues( + const CorrType *in_corr, DataTypeT *out_data, int size, int num_components, + const PointIndex *) { + this->transform().Init(num_components); + // Decode the original value for the first element. + std::unique_ptr zero_vals(new DataTypeT[num_components]()); + this->transform().ComputeOriginalValue(zero_vals.get(), in_corr, out_data); + + // Decode data from the front using D(i) = D(i) + D(i - 1). + for (int i = num_components; i < size; i += num_components) { + this->transform().ComputeOriginalValue(out_data + i - num_components, + in_corr + i, out_data + i); + } + return true; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DELTA_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h new file mode 100644 index 0000000000..324afafa63 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h @@ -0,0 +1,69 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DELTA_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DELTA_ENCODER_H_ + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h" + +namespace draco { + +// Basic prediction scheme based on computing backward differences between +// stored attribute values (also known as delta-coding). Usually works better +// than the reference point prediction scheme, because nearby values are often +// encoded next to each other. +template +class PredictionSchemeDeltaEncoder + : public PredictionSchemeEncoder { + public: + using CorrType = + typename PredictionSchemeEncoder::CorrType; + // Initialized the prediction scheme. + explicit PredictionSchemeDeltaEncoder(const PointAttribute *attribute) + : PredictionSchemeEncoder(attribute) {} + PredictionSchemeDeltaEncoder(const PointAttribute *attribute, + const TransformT &transform) + : PredictionSchemeEncoder(attribute, transform) {} + + bool ComputeCorrectionValues( + const DataTypeT *in_data, CorrType *out_corr, int size, + int num_components, const PointIndex *entry_to_point_id_map) override; + PredictionSchemeMethod GetPredictionMethod() const override { + return PREDICTION_DIFFERENCE; + } + bool IsInitialized() const override { return true; } +}; + +template +bool PredictionSchemeDeltaEncoder< + DataTypeT, TransformT>::ComputeCorrectionValues(const DataTypeT *in_data, + CorrType *out_corr, + int size, + int num_components, + const PointIndex *) { + this->transform().Init(in_data, size, num_components); + // Encode data from the back using D(i) = D(i) - D(i - 1). + for (int i = size - num_components; i > 0; i -= num_components) { + this->transform().ComputeCorrection( + in_data + i, in_data + i - num_components, out_corr + i); + } + // Encode correction for the first element. + std::unique_ptr zero_vals(new DataTypeT[num_components]()); + this->transform().ComputeCorrection(in_data, zero_vals.get(), out_corr); + return true; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_DELTA_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h new file mode 100644 index 0000000000..2a211a9fc2 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h @@ -0,0 +1,90 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_H_ + +#include + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h" + +// Prediction schemes can be used during encoding and decoding of vertex +// attributes to predict attribute values based on the previously +// encoded/decoded data. The differences between the original and predicted +// attribute values are used to compute correction values that can be usually +// encoded with fewer bits compared to the original data. +namespace draco { + +// Abstract base class for typed prediction schemes. It provides basic access +// to the encoded attribute and to the supplied prediction transform. +template > +class PredictionSchemeEncoder : public PredictionSchemeTypedEncoderInterface< + DataTypeT, typename TransformT::CorrType> { + public: + typedef DataTypeT DataType; + typedef TransformT Transform; + // Correction type needs to be defined in the prediction transform class. + typedef typename Transform::CorrType CorrType; + explicit PredictionSchemeEncoder(const PointAttribute *attribute) + : PredictionSchemeEncoder(attribute, Transform()) {} + PredictionSchemeEncoder(const PointAttribute *attribute, + const Transform &transform) + : attribute_(attribute), transform_(transform) {} + + bool EncodePredictionData(EncoderBuffer *buffer) override { + if (!transform_.EncodeTransformData(buffer)) { + return false; + } + return true; + } + + const PointAttribute *GetAttribute() const override { return attribute(); } + + // Returns the number of parent attributes that are needed for the prediction. + int GetNumParentAttributes() const override { return 0; } + + // Returns the type of each of the parent attribute. + GeometryAttribute::Type GetParentAttributeType(int /* i */) const override { + return GeometryAttribute::INVALID; + } + + // Sets the required parent attribute. + bool SetParentAttribute(const PointAttribute * /* att */) override { + return false; + } + + bool AreCorrectionsPositive() override { + return transform_.AreCorrectionsPositive(); + } + + PredictionSchemeTransformType GetTransformType() const override { + return transform_.GetType(); + } + + protected: + inline const PointAttribute *attribute() const { return attribute_; } + inline const Transform &transform() const { return transform_; } + inline Transform &transform() { return transform_; } + + private: + const PointAttribute *attribute_; + Transform transform_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc new file mode 100644 index 0000000000..2338f2f760 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc @@ -0,0 +1,120 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h" + +namespace draco { + +PredictionSchemeMethod SelectPredictionMethod( + int att_id, const PointCloudEncoder *encoder) { + return SelectPredictionMethod(att_id, *encoder->options(), encoder); +} + +PredictionSchemeMethod SelectPredictionMethod( + int att_id, const EncoderOptions &options, + const PointCloudEncoder *encoder) { + if (options.GetSpeed() >= 10) { + // Selected fastest, though still doing some compression. + return PREDICTION_DIFFERENCE; + } + if (encoder->GetGeometryType() == TRIANGULAR_MESH) { + // Use speed setting to select the best encoding method. + const int att_quant = + options.GetAttributeInt(att_id, "quantization_bits", -1); + const PointAttribute *const att = encoder->point_cloud()->attribute(att_id); + if (att_quant != -1 && + att->attribute_type() == GeometryAttribute::TEX_COORD && + att->num_components() == 2) { + // Texture coordinate predictor needs a position attribute that is either + // integer or quantized. For numerical reasons, we require the position + // quantization to be at most 21 bits and the 2*position_quantization + + // uv_quantization < 64 (TODO(b/231259902)). + const PointAttribute *const pos_att = + encoder->point_cloud()->GetNamedAttribute( + GeometryAttribute::POSITION); + bool is_pos_att_valid = false; + if (pos_att) { + if (IsDataTypeIntegral(pos_att->data_type())) { + is_pos_att_valid = true; + } else { + // Check quantization of the position attribute. + const int pos_att_id = encoder->point_cloud()->GetNamedAttributeId( + GeometryAttribute::POSITION); + const int pos_quant = + options.GetAttributeInt(pos_att_id, "quantization_bits", -1); + // Must be quantized but the quantization is restricted to 21 bits and + // 2*|pos_quant|+|att_quant| must be smaller than 64 bits. + if (pos_quant > 0 && pos_quant <= 21 && + 2 * pos_quant + att_quant < 64) { + is_pos_att_valid = true; + } + } + } + + if (is_pos_att_valid && options.GetSpeed() < 4) { + // Use texture coordinate prediction for speeds 0, 1, 2, 3. + return MESH_PREDICTION_TEX_COORDS_PORTABLE; + } + } + if (att->attribute_type() == GeometryAttribute::NORMAL) { +#ifdef DRACO_NORMAL_ENCODING_SUPPORTED + if (options.GetSpeed() < 4) { + // Use geometric normal prediction for speeds 0, 1, 2, 3. + // For this prediction, the position attribute needs to be either + // integer or quantized as well. + const int pos_att_id = encoder->point_cloud()->GetNamedAttributeId( + GeometryAttribute::POSITION); + const PointAttribute *const pos_att = + encoder->point_cloud()->GetNamedAttribute( + GeometryAttribute::POSITION); + if (pos_att && (IsDataTypeIntegral(pos_att->data_type()) || + options.GetAttributeInt(pos_att_id, "quantization_bits", + -1) > 0)) { + return MESH_PREDICTION_GEOMETRIC_NORMAL; + } + } +#endif + return PREDICTION_DIFFERENCE; // default + } + // Handle other attribute types. + if (options.GetSpeed() >= 8) { + return PREDICTION_DIFFERENCE; + } + if (options.GetSpeed() >= 2 || encoder->point_cloud()->num_points() < 40) { + // Parallelogram prediction is used for speeds 2 - 7 or when the overhead + // of using constrained multi-parallelogram would be too high. + return MESH_PREDICTION_PARALLELOGRAM; + } + // Multi-parallelogram is used for speeds 0, 1. + return MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM; + } + // Default option is delta coding. + return PREDICTION_DIFFERENCE; +} + +// Returns the preferred prediction scheme based on the encoder options. +PredictionSchemeMethod GetPredictionMethodFromOptions( + int att_id, const EncoderOptions &options) { + const int pred_type = + options.GetAttributeInt(att_id, "prediction_scheme", -1); + if (pred_type == -1) { + return PREDICTION_UNDEFINED; + } + if (pred_type < 0 || pred_type >= NUM_PREDICTION_SCHEMES) { + return PREDICTION_NONE; + } + return static_cast(pred_type); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h new file mode 100644 index 0000000000..11db5a62e5 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h @@ -0,0 +1,134 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Functions for creating prediction schemes for encoders using the provided +// prediction method id. + +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_FACTORY_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_FACTORY_H_ + +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h" +#ifdef DRACO_NORMAL_ENCODING_SUPPORTED +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h" +#endif +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h" +#include "draco/compression/mesh/mesh_encoder.h" + +namespace draco { + +// Selects a prediction method based on the input geometry type and based on the +// encoder options. +PredictionSchemeMethod SelectPredictionMethod(int att_id, + const PointCloudEncoder *encoder); + +PredictionSchemeMethod SelectPredictionMethod(int att_id, + const EncoderOptions &options, + const PointCloudEncoder *encoder); + +// Factory class for creating mesh prediction schemes. +template +struct MeshPredictionSchemeEncoderFactory { + template + std::unique_ptr> operator()( + PredictionSchemeMethod method, const PointAttribute *attribute, + const TransformT &transform, const MeshDataT &mesh_data, + uint16_t bitstream_version) { + if (method == MESH_PREDICTION_PARALLELOGRAM) { + return std::unique_ptr>( + new MeshPredictionSchemeParallelogramEncoder( + attribute, transform, mesh_data)); + } else if (method == MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM) { + return std::unique_ptr>( + new MeshPredictionSchemeConstrainedMultiParallelogramEncoder< + DataTypeT, TransformT, MeshDataT>(attribute, transform, + mesh_data)); + } else if (method == MESH_PREDICTION_TEX_COORDS_PORTABLE) { + return std::unique_ptr>( + new MeshPredictionSchemeTexCoordsPortableEncoder< + DataTypeT, TransformT, MeshDataT>(attribute, transform, + mesh_data)); + } +#ifdef DRACO_NORMAL_ENCODING_SUPPORTED + else if (method == MESH_PREDICTION_GEOMETRIC_NORMAL) { + return std::unique_ptr>( + new MeshPredictionSchemeGeometricNormalEncoder( + attribute, transform, mesh_data)); + } +#endif + return nullptr; + } +}; + +// Creates a prediction scheme for a given encoder and given prediction method. +// The prediction schemes are automatically initialized with encoder specific +// data if needed. +template +std::unique_ptr> +CreatePredictionSchemeForEncoder(PredictionSchemeMethod method, int att_id, + const PointCloudEncoder *encoder, + const TransformT &transform) { + const PointAttribute *const att = encoder->point_cloud()->attribute(att_id); + if (method == PREDICTION_UNDEFINED) { + method = SelectPredictionMethod(att_id, encoder); + } + if (method == PREDICTION_NONE) { + return nullptr; // No prediction is used. + } + if (encoder->GetGeometryType() == TRIANGULAR_MESH) { + // Cast the encoder to mesh encoder. This is not necessarily safe if there + // is some other encoder decides to use TRIANGULAR_MESH as the return type, + // but unfortunately there is not nice work around for this without using + // RTTI (double dispatch and similar concepts will not work because of the + // template nature of the prediction schemes). + const MeshEncoder *const mesh_encoder = + static_cast(encoder); + const uint16_t bitstream_version = kDracoMeshBitstreamVersion; + auto ret = CreateMeshPredictionScheme< + MeshEncoder, PredictionSchemeEncoder, + MeshPredictionSchemeEncoderFactory>( + mesh_encoder, method, att_id, transform, bitstream_version); + if (ret) { + return ret; + } + // Otherwise try to create another prediction scheme. + } + // Create delta encoder. + return std::unique_ptr>( + new PredictionSchemeDeltaEncoder(att, transform)); +} + +// Create a prediction scheme using a default transform constructor. +template +std::unique_ptr> +CreatePredictionSchemeForEncoder(PredictionSchemeMethod method, int att_id, + const PointCloudEncoder *encoder) { + return CreatePredictionSchemeForEncoder( + method, att_id, encoder, TransformT()); +} + +// Returns the preferred prediction scheme based on the encoder options. +PredictionSchemeMethod GetPredictionMethodFromOptions( + int att_id, const EncoderOptions &options); + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_FACTORY_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h new file mode 100644 index 0000000000..37aa9f76a9 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h @@ -0,0 +1,55 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_INTERFACE_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_INTERFACE_H_ + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h" +#include "draco/core/encoder_buffer.h" + +// Prediction schemes can be used during encoding and decoding of attributes +// to predict attribute values based on the previously encoded/decoded data. +// See prediction_scheme.h for more details. +namespace draco { + +// Abstract interface for all prediction schemes used during attribute encoding. +class PredictionSchemeEncoderInterface : public PredictionSchemeInterface { + public: + // Method that can be used to encode any prediction scheme specific data + // into the output buffer. + virtual bool EncodePredictionData(EncoderBuffer *buffer) = 0; +}; + +// A specialized version of the prediction scheme interface for specific +// input and output data types. +// |entry_to_point_id_map| is the mapping between value entries to point ids +// of the associated point cloud, where one entry is defined as |num_components| +// values of the |in_data|. +// DataTypeT is the data type of input and predicted values. +// CorrTypeT is the data type used for storing corrected values. +template +class PredictionSchemeTypedEncoderInterface + : public PredictionSchemeEncoderInterface { + public: + // Applies the prediction scheme when encoding the attribute. + // |in_data| contains value entries to be encoded. + // |out_corr| is an output array containing the to be encoded corrections. + virtual bool ComputeCorrectionValues( + const DataTypeT *in_data, CorrTypeT *out_corr, int size, + int num_components, const PointIndex *entry_to_point_id_map) = 0; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODER_INTERFACE_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h new file mode 100644 index 0000000000..0929492aae --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h @@ -0,0 +1,77 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODING_TRANSFORM_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODING_TRANSFORM_H_ + +#include "draco/compression/config/compression_shared.h" +#include "draco/core/encoder_buffer.h" + +namespace draco { + +// PredictionSchemeEncodingTransform is used to transform predicted values into +// correction values. +// CorrTypeT is the data type used for storing corrected values. It allows +// transforms to store corrections into a different type or format compared to +// the predicted data. +template +class PredictionSchemeEncodingTransform { + public: + typedef CorrTypeT CorrType; + PredictionSchemeEncodingTransform() : num_components_(0) {} + + PredictionSchemeTransformType GetType() const { + return PREDICTION_TRANSFORM_DELTA; + } + + // Performs any custom initialization of the transform for the encoder. + // |size| = total number of values in |orig_data| (i.e., number of entries * + // number of components). + void Init(const DataTypeT * /* orig_data */, int /* size */, + int num_components) { + num_components_ = num_components; + } + + // Computes the corrections based on the input original values and the + // predicted values. The correction is always computed for all components + // of the input element. |val_id| is the id of the input value + // (i.e., element_id * num_components). The default implementation is equal to + // std::minus. + inline void ComputeCorrection(const DataTypeT *original_vals, + const DataTypeT *predicted_vals, + CorrTypeT *out_corr_vals) { + static_assert(std::is_same::value, + "For the default prediction transform, correction and input " + "data must be of the same type."); + for (int i = 0; i < num_components_; ++i) { + out_corr_vals[i] = original_vals[i] - predicted_vals[i]; + } + } + + // Encode any transform specific data. + bool EncodeTransformData(EncoderBuffer * /* buffer */) { return true; } + + // Should return true if all corrected values are guaranteed to be positive. + bool AreCorrectionsPositive() const { return false; } + + protected: + int num_components() const { return num_components_; } + + private: + int num_components_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_ENCODING_TRANSFORM_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h new file mode 100644 index 0000000000..b36c4c8a27 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h @@ -0,0 +1,85 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Functions for creating prediction schemes from a provided prediction method +// name. The functions in this file can create only basic prediction schemes +// that don't require any encoder or decoder specific data. To create more +// sophisticated prediction schemes, use functions from either +// prediction_scheme_encoder_factory.h or, +// prediction_scheme_decoder_factory.h. + +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_FACTORY_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_FACTORY_H_ + +#include "draco/compression/attributes/mesh_attribute_indices_encoding_data.h" +#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h" +#include "draco/compression/config/compression_shared.h" +#include "draco/mesh/mesh_attribute_corner_table.h" + +namespace draco { + +template +std::unique_ptr CreateMeshPredictionScheme( + const EncodingDataSourceT *source, PredictionSchemeMethod method, + int att_id, const typename PredictionSchemeT::Transform &transform, + uint16_t bitstream_version) { + const PointAttribute *const att = source->point_cloud()->attribute(att_id); + if (source->GetGeometryType() == TRIANGULAR_MESH && + (method == MESH_PREDICTION_PARALLELOGRAM || + method == MESH_PREDICTION_MULTI_PARALLELOGRAM || + method == MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM || + method == MESH_PREDICTION_TEX_COORDS_PORTABLE || + method == MESH_PREDICTION_GEOMETRIC_NORMAL || + method == MESH_PREDICTION_TEX_COORDS_DEPRECATED)) { + const CornerTable *const ct = source->GetCornerTable(); + const MeshAttributeIndicesEncodingData *const encoding_data = + source->GetAttributeEncodingData(att_id); + if (ct == nullptr || encoding_data == nullptr) { + // No connectivity data found. + return nullptr; + } + // Connectivity data exists. + const MeshAttributeCornerTable *const att_ct = + source->GetAttributeCornerTable(att_id); + if (att_ct != nullptr) { + typedef MeshPredictionSchemeData MeshData; + MeshData md; + md.Set(source->mesh(), att_ct, + &encoding_data->encoded_attribute_value_index_to_corner_map, + &encoding_data->vertex_to_encoded_attribute_value_index_map); + MeshPredictionSchemeFactoryT factory; + auto ret = factory(method, att, transform, md, bitstream_version); + if (ret) { + return ret; + } + } else { + typedef MeshPredictionSchemeData MeshData; + MeshData md; + md.Set(source->mesh(), ct, + &encoding_data->encoded_attribute_value_index_to_corner_map, + &encoding_data->vertex_to_encoded_attribute_value_index_map); + MeshPredictionSchemeFactoryT factory; + auto ret = factory(method, att, transform, md, bitstream_version); + if (ret) { + return ret; + } + } + } + return nullptr; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_FACTORY_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h new file mode 100644 index 0000000000..c9b3706930 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h @@ -0,0 +1,60 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_INTERFACE_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_INTERFACE_H_ + +#include "draco/attributes/point_attribute.h" +#include "draco/compression/config/compression_shared.h" + +// Prediction schemes can be used during encoding and decoding of attributes +// to predict attribute values based on the previously encoded/decoded data. +// See prediction_scheme.h for more details. +namespace draco { + +// Abstract interface for all prediction schemes used during attribute encoding. +class PredictionSchemeInterface { + public: + virtual ~PredictionSchemeInterface() = default; + virtual PredictionSchemeMethod GetPredictionMethod() const = 0; + + // Returns the encoded attribute. + virtual const PointAttribute *GetAttribute() const = 0; + + // Returns true when the prediction scheme is initialized with all data it + // needs. + virtual bool IsInitialized() const = 0; + + // Returns the number of parent attributes that are needed for the prediction. + virtual int GetNumParentAttributes() const = 0; + + // Returns the type of each of the parent attribute. + virtual GeometryAttribute::Type GetParentAttributeType(int i) const = 0; + + // Sets the required parent attribute. + // Returns false if the attribute doesn't meet the requirements of the + // prediction scheme. + virtual bool SetParentAttribute(const PointAttribute *att) = 0; + + // Method should return true if the prediction scheme guarantees that all + // correction values are always positive (or at least non-negative). + virtual bool AreCorrectionsPositive() = 0; + + // Returns the transform type used by the prediction scheme. + virtual PredictionSchemeTransformType GetTransformType() const = 0; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_INTERFACE_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h new file mode 100644 index 0000000000..e9e345343d --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h @@ -0,0 +1,118 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_CANONICALIZED_DECODING_TRANSFORM_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_CANONICALIZED_DECODING_TRANSFORM_H_ + +#include + +#include "draco/compression/attributes/normal_compression_utils.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h" +#include "draco/core/decoder_buffer.h" +#include "draco/core/macros.h" +#include "draco/core/math_utils.h" +#include "draco/core/vector_d.h" + +namespace draco { + +// Class for converting correction values transformed by the canonicalized +// normal octahedron transform back to the original values. See the +// corresponding encoder for more details. +template +class PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform + : public PredictionSchemeNormalOctahedronCanonicalizedTransformBase< + DataTypeT> { + public: + typedef VectorD Point2; + typedef DataTypeT CorrType; + typedef DataTypeT DataType; + + PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform() {} + + // Dummy to fulfill concept. + void Init(int num_components) {} + + bool DecodeTransformData(DecoderBuffer *buffer) { + DataTypeT max_quantized_value, center_value; + if (!buffer->Decode(&max_quantized_value)) { + return false; + } + if (!buffer->Decode(¢er_value)) { + return false; + } + (void)center_value; + if (!this->set_max_quantized_value(max_quantized_value)) { + return false; + } + // Account for reading wrong values, e.g., due to fuzzing. + if (this->quantization_bits() < 2) { + return false; + } + if (this->quantization_bits() > 30) { + return false; + } + return true; + } + + inline void ComputeOriginalValue(const DataType *pred_vals, + const CorrType *corr_vals, + DataType *out_orig_vals) const { + DRACO_DCHECK_LE(pred_vals[0], 2 * this->center_value()); + DRACO_DCHECK_LE(pred_vals[1], 2 * this->center_value()); + DRACO_DCHECK_LE(corr_vals[0], 2 * this->center_value()); + DRACO_DCHECK_LE(corr_vals[1], 2 * this->center_value()); + + DRACO_DCHECK_LE(0, pred_vals[0]); + DRACO_DCHECK_LE(0, pred_vals[1]); + DRACO_DCHECK_LE(0, corr_vals[0]); + DRACO_DCHECK_LE(0, corr_vals[1]); + + const Point2 pred = Point2(pred_vals[0], pred_vals[1]); + const Point2 corr = Point2(corr_vals[0], corr_vals[1]); + const Point2 orig = ComputeOriginalValue(pred, corr); + + out_orig_vals[0] = orig[0]; + out_orig_vals[1] = orig[1]; + } + + private: + Point2 ComputeOriginalValue(Point2 pred, Point2 corr) const { + const Point2 t(this->center_value(), this->center_value()); + pred = pred - t; + const bool pred_is_in_diamond = this->IsInDiamond(pred[0], pred[1]); + if (!pred_is_in_diamond) { + this->InvertDiamond(&pred[0], &pred[1]); + } + const bool pred_is_in_bottom_left = this->IsInBottomLeft(pred); + const int32_t rotation_count = this->GetRotationCount(pred); + if (!pred_is_in_bottom_left) { + pred = this->RotatePoint(pred, rotation_count); + } + Point2 orig(this->ModMax(AddAsUnsigned(pred[0], corr[0])), + this->ModMax(AddAsUnsigned(pred[1], corr[1]))); + if (!pred_is_in_bottom_left) { + const int32_t reverse_rotation_count = (4 - rotation_count) % 4; + orig = this->RotatePoint(orig, reverse_rotation_count); + } + if (!pred_is_in_diamond) { + this->InvertDiamond(&orig[0], &orig[1]); + } + orig = orig + t; + return orig; + } +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_CANONICALIZED_DECODING_TRANSFORM_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h new file mode 100644 index 0000000000..0dc96967b1 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h @@ -0,0 +1,116 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_CANONICALIZED_ENCODING_TRANSFORM_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_CANONICALIZED_ENCODING_TRANSFORM_H_ + +#include + +#include "draco/compression/attributes/normal_compression_utils.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h" +#include "draco/core/encoder_buffer.h" +#include "draco/core/macros.h" +#include "draco/core/vector_d.h" + +namespace draco { + +// The transform works on octahedral coordinates for normals. The square is +// subdivided into four inner triangles (diamond) and four outer triangles. The +// inner triangles are associated with the upper part of the octahedron and the +// outer triangles are associated with the lower part. +// Given a prediction value P and the actual value Q that should be encoded, +// this transform first checks if P is outside the diamond. If so, the outer +// triangles are flipped towards the inside and vice versa. Then it checks if p +// is in the bottom left quadrant. If it is not, it rotates p and q accordingly. +// The actual correction value is then based on the mapped and rotated P and Q +// values. The inversion tends to result in shorter correction vectors and the +// rotation makes it so that all long correction values are positive, reducing +// the possible value range of the correction values and increasing the +// occurrences of positive large correction values, which helps the entropy +// encoder. This is possible since P is also known by the decoder, see also +// ComputeCorrection and ComputeOriginalValue functions. +// Note that the tile is not periodic, which implies that the outer edges can +// not be identified, which requires us to use an odd number of values on each +// axis. +// DataTypeT is expected to be some integral type. +// +template +class PredictionSchemeNormalOctahedronCanonicalizedEncodingTransform + : public PredictionSchemeNormalOctahedronCanonicalizedTransformBase< + DataTypeT> { + public: + typedef PredictionSchemeNormalOctahedronCanonicalizedTransformBase + Base; + typedef VectorD Point2; + typedef DataTypeT CorrType; + typedef DataTypeT DataType; + + // We expect the mod value to be of the form 2^b-1. + explicit PredictionSchemeNormalOctahedronCanonicalizedEncodingTransform( + DataType max_quantized_value) + : Base(max_quantized_value) {} + + // Dummy function to fulfill concept. + void Init(const DataTypeT *orig_data, int size, int num_components) {} + + bool EncodeTransformData(EncoderBuffer *buffer) { + buffer->Encode(this->max_quantized_value()); + buffer->Encode(this->center_value()); + return true; + } + + inline void ComputeCorrection(const DataType *orig_vals, + const DataType *pred_vals, + CorrType *out_corr_vals) const { + DRACO_DCHECK_LE(pred_vals[0], this->center_value() * 2); + DRACO_DCHECK_LE(pred_vals[1], this->center_value() * 2); + DRACO_DCHECK_LE(orig_vals[0], this->center_value() * 2); + DRACO_DCHECK_LE(orig_vals[1], this->center_value() * 2); + DRACO_DCHECK_LE(0, pred_vals[0]); + DRACO_DCHECK_LE(0, pred_vals[1]); + DRACO_DCHECK_LE(0, orig_vals[0]); + DRACO_DCHECK_LE(0, orig_vals[1]); + + const Point2 orig = Point2(orig_vals[0], orig_vals[1]); + const Point2 pred = Point2(pred_vals[0], pred_vals[1]); + const Point2 corr = ComputeCorrection(orig, pred); + + out_corr_vals[0] = corr[0]; + out_corr_vals[1] = corr[1]; + } + + private: + Point2 ComputeCorrection(Point2 orig, Point2 pred) const { + const Point2 t(this->center_value(), this->center_value()); + orig = orig - t; + pred = pred - t; + if (!this->IsInDiamond(pred[0], pred[1])) { + this->InvertDiamond(&orig[0], &orig[1]); + this->InvertDiamond(&pred[0], &pred[1]); + } + if (!this->IsInBottomLeft(pred)) { + const int32_t rotation_count = this->GetRotationCount(pred); + orig = this->RotatePoint(orig, rotation_count); + pred = this->RotatePoint(pred, rotation_count); + } + Point2 corr = orig - pred; + corr[0] = this->MakePositive(corr[0]); + corr[1] = this->MakePositive(corr[1]); + return corr; + } +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_CANONICALIZED_ENCODING_TRANSFORM_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h new file mode 100644 index 0000000000..4a1e3a67b8 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h @@ -0,0 +1,102 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_CANONICALIZED_TRANSFORM_BASE_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_CANONICALIZED_TRANSFORM_BASE_H_ + +#include + +#include "draco/compression/attributes/normal_compression_utils.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h" +#include "draco/compression/config/compression_shared.h" +#include "draco/core/bit_utils.h" +#include "draco/core/macros.h" +#include "draco/core/vector_d.h" + +namespace draco { + +// Base class containing shared functionality used by both encoding and decoding +// canonicalized normal octahedron prediction scheme transforms. See the +// encoding transform for more details about the method. +template +class PredictionSchemeNormalOctahedronCanonicalizedTransformBase + : public PredictionSchemeNormalOctahedronTransformBase { + public: + typedef PredictionSchemeNormalOctahedronTransformBase Base; + typedef VectorD Point2; + typedef DataTypeT DataType; + + PredictionSchemeNormalOctahedronCanonicalizedTransformBase() : Base() {} + // We expect the mod value to be of the form 2^b-1. + explicit PredictionSchemeNormalOctahedronCanonicalizedTransformBase( + DataType mod_value) + : Base(mod_value) {} + + static constexpr PredictionSchemeTransformType GetType() { + return PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED; + } + + int32_t GetRotationCount(Point2 pred) const { + const DataType sign_x = pred[0]; + const DataType sign_y = pred[1]; + + int32_t rotation_count = 0; + if (sign_x == 0) { + if (sign_y == 0) { + rotation_count = 0; + } else if (sign_y > 0) { + rotation_count = 3; + } else { + rotation_count = 1; + } + } else if (sign_x > 0) { + if (sign_y >= 0) { + rotation_count = 2; + } else { + rotation_count = 1; + } + } else { + if (sign_y <= 0) { + rotation_count = 0; + } else { + rotation_count = 3; + } + } + return rotation_count; + } + + Point2 RotatePoint(Point2 p, int32_t rotation_count) const { + switch (rotation_count) { + case 1: + return Point2(p[1], -p[0]); + case 2: + return Point2(-p[0], -p[1]); + case 3: + return Point2(-p[1], p[0]); + default: + return p; + } + } + + bool IsInBottomLeft(const Point2 &p) const { + if (p[0] == 0 && p[1] == 0) { + return true; + } + return (p[0] < 0 && p[1] <= 0); + } +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_CANONICALIZED_TRANSFORM_BASE_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_test.cc b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_test.cc new file mode 100644 index 0000000000..298758d8c4 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_test.cc @@ -0,0 +1,192 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h" +#include "draco/core/draco_test_base.h" + +namespace { + +class PredictionSchemeNormalOctahedronCanonicalizedTransformTest + : public ::testing::Test { + protected: + typedef draco::PredictionSchemeNormalOctahedronCanonicalizedEncodingTransform< + int32_t> + Transform; + typedef Transform::Point2 Point2; + + void TestComputeCorrection(const Transform &transform, const int32_t ox, + const int32_t oy, const int32_t px, + const int32_t py, const int32_t cx, + const int32_t cy) { + const int32_t o[2] = {ox + 7, oy + 7}; + const int32_t p[2] = {px + 7, py + 7}; + int32_t corr[2] = {500, 500}; + transform.ComputeCorrection(o, p, corr); + ASSERT_EQ(corr[0], (cx + 15) % 15); + ASSERT_EQ(corr[1], (cy + 15) % 15); + } + + void TestGetRotationCount(const Transform &transform, const Point2 &pred, + const int32_t rot_dir) { + const int32_t rotation_count = transform.GetRotationCount(pred); + ASSERT_EQ(rot_dir, rotation_count); + } + + void TestRotateRepresentation(const Transform &transform, const Point2 &org, + const Point2 &pred, const Point2 &rot_org, + const Point2 &rot_pred) { + const int32_t rotation_count = transform.GetRotationCount(pred); + const Point2 res_org = transform.RotatePoint(org, rotation_count); + const Point2 res_pred = transform.RotatePoint(pred, rotation_count); + ASSERT_EQ(rot_org[0], res_org[0]); + ASSERT_EQ(rot_org[1], res_org[1]); + ASSERT_EQ(rot_pred[0], res_pred[0]); + ASSERT_EQ(rot_pred[1], res_pred[1]); + } +}; + +TEST_F(PredictionSchemeNormalOctahedronCanonicalizedTransformTest, Init) { + const Transform transform(15); + ASSERT_TRUE(transform.AreCorrectionsPositive()); +} + +TEST_F(PredictionSchemeNormalOctahedronCanonicalizedTransformTest, + IsInBottomLeft) { + const Transform transform(15); + ASSERT_TRUE(transform.IsInBottomLeft(Point2(0, 0))); + ASSERT_TRUE(transform.IsInBottomLeft(Point2(-1, -1))); + ASSERT_TRUE(transform.IsInBottomLeft(Point2(-7, -7))); + + ASSERT_FALSE(transform.IsInBottomLeft(Point2(1, 1))); + ASSERT_FALSE(transform.IsInBottomLeft(Point2(7, 7))); + ASSERT_FALSE(transform.IsInBottomLeft(Point2(-1, 1))); + ASSERT_FALSE(transform.IsInBottomLeft(Point2(-7, 7))); + ASSERT_FALSE(transform.IsInBottomLeft(Point2(1, -1))); + ASSERT_FALSE(transform.IsInBottomLeft(Point2(7, -7))); +} + +TEST_F(PredictionSchemeNormalOctahedronCanonicalizedTransformTest, + GetRotationCount) { + const Transform transform(15); + TestGetRotationCount(transform, Point2(1, 2), 2); // top right + TestGetRotationCount(transform, Point2(-1, 2), 3); // top left + TestGetRotationCount(transform, Point2(1, -2), 1); // bottom right + TestGetRotationCount(transform, Point2(-1, -2), 0); // bottom left + TestGetRotationCount(transform, Point2(0, 2), 3); // top left + TestGetRotationCount(transform, Point2(0, -2), 1); // bottom right + TestGetRotationCount(transform, Point2(2, 0), 2); // top right + TestGetRotationCount(transform, Point2(-2, 0), 0); // bottom left + TestGetRotationCount(transform, Point2(0, 0), 0); // bottom left +} + +TEST_F(PredictionSchemeNormalOctahedronCanonicalizedTransformTest, + RotateRepresentation) { + const Transform transform(15); + // p top left; shift clockwise by 3 + TestRotateRepresentation(transform, Point2(1, 2), Point2(-3, 1), + Point2(-2, 1), Point2(-1, -3)); // q top right + TestRotateRepresentation(transform, Point2(-1, -2), Point2(-3, 1), + Point2(2, -1), Point2(-1, -3)); // q bottom left + TestRotateRepresentation(transform, Point2(1, -2), Point2(-3, 1), + Point2(2, 1), Point2(-1, -3)); // q bottom right + TestRotateRepresentation(transform, Point2(-1, 2), Point2(-3, 1), + Point2(-2, -1), Point2(-1, -3)); // q top left + // p top right; shift clockwise by 2 (flip) + TestRotateRepresentation(transform, Point2(1, 1), Point2(1, 3), + Point2(-1, -1), Point2(-1, -3)); // q top right + TestRotateRepresentation(transform, Point2(-1, -2), Point2(1, 3), + Point2(1, 2), Point2(-1, -3)); // q bottom left + TestRotateRepresentation(transform, Point2(-1, 2), Point2(1, 3), + Point2(1, -2), Point2(-1, -3)); // q top left + TestRotateRepresentation(transform, Point2(1, -2), Point2(1, 3), + Point2(-1, 2), Point2(-1, -3)); // q bottom right + // p bottom right; shift clockwise by 1 + TestRotateRepresentation(transform, Point2(1, 2), Point2(3, -1), + Point2(2, -1), Point2(-1, -3)); // q top right + TestRotateRepresentation(transform, Point2(1, -2), Point2(3, -1), + Point2(-2, -1), Point2(-1, -3)); // q bottom right + TestRotateRepresentation(transform, Point2(-1, -2), Point2(3, -1), + Point2(-2, 1), Point2(-1, -3)); // q bottom left + TestRotateRepresentation(transform, Point2(-1, 2), Point2(3, -1), + Point2(2, 1), Point2(-1, -3)); // q top left + // p bottom left; no change + TestRotateRepresentation(transform, Point2(1, 2), Point2(-1, -3), + Point2(1, 2), Point2(-1, -3)); // q top right + TestRotateRepresentation(transform, Point2(-1, 2), Point2(-1, -3), + Point2(-1, 2), Point2(-1, -3)); // q top left + TestRotateRepresentation(transform, Point2(1, -2), Point2(-1, -3), + Point2(1, -2), Point2(-1, -3)); // q bottom right + TestRotateRepresentation(transform, Point2(-1, -2), Point2(-1, -3), + Point2(-1, -2), Point2(-1, -3)); // q bottom left +} + +TEST_F(PredictionSchemeNormalOctahedronCanonicalizedTransformTest, + ComputeCorrection) { + const Transform transform(15); + TestComputeCorrection(transform, 0, 0, 0, 0, 0, 0); + TestComputeCorrection(transform, 1, 1, 1, 1, 0, 0); + // inside diamond; p top right + TestComputeCorrection(transform, 3, 4, 1, 2, -2, -2); // q top right + TestComputeCorrection(transform, -3, 4, 1, 2, 4, -2); // q top left + TestComputeCorrection(transform, 3, -4, 1, 2, -2, 6); // q bottom right + TestComputeCorrection(transform, -3, -4, 1, 2, 4, 6); // q bottom left + // inside diamond; p top left + TestComputeCorrection(transform, 3, 4, -1, 2, -2, 4); // q top right + TestComputeCorrection(transform, -3, 4, -1, 2, -2, -2); // q top left + TestComputeCorrection(transform, 3, -4, -1, 2, 6, 4); // q bottom right + TestComputeCorrection(transform, -3, -4, -1, 2, 6, -2); // q bottom left + // inside diamond; p bottom right + TestComputeCorrection(transform, 3, 4, 1, -2, 6, -2); // q top right + TestComputeCorrection(transform, -3, 4, 1, -2, 6, 4); // q top left + TestComputeCorrection(transform, 3, -4, 1, -2, -2, -2); // q bottom right + TestComputeCorrection(transform, -3, -4, 1, -2, -2, 4); // q bottom left + // inside diamond; p bottom left + TestComputeCorrection(transform, 3, 4, -1, -2, 4, 6); // q top right + TestComputeCorrection(transform, -3, 4, -1, -2, -2, 6); // q top left + TestComputeCorrection(transform, 3, -4, -1, -2, 4, -2); // q bottom right + TestComputeCorrection(transform, -3, -4, -1, -2, -2, -2); // q bottom left + // outside diamond; p top right + TestComputeCorrection(transform, 1, 2, 5, 4, -2, -4); // q top right + TestComputeCorrection(transform, -1, 2, 5, 4, -7, -4); // q top left + TestComputeCorrection(transform, 1, -2, 5, 4, -2, -7); // q bottom right + TestComputeCorrection(transform, -1, -2, 5, 4, -7, -7); // q bottom left + // outside diamond; p top left + TestComputeCorrection(transform, 1, 2, -5, 4, -4, -7); // q top right + TestComputeCorrection(transform, -1, 2, -5, 4, -4, -2); // q top left + TestComputeCorrection(transform, 1, -2, -5, 4, -7, -7); // q bottom right + TestComputeCorrection(transform, -1, -2, -5, 4, -7, -2); // q bottom left + // outside diamond; p bottom right + TestComputeCorrection(transform, 1, 2, 5, -4, -7, -2); // q top right + TestComputeCorrection(transform, -1, 2, 5, -4, -7, -7); // q top left + TestComputeCorrection(transform, 1, -2, 5, -4, -4, -2); // q bottom right + TestComputeCorrection(transform, -1, -2, 5, -4, -4, -7); // q bottom left + // outside diamond; p bottom left + TestComputeCorrection(transform, 1, 2, -5, -4, -7, -7); // q top right + TestComputeCorrection(transform, -1, 2, -5, -4, -2, -7); // q top left + TestComputeCorrection(transform, 1, -2, -5, -4, -7, -4); // q bottom right + TestComputeCorrection(transform, -1, -2, -5, -4, -2, -4); // q bottom left + + TestComputeCorrection(transform, -1, -2, 7, 7, -5, -6); + TestComputeCorrection(transform, 0, 0, 7, 7, 7, 7); + TestComputeCorrection(transform, -1, -2, 0, -2, 0, 1); +} + +TEST_F(PredictionSchemeNormalOctahedronCanonicalizedTransformTest, Interface) { + const Transform transform(15); + ASSERT_EQ(transform.max_quantized_value(), 15); + ASSERT_EQ(transform.center_value(), 7); + ASSERT_EQ(transform.quantization_bits(), 4); +} + +} // namespace diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h new file mode 100644 index 0000000000..d3705c8ade --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h @@ -0,0 +1,115 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_DECODING_TRANSFORM_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_DECODING_TRANSFORM_H_ + +#include + +#include "draco/compression/attributes/normal_compression_utils.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h" +#include "draco/core/decoder_buffer.h" +#include "draco/core/macros.h" +#include "draco/core/vector_d.h" +#include "draco/draco_features.h" + +namespace draco { + +// Class for converting correction values transformed by the octahedral normal +// transform back to the original values. See the corresponding encoder for more +// details. +template +class PredictionSchemeNormalOctahedronDecodingTransform + : public PredictionSchemeNormalOctahedronTransformBase { + public: + typedef VectorD Point2; + typedef DataTypeT CorrType; + typedef DataTypeT DataType; + + PredictionSchemeNormalOctahedronDecodingTransform() {} + + // Dummy function to fulfill concept. + void Init(int num_components) {} + bool DecodeTransformData(DecoderBuffer *buffer) { + DataTypeT max_quantized_value, center_value; + if (!buffer->Decode(&max_quantized_value)) { + return false; + } + if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) { + if (!buffer->Decode(¢er_value)) { + return false; + } + } + (void)center_value; + return this->set_max_quantized_value(max_quantized_value); + } + + inline void ComputeOriginalValue(const DataType *pred_vals, + const CorrType *corr_vals, + DataType *out_orig_vals) const { + DRACO_DCHECK_LE(pred_vals[0], 2 * this->center_value()); + DRACO_DCHECK_LE(pred_vals[1], 2 * this->center_value()); + DRACO_DCHECK_LE(corr_vals[0], 2 * this->center_value()); + DRACO_DCHECK_LE(corr_vals[1], 2 * this->center_value()); + + DRACO_DCHECK_LE(0, pred_vals[0]); + DRACO_DCHECK_LE(0, pred_vals[1]); + DRACO_DCHECK_LE(0, corr_vals[0]); + DRACO_DCHECK_LE(0, corr_vals[1]); + + const Point2 pred = Point2(pred_vals[0], pred_vals[1]); + const Point2 corr = Point2(corr_vals[0], corr_vals[1]); + const Point2 orig = ComputeOriginalValue(pred, corr); + + out_orig_vals[0] = orig[0]; + out_orig_vals[1] = orig[1]; + } + + private: + Point2 ComputeOriginalValue(Point2 pred, const Point2 &corr) const { + const Point2 t(this->center_value(), this->center_value()); + typedef typename std::make_unsigned::type UnsignedDataTypeT; + typedef VectorD Point2u; + + // Perform the addition in unsigned type to avoid signed integer overflow. + // Note that the result will be the same (for non-overflowing values). + pred = Point2(Point2u(pred) - Point2u(t)); + + const bool pred_is_in_diamond = this->IsInDiamond(pred[0], pred[1]); + if (!pred_is_in_diamond) { + this->InvertDiamond(&pred[0], &pred[1]); + } + + // Perform the addition in unsigned type to avoid signed integer overflow. + // Note that the result will be the same (for non-overflowing values). + Point2 orig(Point2u(pred) + Point2u(corr)); + + orig[0] = this->ModMax(orig[0]); + orig[1] = this->ModMax(orig[1]); + if (!pred_is_in_diamond) { + this->InvertDiamond(&orig[0], &orig[1]); + } + + // Perform the addition in unsigned type to avoid signed integer overflow. + // Note that the result will be the same (for non-overflowing values). + orig = Point2(Point2u(orig) + Point2u(t)); + return orig; + } +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_DECODING_TRANSFORM_H_ +#endif diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h new file mode 100644 index 0000000000..4abfef6690 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h @@ -0,0 +1,105 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_ENCODING_TRANSFORM_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_ENCODING_TRANSFORM_H_ + +#include + +#include "draco/compression/attributes/normal_compression_utils.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h" +#include "draco/core/encoder_buffer.h" +#include "draco/core/macros.h" +#include "draco/core/vector_d.h" + +namespace draco { + +// The transform works on octahedral coordinates for normals. The square is +// subdivided into four inner triangles (diamond) and four outer triangles. The +// inner triangles are associated with the upper part of the octahedron and the +// outer triangles are associated with the lower part. +// Given a prediction value P and the actual value Q that should be encoded, +// this transform first checks if P is outside the diamond. If so, the outer +// triangles are flipped towards the inside and vice versa. The actual +// correction value is then based on the mapped P and Q values. This tends to +// result in shorter correction vectors. +// This is possible since the P value is also known by the decoder, see also +// ComputeCorrection and ComputeOriginalValue functions. +// Note that the tile is not periodic, which implies that the outer edges can +// not be identified, which requires us to use an odd number of values on each +// axis. +// DataTypeT is expected to be some integral type. +// +template +class PredictionSchemeNormalOctahedronEncodingTransform + : public PredictionSchemeNormalOctahedronTransformBase { + public: + typedef PredictionSchemeNormalOctahedronTransformBase Base; + typedef VectorD Point2; + typedef DataTypeT CorrType; + typedef DataTypeT DataType; + + // We expect the mod value to be of the form 2^b-1. + explicit PredictionSchemeNormalOctahedronEncodingTransform( + DataType max_quantized_value) + : Base(max_quantized_value) {} + + void Init(const DataTypeT *orig_data, int size, int num_components) {} + + bool EncodeTransformData(EncoderBuffer *buffer) { + buffer->Encode(this->max_quantized_value()); + return true; + } + + inline void ComputeCorrection(const DataType *orig_vals, + const DataType *pred_vals, + CorrType *out_corr_vals) const { + DRACO_DCHECK_LE(pred_vals[0], this->center_value() * 2); + DRACO_DCHECK_LE(pred_vals[1], this->center_value() * 2); + DRACO_DCHECK_LE(orig_vals[0], this->center_value() * 2); + DRACO_DCHECK_LE(orig_vals[1], this->center_value() * 2); + DRACO_DCHECK_LE(0, pred_vals[0]); + DRACO_DCHECK_LE(0, pred_vals[1]); + DRACO_DCHECK_LE(0, orig_vals[0]); + DRACO_DCHECK_LE(0, orig_vals[1]); + + const Point2 orig = Point2(orig_vals[0], orig_vals[1]); + const Point2 pred = Point2(pred_vals[0], pred_vals[1]); + const Point2 corr = ComputeCorrection(orig, pred); + + out_corr_vals[0] = corr[0]; + out_corr_vals[1] = corr[1]; + } + + private: + Point2 ComputeCorrection(Point2 orig, Point2 pred) const { + const Point2 t(this->center_value(), this->center_value()); + orig = orig - t; + pred = pred - t; + + if (!this->IsInDiamond(pred[0], pred[1])) { + this->InvertDiamond(&orig[0], &orig[1]); + this->InvertDiamond(&pred[0], &pred[1]); + } + + Point2 corr = orig - pred; + corr[0] = this->MakePositive(corr[0]); + corr[1] = this->MakePositive(corr[1]); + return corr; + } +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_ENCODING_TRANSFORM_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h new file mode 100644 index 0000000000..c9dd7d67bf --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h @@ -0,0 +1,90 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_TRANSFORM_BASE_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_TRANSFORM_BASE_H_ + +#include + +#include "draco/compression/attributes/normal_compression_utils.h" +#include "draco/compression/config/compression_shared.h" +#include "draco/core/bit_utils.h" +#include "draco/core/macros.h" +#include "draco/core/vector_d.h" + +namespace draco { + +// Base class containing shared functionality used by both encoding and decoding +// octahedral normal prediction scheme transforms. See the encoding transform +// for more details about the method. +template +class PredictionSchemeNormalOctahedronTransformBase { + public: + typedef VectorD Point2; + typedef DataTypeT DataType; + + PredictionSchemeNormalOctahedronTransformBase() {} + // We expect the mod value to be of the form 2^b-1. + explicit PredictionSchemeNormalOctahedronTransformBase( + DataType max_quantized_value) { + this->set_max_quantized_value(max_quantized_value); + } + + static constexpr PredictionSchemeTransformType GetType() { + return PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON; + } + + // We can return true as we keep correction values positive. + bool AreCorrectionsPositive() const { return true; } + + inline DataTypeT max_quantized_value() const { + return octahedron_tool_box_.max_quantized_value(); + } + inline DataTypeT center_value() const { + return octahedron_tool_box_.center_value(); + } + inline int32_t quantization_bits() const { + return octahedron_tool_box_.quantization_bits(); + } + + protected: + inline bool set_max_quantized_value(DataTypeT max_quantized_value) { + if (max_quantized_value % 2 == 0) { + return false; + } + int q = MostSignificantBit(max_quantized_value) + 1; + return octahedron_tool_box_.SetQuantizationBits(q); + } + + bool IsInDiamond(DataTypeT s, DataTypeT t) const { + return octahedron_tool_box_.IsInDiamond(s, t); + } + void InvertDiamond(DataTypeT *s, DataTypeT *t) const { + return octahedron_tool_box_.InvertDiamond(s, t); + } + + int32_t ModMax(int32_t x) const { return octahedron_tool_box_.ModMax(x); } + + // For correction values. + int32_t MakePositive(int32_t x) const { + return octahedron_tool_box_.MakePositive(x); + } + + private: + OctahedronToolBox octahedron_tool_box_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_NORMAL_OCTAHEDRON_TRANSFORM_BASE_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_test.cc b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_test.cc new file mode 100644 index 0000000000..1403973c48 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_test.cc @@ -0,0 +1,71 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h" +#include "draco/core/draco_test_base.h" + +namespace { + +class PredictionSchemeNormalOctahedronTransformTest : public ::testing::Test { + protected: + typedef draco::PredictionSchemeNormalOctahedronEncodingTransform + Transform; + typedef Transform::Point2 Point2; + + void TestComputeCorrection(const Transform &transform, const int32_t ox, + const int32_t oy, const int32_t px, + const int32_t py, const int32_t cx, + const int32_t cy) { + const int32_t o[2] = {ox + 7, oy + 7}; + const int32_t p[2] = {px + 7, py + 7}; + int32_t corr[2] = {500, 500}; + transform.ComputeCorrection(o, p, corr); + ASSERT_EQ(corr[0], (cx + 15) % 15); + ASSERT_EQ(corr[1], (cy + 15) % 15); + } +}; + +TEST_F(PredictionSchemeNormalOctahedronTransformTest, Init) { + const Transform transform(15); + ASSERT_TRUE(transform.AreCorrectionsPositive()); +} + +TEST_F(PredictionSchemeNormalOctahedronTransformTest, ComputeCorrections) { + const Transform transform(15); + // checks inside diamond + TestComputeCorrection(transform, 0, 0, 0, 0, 0, 0); + TestComputeCorrection(transform, 1, 1, 1, 1, 0, 0); + TestComputeCorrection(transform, 3, 4, 1, 1, 2, 3); + TestComputeCorrection(transform, -1, -1, -1, -1, 0, 0); + TestComputeCorrection(transform, -3, -4, -1, -1, -2, -3); + // checks outside diamond + TestComputeCorrection(transform, 4, 4, 4, 4, 0, 0); + TestComputeCorrection(transform, 5, 6, 4, 4, -2, -1); + TestComputeCorrection(transform, 3, 2, 4, 4, 2, 1); + // checks on outer edges + TestComputeCorrection(transform, 7, 7, 4, 4, -3, -3); + TestComputeCorrection(transform, 6, 7, 4, 4, -3, -2); + TestComputeCorrection(transform, -6, 7, 4, 4, -3, -2); + TestComputeCorrection(transform, 7, 6, 4, 4, -2, -3); + TestComputeCorrection(transform, 7, -6, 4, 4, -2, -3); +} + +TEST_F(PredictionSchemeNormalOctahedronTransformTest, Interface) { + const Transform transform(15); + ASSERT_EQ(transform.max_quantized_value(), 15); + ASSERT_EQ(transform.center_value(), 7); + ASSERT_EQ(transform.quantization_bits(), 4); +} + +} // namespace diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h new file mode 100644 index 0000000000..e100c738a6 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h @@ -0,0 +1,88 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_DECODING_TRANSFORM_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_DECODING_TRANSFORM_H_ + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h" +#include "draco/core/decoder_buffer.h" + +namespace draco { + +// PredictionSchemeWrapDecodingTransform unwraps values encoded with the +// PredictionSchemeWrapEncodingTransform. +// See prediction_scheme_wrap_transform_base.h for more details about the +// method. +template +class PredictionSchemeWrapDecodingTransform + : public PredictionSchemeWrapTransformBase { + public: + typedef CorrTypeT CorrType; + PredictionSchemeWrapDecodingTransform() {} + + // Computes the original value from the input predicted value and the decoded + // corrections. Values out of the bounds of the input values are unwrapped. + inline void ComputeOriginalValue(const DataTypeT *predicted_vals, + const CorrTypeT *corr_vals, + DataTypeT *out_original_vals) const { + // For now we assume both |DataTypeT| and |CorrTypeT| are equal. + static_assert(std::is_same::value, + "Predictions and corrections must have the same type."); + + // The only valid implementation right now is for int32_t. + static_assert(std::is_same::value, + "Only int32_t is supported for predicted values."); + + predicted_vals = this->ClampPredictedValue(predicted_vals); + + // Perform the wrapping using unsigned coordinates to avoid potential signed + // integer overflows caused by malformed input. + const uint32_t *const uint_predicted_vals = + reinterpret_cast(predicted_vals); + const uint32_t *const uint_corr_vals = + reinterpret_cast(corr_vals); + for (int i = 0; i < this->num_components(); ++i) { + out_original_vals[i] = + static_cast(uint_predicted_vals[i] + uint_corr_vals[i]); + if (out_original_vals[i] > this->max_value()) { + out_original_vals[i] -= this->max_dif(); + } else if (out_original_vals[i] < this->min_value()) { + out_original_vals[i] += this->max_dif(); + } + } + } + + bool DecodeTransformData(DecoderBuffer *buffer) { + DataTypeT min_value, max_value; + if (!buffer->Decode(&min_value)) { + return false; + } + if (!buffer->Decode(&max_value)) { + return false; + } + if (min_value > max_value) { + return false; + } + this->set_min_value(min_value); + this->set_max_value(max_value); + if (!this->InitCorrectionBounds()) { + return false; + } + return true; + } +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_DECODING_TRANSFORM_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h new file mode 100644 index 0000000000..1f5e8b1358 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h @@ -0,0 +1,81 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_ENCODING_TRANSFORM_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_ENCODING_TRANSFORM_H_ + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h" +#include "draco/core/encoder_buffer.h" + +namespace draco { + +// PredictionSchemeWrapEncodingTransform wraps input values using the wrapping +// scheme described in: prediction_scheme_wrap_transform_base.h . +template +class PredictionSchemeWrapEncodingTransform + : public PredictionSchemeWrapTransformBase { + public: + typedef CorrTypeT CorrType; + PredictionSchemeWrapEncodingTransform() {} + + void Init(const DataTypeT *orig_data, int size, int num_components) { + PredictionSchemeWrapTransformBase::Init(num_components); + // Go over the original values and compute the bounds. + if (size == 0) { + return; + } + DataTypeT min_value = orig_data[0]; + DataTypeT max_value = min_value; + for (int i = 1; i < size; ++i) { + if (orig_data[i] < min_value) { + min_value = orig_data[i]; + } else if (orig_data[i] > max_value) { + max_value = orig_data[i]; + } + } + this->set_min_value(min_value); + this->set_max_value(max_value); + this->InitCorrectionBounds(); + } + + // Computes the corrections based on the input original value and the + // predicted value. Out of bound correction values are wrapped around the max + // range of input values. + inline void ComputeCorrection(const DataTypeT *original_vals, + const DataTypeT *predicted_vals, + CorrTypeT *out_corr_vals) const { + for (int i = 0; i < this->num_components(); ++i) { + predicted_vals = this->ClampPredictedValue(predicted_vals); + out_corr_vals[i] = original_vals[i] - predicted_vals[i]; + // Wrap around if needed. + DataTypeT &corr_val = out_corr_vals[i]; + if (corr_val < this->min_correction()) { + corr_val += this->max_dif(); + } else if (corr_val > this->max_correction()) { + corr_val -= this->max_dif(); + } + } + } + + bool EncodeTransformData(EncoderBuffer *buffer) { + // Store the input value range as it is needed by the decoder. + buffer->Encode(this->min_value()); + buffer->Encode(this->max_value()); + return true; + } +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_ENCODING_TRANSFORM_H_ diff --git a/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h new file mode 100644 index 0000000000..bba3de09c3 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h @@ -0,0 +1,120 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_TRANSFORM_BASE_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_TRANSFORM_BASE_H_ + +#include +#include + +#include "draco/compression/config/compression_shared.h" +#include "draco/core/macros.h" + +namespace draco { + +// PredictionSchemeWrapTransform uses the min and max bounds of the original +// data to wrap stored correction values around these bounds centered at 0, +// i.e., when the range of the original values O is between and +// N = MAX-MIN, we can then store any correction X = O - P, as: +// X + N, if X < -N / 2 +// X - N, if X > N / 2 +// X otherwise +// To unwrap this value, the decoder then simply checks whether the final +// corrected value F = P + X is out of the bounds of the input values. +// All out of bounds values are unwrapped using +// F + N, if F < MIN +// F - N, if F > MAX +// This wrapping can reduce the number of unique values, which translates to a +// better entropy of the stored values and better compression rates. +template +class PredictionSchemeWrapTransformBase { + public: + PredictionSchemeWrapTransformBase() + : num_components_(0), + min_value_(0), + max_value_(0), + max_dif_(0), + max_correction_(0), + min_correction_(0) {} + + static constexpr PredictionSchemeTransformType GetType() { + return PREDICTION_TRANSFORM_WRAP; + } + + void Init(int num_components) { + num_components_ = num_components; + clamped_value_.resize(num_components); + } + + bool AreCorrectionsPositive() const { return false; } + + inline const DataTypeT *ClampPredictedValue( + const DataTypeT *predicted_val) const { + for (int i = 0; i < this->num_components(); ++i) { + if (predicted_val[i] > max_value_) { + clamped_value_[i] = max_value_; + } else if (predicted_val[i] < min_value_) { + clamped_value_[i] = min_value_; + } else { + clamped_value_[i] = predicted_val[i]; + } + } + return clamped_value_.data(); + } + + // TODO(b/199760123): Consider refactoring to avoid this dummy. + int quantization_bits() const { + DRACO_DCHECK(false); + return -1; + } + + protected: + bool InitCorrectionBounds() { + const int64_t dif = + static_cast(max_value_) - static_cast(min_value_); + if (dif < 0 || dif >= std::numeric_limits::max()) { + return false; + } + max_dif_ = 1 + static_cast(dif); + max_correction_ = max_dif_ / 2; + min_correction_ = -max_correction_; + if ((max_dif_ & 1) == 0) { + max_correction_ -= 1; + } + return true; + } + + inline int num_components() const { return num_components_; } + inline DataTypeT min_value() const { return min_value_; } + inline void set_min_value(const DataTypeT &v) { min_value_ = v; } + inline DataTypeT max_value() const { return max_value_; } + inline void set_max_value(const DataTypeT &v) { max_value_ = v; } + inline DataTypeT max_dif() const { return max_dif_; } + inline DataTypeT min_correction() const { return min_correction_; } + inline DataTypeT max_correction() const { return max_correction_; } + + private: + int num_components_; + DataTypeT min_value_; + DataTypeT max_value_; + DataTypeT max_dif_; + DataTypeT max_correction_; + DataTypeT min_correction_; + // This is in fact just a tmp variable to avoid reallocation. + mutable std::vector clamped_value_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_PREDICTION_SCHEME_WRAP_TRANSFORM_BASE_H_ diff --git a/third-party/draco/src/draco/compression/attributes/sequential_attribute_decoder.cc b/third-party/draco/src/draco/compression/attributes/sequential_attribute_decoder.cc new file mode 100644 index 0000000000..b4ba24f2d3 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_attribute_decoder.cc @@ -0,0 +1,118 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/sequential_attribute_decoder.h" + +namespace draco { + +SequentialAttributeDecoder::SequentialAttributeDecoder() + : decoder_(nullptr), attribute_(nullptr), attribute_id_(-1) {} + +bool SequentialAttributeDecoder::Init(PointCloudDecoder *decoder, + int attribute_id) { + decoder_ = decoder; + attribute_ = decoder->point_cloud()->attribute(attribute_id); + attribute_id_ = attribute_id; + return true; +} + +bool SequentialAttributeDecoder::InitializeStandalone( + PointAttribute *attribute) { + attribute_ = attribute; + attribute_id_ = -1; + return true; +} + +bool SequentialAttributeDecoder::DecodePortableAttribute( + const std::vector &point_ids, DecoderBuffer *in_buffer) { + if (attribute_->num_components() <= 0 || + !attribute_->Reset(point_ids.size())) { + return false; + } + if (!DecodeValues(point_ids, in_buffer)) { + return false; + } + return true; +} + +bool SequentialAttributeDecoder::DecodeDataNeededByPortableTransform( + const std::vector &point_ids, DecoderBuffer *in_buffer) { + // Default implementation does not apply any transform. + return true; +} + +bool SequentialAttributeDecoder::TransformAttributeToOriginalFormat( + const std::vector &point_ids) { + // Default implementation does not apply any transform. + return true; +} + +const PointAttribute *SequentialAttributeDecoder::GetPortableAttribute() { + // If needed, copy point to attribute value index mapping from the final + // attribute to the portable attribute. + if (!attribute_->is_mapping_identity() && portable_attribute_ && + portable_attribute_->is_mapping_identity()) { + portable_attribute_->SetExplicitMapping(attribute_->indices_map_size()); + for (PointIndex i(0); + i < static_cast(attribute_->indices_map_size()); ++i) { + portable_attribute_->SetPointMapEntry(i, attribute_->mapped_index(i)); + } + } + return portable_attribute_.get(); +} + +bool SequentialAttributeDecoder::InitPredictionScheme( + PredictionSchemeInterface *ps) { + for (int i = 0; i < ps->GetNumParentAttributes(); ++i) { + const int att_id = decoder_->point_cloud()->GetNamedAttributeId( + ps->GetParentAttributeType(i)); + if (att_id == -1) { + return false; // Requested attribute does not exist. + } +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + if (decoder_->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) { + if (!ps->SetParentAttribute(decoder_->point_cloud()->attribute(att_id))) { + return false; + } + } else +#endif + { + const PointAttribute *const pa = decoder_->GetPortableAttribute(att_id); + if (pa == nullptr || !ps->SetParentAttribute(pa)) { + return false; + } + } + } + return true; +} + +bool SequentialAttributeDecoder::DecodeValues( + const std::vector &point_ids, DecoderBuffer *in_buffer) { + const int32_t num_values = static_cast(point_ids.size()); + const int entry_size = static_cast(attribute_->byte_stride()); + std::unique_ptr value_data_ptr(new uint8_t[entry_size]); + uint8_t *const value_data = value_data_ptr.get(); + int out_byte_pos = 0; + // Decode raw attribute values in their original format. + for (int i = 0; i < num_values; ++i) { + if (!in_buffer->Decode(value_data, entry_size)) { + return false; + } + attribute_->buffer()->Write(out_byte_pos, value_data, entry_size); + out_byte_pos += entry_size; + } + return true; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/sequential_attribute_decoder.h b/third-party/draco/src/draco/compression/attributes/sequential_attribute_decoder.h new file mode 100644 index 0000000000..d48119465a --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_attribute_decoder.h @@ -0,0 +1,86 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_DECODER_H_ + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h" +#include "draco/compression/point_cloud/point_cloud_decoder.h" +#include "draco/draco_features.h" + +namespace draco { + +// A base class for decoding attribute values encoded by the +// SequentialAttributeEncoder. +class SequentialAttributeDecoder { + public: + SequentialAttributeDecoder(); + virtual ~SequentialAttributeDecoder() = default; + + virtual bool Init(PointCloudDecoder *decoder, int attribute_id); + + // Initialization for a specific attribute. This can be used mostly for + // standalone decoding of an attribute without an PointCloudDecoder. + virtual bool InitializeStandalone(PointAttribute *attribute); + + // Performs lossless decoding of the portable attribute data. + virtual bool DecodePortableAttribute(const std::vector &point_ids, + DecoderBuffer *in_buffer); + + // Decodes any data needed to revert portable transform of the decoded + // attribute. + virtual bool DecodeDataNeededByPortableTransform( + const std::vector &point_ids, DecoderBuffer *in_buffer); + + // Reverts transformation performed by encoder in + // SequentialAttributeEncoder::TransformAttributeToPortableFormat() method. + virtual bool TransformAttributeToOriginalFormat( + const std::vector &point_ids); + + const PointAttribute *GetPortableAttribute(); + + const PointAttribute *attribute() const { return attribute_; } + PointAttribute *attribute() { return attribute_; } + int attribute_id() const { return attribute_id_; } + PointCloudDecoder *decoder() const { return decoder_; } + + protected: + // Should be used to initialize newly created prediction scheme. + // Returns false when the initialization failed (in which case the scheme + // cannot be used). + virtual bool InitPredictionScheme(PredictionSchemeInterface *ps); + + // The actual implementation of the attribute decoding. Should be overridden + // for specialized decoders. + virtual bool DecodeValues(const std::vector &point_ids, + DecoderBuffer *in_buffer); + + void SetPortableAttribute(std::unique_ptr att) { + portable_attribute_ = std::move(att); + } + + PointAttribute *portable_attribute() { return portable_attribute_.get(); } + + private: + PointCloudDecoder *decoder_; + PointAttribute *attribute_; + int attribute_id_; + + // Storage for decoded portable attribute (after lossless decoding). + std::unique_ptr portable_attribute_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.cc b/third-party/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.cc new file mode 100644 index 0000000000..0e5e26bcaa --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.cc @@ -0,0 +1,149 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/sequential_attribute_decoders_controller.h" +#ifdef DRACO_NORMAL_ENCODING_SUPPORTED +#include "draco/compression/attributes/sequential_normal_attribute_decoder.h" +#endif +#include "draco/compression/attributes/sequential_quantization_attribute_decoder.h" +#include "draco/compression/config/compression_shared.h" + +namespace draco { + +SequentialAttributeDecodersController::SequentialAttributeDecodersController( + std::unique_ptr sequencer) + : sequencer_(std::move(sequencer)) {} + +bool SequentialAttributeDecodersController::DecodeAttributesDecoderData( + DecoderBuffer *buffer) { + if (!AttributesDecoder::DecodeAttributesDecoderData(buffer)) { + return false; + } + // Decode unique ids of all sequential encoders and create them. + const int32_t num_attributes = GetNumAttributes(); + sequential_decoders_.resize(num_attributes); + for (int i = 0; i < num_attributes; ++i) { + uint8_t decoder_type; + if (!buffer->Decode(&decoder_type)) { + return false; + } + // Create the decoder from the id. + sequential_decoders_[i] = CreateSequentialDecoder(decoder_type); + if (!sequential_decoders_[i]) { + return false; + } + if (!sequential_decoders_[i]->Init(GetDecoder(), GetAttributeId(i))) { + return false; + } + } + return true; +} + +bool SequentialAttributeDecodersController::DecodeAttributes( + DecoderBuffer *buffer) { + if (!sequencer_ || !sequencer_->GenerateSequence(&point_ids_)) { + return false; + } + // Initialize point to attribute value mapping for all decoded attributes. + const int32_t num_attributes = GetNumAttributes(); + for (int i = 0; i < num_attributes; ++i) { + PointAttribute *const pa = + GetDecoder()->point_cloud()->attribute(GetAttributeId(i)); + if (!sequencer_->UpdatePointToAttributeIndexMapping(pa)) { + return false; + } + } + return AttributesDecoder::DecodeAttributes(buffer); +} + +bool SequentialAttributeDecodersController::DecodePortableAttributes( + DecoderBuffer *in_buffer) { + const int32_t num_attributes = GetNumAttributes(); + for (int i = 0; i < num_attributes; ++i) { + if (!sequential_decoders_[i]->DecodePortableAttribute(point_ids_, + in_buffer)) { + return false; + } + } + return true; +} + +bool SequentialAttributeDecodersController:: + DecodeDataNeededByPortableTransforms(DecoderBuffer *in_buffer) { + const int32_t num_attributes = GetNumAttributes(); + for (int i = 0; i < num_attributes; ++i) { + if (!sequential_decoders_[i]->DecodeDataNeededByPortableTransform( + point_ids_, in_buffer)) { + return false; + } + } + return true; +} + +bool SequentialAttributeDecodersController:: + TransformAttributesToOriginalFormat() { + const int32_t num_attributes = GetNumAttributes(); + for (int i = 0; i < num_attributes; ++i) { + // Check whether the attribute transform should be skipped. + if (GetDecoder()->options()) { + const PointAttribute *const attribute = + sequential_decoders_[i]->attribute(); + const PointAttribute *const portable_attribute = + sequential_decoders_[i]->GetPortableAttribute(); + if (portable_attribute && + GetDecoder()->options()->GetAttributeBool( + attribute->attribute_type(), "skip_attribute_transform", false)) { + // Attribute transform should not be performed. In this case, we replace + // the output geometry attribute with the portable attribute. + // TODO(ostava): We can potentially avoid this copy by introducing a new + // mechanism that would allow to use the final attributes as portable + // attributes for predictors that may need them. + sequential_decoders_[i]->attribute()->CopyFrom(*portable_attribute); + continue; + } + } + if (!sequential_decoders_[i]->TransformAttributeToOriginalFormat( + point_ids_)) { + return false; + } + } + return true; +} + +std::unique_ptr +SequentialAttributeDecodersController::CreateSequentialDecoder( + uint8_t decoder_type) { + switch (decoder_type) { + case SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC: + return std::unique_ptr( + new SequentialAttributeDecoder()); + case SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER: + return std::unique_ptr( + new SequentialIntegerAttributeDecoder()); + case SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION: + return std::unique_ptr( + new SequentialQuantizationAttributeDecoder()); +#ifdef DRACO_NORMAL_ENCODING_SUPPORTED + case SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS: + return std::unique_ptr( + new SequentialNormalAttributeDecoder()); +#endif + default: + break; + } + // Unknown or unsupported decoder type. + return nullptr; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.h b/third-party/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.h new file mode 100644 index 0000000000..abc1f36852 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_attribute_decoders_controller.h @@ -0,0 +1,61 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_DECODERS_CONTROLLER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_DECODERS_CONTROLLER_H_ + +#include "draco/compression/attributes/attributes_decoder.h" +#include "draco/compression/attributes/points_sequencer.h" +#include "draco/compression/attributes/sequential_attribute_decoder.h" + +namespace draco { + +// A basic implementation of an attribute decoder that decodes data encoded by +// the SequentialAttributeEncodersController class. The +// SequentialAttributeDecodersController creates a single +// AttributeIndexedValuesDecoder for each of the decoded attribute, where the +// type of the values decoder is determined by the unique identifier that was +// encoded by the encoder. +class SequentialAttributeDecodersController : public AttributesDecoder { + public: + explicit SequentialAttributeDecodersController( + std::unique_ptr sequencer); + + bool DecodeAttributesDecoderData(DecoderBuffer *buffer) override; + bool DecodeAttributes(DecoderBuffer *buffer) override; + const PointAttribute *GetPortableAttribute( + int32_t point_attribute_id) override { + const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id); + if (loc_id < 0) { + return nullptr; + } + return sequential_decoders_[loc_id]->GetPortableAttribute(); + } + + protected: + bool DecodePortableAttributes(DecoderBuffer *in_buffer) override; + bool DecodeDataNeededByPortableTransforms(DecoderBuffer *in_buffer) override; + bool TransformAttributesToOriginalFormat() override; + virtual std::unique_ptr CreateSequentialDecoder( + uint8_t decoder_type); + + private: + std::vector> sequential_decoders_; + std::vector point_ids_; + std::unique_ptr sequencer_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_DECODERS_CONTROLLER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/sequential_attribute_encoder.cc b/third-party/draco/src/draco/compression/attributes/sequential_attribute_encoder.cc new file mode 100644 index 0000000000..6bde3eeb3b --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_attribute_encoder.cc @@ -0,0 +1,108 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/sequential_attribute_encoder.h" + +namespace draco { + +SequentialAttributeEncoder::SequentialAttributeEncoder() + : encoder_(nullptr), + attribute_(nullptr), + attribute_id_(-1), + is_parent_encoder_(false) {} + +bool SequentialAttributeEncoder::Init(PointCloudEncoder *encoder, + int attribute_id) { + encoder_ = encoder; + attribute_ = encoder_->point_cloud()->attribute(attribute_id); + attribute_id_ = attribute_id; + return true; +} + +bool SequentialAttributeEncoder::InitializeStandalone( + PointAttribute *attribute) { + attribute_ = attribute; + attribute_id_ = -1; + return true; +} + +bool SequentialAttributeEncoder::TransformAttributeToPortableFormat( + const std::vector &point_ids) { + // Default implementation doesn't transform the input data. + return true; +} + +bool SequentialAttributeEncoder::EncodePortableAttribute( + const std::vector &point_ids, EncoderBuffer *out_buffer) { + // Lossless encoding of the input values. + if (!EncodeValues(point_ids, out_buffer)) { + return false; + } + return true; +} + +bool SequentialAttributeEncoder::EncodeDataNeededByPortableTransform( + EncoderBuffer *out_buffer) { + // Default implementation doesn't transform the input data. + return true; +} + +bool SequentialAttributeEncoder::EncodeValues( + const std::vector &point_ids, EncoderBuffer *out_buffer) { + const int entry_size = static_cast(attribute_->byte_stride()); + const std::unique_ptr value_data_ptr(new uint8_t[entry_size]); + uint8_t *const value_data = value_data_ptr.get(); + // Encode all attribute values in their native raw format. + for (uint32_t i = 0; i < point_ids.size(); ++i) { + const AttributeValueIndex entry_id = attribute_->mapped_index(point_ids[i]); + attribute_->GetValue(entry_id, value_data); + out_buffer->Encode(value_data, entry_size); + } + return true; +} + +void SequentialAttributeEncoder::MarkParentAttribute() { + is_parent_encoder_ = true; +} + +bool SequentialAttributeEncoder::InitPredictionScheme( + PredictionSchemeInterface *ps) { + for (int i = 0; i < ps->GetNumParentAttributes(); ++i) { + const int att_id = encoder_->point_cloud()->GetNamedAttributeId( + ps->GetParentAttributeType(i)); + if (att_id == -1) { + return false; // Requested attribute does not exist. + } + parent_attributes_.push_back(att_id); + encoder_->MarkParentAttribute(att_id); + } + return true; +} + +bool SequentialAttributeEncoder::SetPredictionSchemeParentAttributes( + PredictionSchemeInterface *ps) { + for (int i = 0; i < ps->GetNumParentAttributes(); ++i) { + const int att_id = encoder_->point_cloud()->GetNamedAttributeId( + ps->GetParentAttributeType(i)); + if (att_id == -1) { + return false; // Requested attribute does not exist. + } + if (!ps->SetParentAttribute(encoder_->GetPortableAttribute(att_id))) { + return false; + } + } + return true; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/sequential_attribute_encoder.h b/third-party/draco/src/draco/compression/attributes/sequential_attribute_encoder.h new file mode 100644 index 0000000000..00f62db895 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_attribute_encoder.h @@ -0,0 +1,134 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_ENCODER_H_ + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h" +#include "draco/compression/point_cloud/point_cloud_encoder.h" + +namespace draco { + +// A base class for encoding attribute values of a single attribute using a +// given sequence of point ids. The default implementation encodes all attribute +// values directly to the buffer but derived classes can perform any custom +// encoding (such as quantization) by overriding the EncodeValues() method. +class SequentialAttributeEncoder { + public: + SequentialAttributeEncoder(); + virtual ~SequentialAttributeEncoder() = default; + + // Method that can be used for custom initialization of an attribute encoder, + // such as creation of prediction schemes and initialization of attribute + // encoder dependencies. + // |encoder| is the parent PointCloudEncoder, + // |attribute_id| is the id of the attribute that is being encoded by this + // encoder. + // This method is automatically called by the PointCloudEncoder after all + // attribute encoders are created and it should not be called explicitly from + // other places. + virtual bool Init(PointCloudEncoder *encoder, int attribute_id); + + // Initialization for a specific attribute. This can be used mostly for + // standalone encoding of an attribute without an PointCloudEncoder. + virtual bool InitializeStandalone(PointAttribute *attribute); + + // Transforms attribute data into format that is going to be encoded + // losslessly. The transform itself can be lossy. + virtual bool TransformAttributeToPortableFormat( + const std::vector &point_ids); + + // Performs lossless encoding of the transformed attribute data. + virtual bool EncodePortableAttribute(const std::vector &point_ids, + EncoderBuffer *out_buffer); + + // Encodes any data related to the portable attribute transform. + virtual bool EncodeDataNeededByPortableTransform(EncoderBuffer *out_buffer); + + virtual bool IsLossyEncoder() const { return false; } + + int NumParentAttributes() const { + return static_cast(parent_attributes_.size()); + } + int GetParentAttributeId(int i) const { return parent_attributes_[i]; } + + const PointAttribute *GetPortableAttribute() const { + if (portable_attribute_ != nullptr) { + return portable_attribute_.get(); + } + return attribute(); + } + + // Called when this attribute encoder becomes a parent encoder of another + // encoder. + void MarkParentAttribute(); + + virtual uint8_t GetUniqueId() const { + return SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC; + } + + const PointAttribute *attribute() const { return attribute_; } + int attribute_id() const { return attribute_id_; } + PointCloudEncoder *encoder() const { return encoder_; } + + protected: + // Should be used to initialize newly created prediction scheme. + // Returns false when the initialization failed (in which case the scheme + // cannot be used). + virtual bool InitPredictionScheme(PredictionSchemeInterface *ps); + + // Sets parent attributes for a given prediction scheme. Must be called + // after all prediction schemes are initialized, but before the prediction + // scheme is used. + virtual bool SetPredictionSchemeParentAttributes( + PredictionSchemeInterface *ps); + + // Encodes all attribute values in the specified order. Should be overridden + // for specialized encoders. + virtual bool EncodeValues(const std::vector &point_ids, + EncoderBuffer *out_buffer); + + bool is_parent_encoder() const { return is_parent_encoder_; } + + void SetPortableAttribute(std::unique_ptr att) { + portable_attribute_ = std::move(att); + } + + // Returns a mutable attribute that should be filled by derived encoders with + // the transformed version of the attribute data. To get a public const + // version, use the GetPortableAttribute() method. + PointAttribute *portable_attribute() { return portable_attribute_.get(); } + + private: + PointCloudEncoder *encoder_; + const PointAttribute *attribute_; + int attribute_id_; + + // List of attribute encoders that need to be encoded before this attribute. + // E.g. The parent attributes may be used to predict values used by this + // attribute encoder. + std::vector parent_attributes_; + + bool is_parent_encoder_; + + // Attribute that stores transformed data from the source attribute after it + // is processed through the ApplyTransform() method. Attribute data stored + // within this attribute is guaranteed to be encoded losslessly and it can be + // safely used for prediction of other attributes. + std::unique_ptr portable_attribute_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc b/third-party/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc new file mode 100644 index 0000000000..7d5d1eeff2 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.cc @@ -0,0 +1,159 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/sequential_attribute_encoders_controller.h" +#ifdef DRACO_NORMAL_ENCODING_SUPPORTED +#include "draco/compression/attributes/sequential_normal_attribute_encoder.h" +#endif +#include "draco/compression/attributes/sequential_quantization_attribute_encoder.h" +#include "draco/compression/point_cloud/point_cloud_encoder.h" + +namespace draco { + +SequentialAttributeEncodersController::SequentialAttributeEncodersController( + std::unique_ptr sequencer) + : sequencer_(std::move(sequencer)) {} + +SequentialAttributeEncodersController::SequentialAttributeEncodersController( + std::unique_ptr sequencer, int point_attrib_id) + : AttributesEncoder(point_attrib_id), sequencer_(std::move(sequencer)) {} + +bool SequentialAttributeEncodersController::Init(PointCloudEncoder *encoder, + const PointCloud *pc) { + if (!AttributesEncoder::Init(encoder, pc)) { + return false; + } + if (!CreateSequentialEncoders()) { + return false; + } + // Initialize all value encoders. + for (uint32_t i = 0; i < num_attributes(); ++i) { + const int32_t att_id = GetAttributeId(i); + if (!sequential_encoders_[i]->Init(encoder, att_id)) { + return false; + } + } + return true; +} + +bool SequentialAttributeEncodersController::EncodeAttributesEncoderData( + EncoderBuffer *out_buffer) { + if (!AttributesEncoder::EncodeAttributesEncoderData(out_buffer)) { + return false; + } + // Encode a unique id of every sequential encoder. + for (uint32_t i = 0; i < sequential_encoders_.size(); ++i) { + out_buffer->Encode(sequential_encoders_[i]->GetUniqueId()); + } + return true; +} + +bool SequentialAttributeEncodersController::EncodeAttributes( + EncoderBuffer *buffer) { + if (!sequencer_ || !sequencer_->GenerateSequence(&point_ids_)) { + return false; + } + return AttributesEncoder::EncodeAttributes(buffer); +} + +bool SequentialAttributeEncodersController:: + TransformAttributesToPortableFormat() { + for (uint32_t i = 0; i < sequential_encoders_.size(); ++i) { + if (!sequential_encoders_[i]->TransformAttributeToPortableFormat( + point_ids_)) { + return false; + } + } + return true; +} + +bool SequentialAttributeEncodersController::EncodePortableAttributes( + EncoderBuffer *out_buffer) { + for (uint32_t i = 0; i < sequential_encoders_.size(); ++i) { + if (!sequential_encoders_[i]->EncodePortableAttribute(point_ids_, + out_buffer)) { + return false; + } + } + return true; +} + +bool SequentialAttributeEncodersController:: + EncodeDataNeededByPortableTransforms(EncoderBuffer *out_buffer) { + for (uint32_t i = 0; i < sequential_encoders_.size(); ++i) { + if (!sequential_encoders_[i]->EncodeDataNeededByPortableTransform( + out_buffer)) { + return false; + } + } + return true; +} + +bool SequentialAttributeEncodersController::CreateSequentialEncoders() { + sequential_encoders_.resize(num_attributes()); + for (uint32_t i = 0; i < num_attributes(); ++i) { + sequential_encoders_[i] = CreateSequentialEncoder(i); + if (sequential_encoders_[i] == nullptr) { + return false; + } + if (i < sequential_encoder_marked_as_parent_.size()) { + if (sequential_encoder_marked_as_parent_[i]) { + sequential_encoders_[i]->MarkParentAttribute(); + } + } + } + return true; +} + +std::unique_ptr +SequentialAttributeEncodersController::CreateSequentialEncoder(int i) { + const int32_t att_id = GetAttributeId(i); + const PointAttribute *const att = encoder()->point_cloud()->attribute(att_id); + + switch (att->data_type()) { + case DT_UINT8: + case DT_INT8: + case DT_UINT16: + case DT_INT16: + case DT_UINT32: + case DT_INT32: + return std::unique_ptr( + new SequentialIntegerAttributeEncoder()); + case DT_FLOAT32: + if (encoder()->options()->GetAttributeInt(att_id, "quantization_bits", + -1) > 0) { +#ifdef DRACO_NORMAL_ENCODING_SUPPORTED + if (att->attribute_type() == GeometryAttribute::NORMAL) { + // We currently only support normals with float coordinates + // and must be quantized. + return std::unique_ptr( + new SequentialNormalAttributeEncoder()); + } else { +#endif + return std::unique_ptr( + new SequentialQuantizationAttributeEncoder()); +#ifdef DRACO_NORMAL_ENCODING_SUPPORTED + } +#endif + } + break; + default: + break; + } + // Return the default attribute encoder. + return std::unique_ptr( + new SequentialAttributeEncoder()); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.h b/third-party/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.h new file mode 100644 index 0000000000..13c2704ec0 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_attribute_encoders_controller.h @@ -0,0 +1,115 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_ENCODERS_CONTROLLER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_ENCODERS_CONTROLLER_H_ + +#include "draco/compression/attributes/attributes_encoder.h" +#include "draco/compression/attributes/points_sequencer.h" +#include "draco/compression/attributes/sequential_attribute_encoder.h" + +namespace draco { + +// A basic implementation of an attribute encoder that can be used to encode +// an arbitrary set of attributes. The encoder creates a sequential attribute +// encoder for each encoded attribute (see sequential_attribute_encoder.h) and +// then it encodes all attribute values in an order defined by a point sequence +// generated in the GeneratePointSequence() method. The default implementation +// generates a linear sequence of all points, but derived classes can generate +// any custom sequence. +class SequentialAttributeEncodersController : public AttributesEncoder { + public: + explicit SequentialAttributeEncodersController( + std::unique_ptr sequencer); + SequentialAttributeEncodersController( + std::unique_ptr sequencer, int point_attrib_id); + + bool Init(PointCloudEncoder *encoder, const PointCloud *pc) override; + bool EncodeAttributesEncoderData(EncoderBuffer *out_buffer) override; + bool EncodeAttributes(EncoderBuffer *buffer) override; + uint8_t GetUniqueId() const override { return BASIC_ATTRIBUTE_ENCODER; } + + int NumParentAttributes(int32_t point_attribute_id) const override { + const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id); + if (loc_id < 0) { + return 0; + } + return sequential_encoders_[loc_id]->NumParentAttributes(); + } + + int GetParentAttributeId(int32_t point_attribute_id, + int32_t parent_i) const override { + const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id); + if (loc_id < 0) { + return -1; + } + return sequential_encoders_[loc_id]->GetParentAttributeId(parent_i); + } + + bool MarkParentAttribute(int32_t point_attribute_id) override { + const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id); + if (loc_id < 0) { + return false; + } + // Mark the attribute encoder as parent (even when if it is not created + // yet). + if (sequential_encoder_marked_as_parent_.size() <= loc_id) { + sequential_encoder_marked_as_parent_.resize(loc_id + 1, false); + } + sequential_encoder_marked_as_parent_[loc_id] = true; + + if (sequential_encoders_.size() <= loc_id) { + return true; // Sequential encoders not generated yet. + } + sequential_encoders_[loc_id]->MarkParentAttribute(); + return true; + } + + const PointAttribute *GetPortableAttribute( + int32_t point_attribute_id) override { + const int32_t loc_id = GetLocalIdForPointAttribute(point_attribute_id); + if (loc_id < 0) { + return nullptr; + } + return sequential_encoders_[loc_id]->GetPortableAttribute(); + } + + protected: + bool TransformAttributesToPortableFormat() override; + bool EncodePortableAttributes(EncoderBuffer *out_buffer) override; + bool EncodeDataNeededByPortableTransforms(EncoderBuffer *out_buffer) override; + + // Creates all sequential encoders (one for each attribute associated with the + // encoder). + virtual bool CreateSequentialEncoders(); + + // Create a sequential encoder for a given attribute based on the attribute + // type + // and the provided encoder options. + virtual std::unique_ptr CreateSequentialEncoder( + int i); + + private: + std::vector> sequential_encoders_; + + // Flag for each sequential attribute encoder indicating whether it was marked + // as parent attribute or not. + std::vector sequential_encoder_marked_as_parent_; + std::vector point_ids_; + std::unique_ptr sequencer_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_ATTRIBUTE_ENCODERS_CONTROLLER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc b/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc new file mode 100644 index 0000000000..927a4a52f1 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.cc @@ -0,0 +1,247 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/sequential_integer_attribute_decoder.h" + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h" +#include "draco/compression/entropy/symbol_decoding.h" + +namespace draco { + +SequentialIntegerAttributeDecoder::SequentialIntegerAttributeDecoder() {} + +bool SequentialIntegerAttributeDecoder::Init(PointCloudDecoder *decoder, + int attribute_id) { + if (!SequentialAttributeDecoder::Init(decoder, attribute_id)) { + return false; + } + return true; +} + +bool SequentialIntegerAttributeDecoder::TransformAttributeToOriginalFormat( + const std::vector &point_ids) { +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + if (decoder() && + decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) { + return true; // Don't revert the transform here for older files. + } +#endif + return StoreValues(static_cast(point_ids.size())); +} + +bool SequentialIntegerAttributeDecoder::DecodeValues( + const std::vector &point_ids, DecoderBuffer *in_buffer) { + // Decode prediction scheme. + int8_t prediction_scheme_method; + if (!in_buffer->Decode(&prediction_scheme_method)) { + return false; + } + // Check that decoded prediction scheme method type is valid. + if (prediction_scheme_method < PREDICTION_NONE || + prediction_scheme_method >= NUM_PREDICTION_SCHEMES) { + return false; + } + if (prediction_scheme_method != PREDICTION_NONE) { + int8_t prediction_transform_type; + if (!in_buffer->Decode(&prediction_transform_type)) { + return false; + } + // Check that decoded prediction scheme transform type is valid. + if (prediction_transform_type < PREDICTION_TRANSFORM_NONE || + prediction_transform_type >= NUM_PREDICTION_SCHEME_TRANSFORM_TYPES) { + return false; + } + prediction_scheme_ = CreateIntPredictionScheme( + static_cast(prediction_scheme_method), + static_cast(prediction_transform_type)); + } + + if (prediction_scheme_) { + if (!InitPredictionScheme(prediction_scheme_.get())) { + return false; + } + } + + if (!DecodeIntegerValues(point_ids, in_buffer)) { + return false; + } + +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + const int32_t num_values = static_cast(point_ids.size()); + if (decoder() && + decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) { + // For older files, revert the transform right after we decode the data. + if (!StoreValues(num_values)) { + return false; + } + } +#endif + return true; +} + +std::unique_ptr> +SequentialIntegerAttributeDecoder::CreateIntPredictionScheme( + PredictionSchemeMethod method, + PredictionSchemeTransformType transform_type) { + if (transform_type != PREDICTION_TRANSFORM_WRAP) { + return nullptr; // For now we support only wrap transform. + } + return CreatePredictionSchemeForDecoder< + int32_t, PredictionSchemeWrapDecodingTransform>( + method, attribute_id(), decoder()); +} + +bool SequentialIntegerAttributeDecoder::DecodeIntegerValues( + const std::vector &point_ids, DecoderBuffer *in_buffer) { + const int num_components = GetNumValueComponents(); + if (num_components <= 0) { + return false; + } + const size_t num_entries = point_ids.size(); + const size_t num_values = num_entries * num_components; + PreparePortableAttribute(static_cast(num_entries), num_components); + int32_t *const portable_attribute_data = GetPortableAttributeData(); + if (portable_attribute_data == nullptr) { + return false; + } + uint8_t compressed; + if (!in_buffer->Decode(&compressed)) { + return false; + } + if (compressed > 0) { + // Decode compressed values. + if (!DecodeSymbols(static_cast(num_values), num_components, + in_buffer, + reinterpret_cast(portable_attribute_data))) { + return false; + } + } else { + // Decode the integer data directly. + // Get the number of bytes for a given entry. + uint8_t num_bytes; + if (!in_buffer->Decode(&num_bytes)) { + return false; + } + if (num_bytes == DataTypeLength(DT_INT32)) { + if (portable_attribute()->buffer()->data_size() < + sizeof(int32_t) * num_values) { + return false; + } + if (!in_buffer->Decode(portable_attribute_data, + sizeof(int32_t) * num_values)) { + return false; + } + } else { + if (portable_attribute()->buffer()->data_size() < + num_bytes * num_values) { + return false; + } + if (in_buffer->remaining_size() < + static_cast(num_bytes) * static_cast(num_values)) { + return false; + } + for (size_t i = 0; i < num_values; ++i) { + if (!in_buffer->Decode(portable_attribute_data + i, num_bytes)) { + return false; + } + } + } + } + + if (num_values > 0 && (prediction_scheme_ == nullptr || + !prediction_scheme_->AreCorrectionsPositive())) { + // Convert the values back to the original signed format. + ConvertSymbolsToSignedInts( + reinterpret_cast(portable_attribute_data), + static_cast(num_values), portable_attribute_data); + } + + // If the data was encoded with a prediction scheme, we must revert it. + if (prediction_scheme_) { + if (!prediction_scheme_->DecodePredictionData(in_buffer)) { + return false; + } + + if (num_values > 0) { + if (!prediction_scheme_->ComputeOriginalValues( + portable_attribute_data, portable_attribute_data, + static_cast(num_values), num_components, point_ids.data())) { + return false; + } + } + } + return true; +} + +bool SequentialIntegerAttributeDecoder::StoreValues(uint32_t num_values) { + switch (attribute()->data_type()) { + case DT_UINT8: + StoreTypedValues(num_values); + break; + case DT_INT8: + StoreTypedValues(num_values); + break; + case DT_UINT16: + StoreTypedValues(num_values); + break; + case DT_INT16: + StoreTypedValues(num_values); + break; + case DT_UINT32: + StoreTypedValues(num_values); + break; + case DT_INT32: + StoreTypedValues(num_values); + break; + default: + return false; + } + return true; +} + +template +void SequentialIntegerAttributeDecoder::StoreTypedValues(uint32_t num_values) { + const int num_components = attribute()->num_components(); + const int entry_size = sizeof(AttributeTypeT) * num_components; + const std::unique_ptr att_val( + new AttributeTypeT[num_components]); + const int32_t *const portable_attribute_data = GetPortableAttributeData(); + int val_id = 0; + int out_byte_pos = 0; + for (uint32_t i = 0; i < num_values; ++i) { + for (int c = 0; c < num_components; ++c) { + const AttributeTypeT value = + static_cast(portable_attribute_data[val_id++]); + att_val[c] = value; + } + // Store the integer value into the attribute buffer. + attribute()->buffer()->Write(out_byte_pos, att_val.get(), entry_size); + out_byte_pos += entry_size; + } +} + +void SequentialIntegerAttributeDecoder::PreparePortableAttribute( + int num_entries, int num_components) { + GeometryAttribute ga; + ga.Init(attribute()->attribute_type(), nullptr, num_components, DT_INT32, + false, num_components * DataTypeLength(DT_INT32), 0); + std::unique_ptr port_att(new PointAttribute(ga)); + port_att->SetIdentityMapping(); + port_att->Reset(num_entries); + port_att->set_unique_id(attribute()->unique_id()); + SetPortableAttribute(std::move(port_att)); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.h b/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.h new file mode 100644 index 0000000000..ef48ed817a --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_decoder.h @@ -0,0 +1,76 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_INTEGER_ATTRIBUTE_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_INTEGER_ATTRIBUTE_DECODER_H_ + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h" +#include "draco/compression/attributes/sequential_attribute_decoder.h" +#include "draco/draco_features.h" + +namespace draco { + +// Decoder for attributes encoded with the SequentialIntegerAttributeEncoder. +class SequentialIntegerAttributeDecoder : public SequentialAttributeDecoder { + public: + SequentialIntegerAttributeDecoder(); + bool Init(PointCloudDecoder *decoder, int attribute_id) override; + + bool TransformAttributeToOriginalFormat( + const std::vector &point_ids) override; + + protected: + bool DecodeValues(const std::vector &point_ids, + DecoderBuffer *in_buffer) override; + virtual bool DecodeIntegerValues(const std::vector &point_ids, + DecoderBuffer *in_buffer); + + // Returns a prediction scheme that should be used for decoding of the + // integer values. + virtual std::unique_ptr> + CreateIntPredictionScheme(PredictionSchemeMethod method, + PredictionSchemeTransformType transform_type); + + // Returns the number of integer attribute components. In general, this + // can be different from the number of components of the input attribute. + virtual int32_t GetNumValueComponents() const { + return attribute()->num_components(); + } + + // Called after all integer values are decoded. The implementation should + // use this method to store the values into the attribute. + virtual bool StoreValues(uint32_t num_values); + + void PreparePortableAttribute(int num_entries, int num_components); + + int32_t *GetPortableAttributeData() { + if (portable_attribute()->size() == 0) { + return nullptr; + } + return reinterpret_cast( + portable_attribute()->GetAddress(AttributeValueIndex(0))); + } + + private: + // Stores decoded values into the attribute with a data type AttributeTypeT. + template + void StoreTypedValues(uint32_t num_values); + + std::unique_ptr> + prediction_scheme_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_INTEGER_ATTRIBUTE_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc b/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc new file mode 100644 index 0000000000..5f673be422 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.cc @@ -0,0 +1,235 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/sequential_integer_attribute_encoder.h" + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h" +#include "draco/compression/entropy/symbol_encoding.h" +#include "draco/core/bit_utils.h" + +namespace draco { + +SequentialIntegerAttributeEncoder::SequentialIntegerAttributeEncoder() {} + +bool SequentialIntegerAttributeEncoder::Init(PointCloudEncoder *encoder, + int attribute_id) { + if (!SequentialAttributeEncoder::Init(encoder, attribute_id)) { + return false; + } + if (GetUniqueId() == SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER) { + // When encoding integers, this encoder currently works only for integer + // attributes up to 32 bits. + switch (attribute()->data_type()) { + case DT_INT8: + case DT_UINT8: + case DT_INT16: + case DT_UINT16: + case DT_INT32: + case DT_UINT32: + break; + default: + return false; + } + } + // Init prediction scheme. + const PredictionSchemeMethod prediction_scheme_method = + GetPredictionMethodFromOptions(attribute_id, *encoder->options()); + + prediction_scheme_ = CreateIntPredictionScheme(prediction_scheme_method); + + if (prediction_scheme_ && !InitPredictionScheme(prediction_scheme_.get())) { + prediction_scheme_ = nullptr; + } + + return true; +} + +bool SequentialIntegerAttributeEncoder::TransformAttributeToPortableFormat( + const std::vector &point_ids) { + if (encoder()) { + if (!PrepareValues(point_ids, encoder()->point_cloud()->num_points())) { + return false; + } + } else { + if (!PrepareValues(point_ids, 0)) { + return false; + } + } + + // Update point to attribute mapping with the portable attribute if the + // attribute is a parent attribute (for now, we can skip it otherwise). + if (is_parent_encoder()) { + // First create map between original attribute value indices and new ones + // (determined by the encoding order). + const PointAttribute *const orig_att = attribute(); + PointAttribute *const portable_att = portable_attribute(); + IndexTypeVector + value_to_value_map(orig_att->size()); + for (int i = 0; i < point_ids.size(); ++i) { + value_to_value_map[orig_att->mapped_index(point_ids[i])] = + AttributeValueIndex(i); + } + if (portable_att->is_mapping_identity()) { + portable_att->SetExplicitMapping(encoder()->point_cloud()->num_points()); + } + // Go over all points of the original attribute and update the mapping in + // the portable attribute. + for (PointIndex i(0); i < encoder()->point_cloud()->num_points(); ++i) { + portable_att->SetPointMapEntry( + i, value_to_value_map[orig_att->mapped_index(i)]); + } + } + return true; +} + +std::unique_ptr> +SequentialIntegerAttributeEncoder::CreateIntPredictionScheme( + PredictionSchemeMethod method) { + return CreatePredictionSchemeForEncoder< + int32_t, PredictionSchemeWrapEncodingTransform>( + method, attribute_id(), encoder()); +} + +bool SequentialIntegerAttributeEncoder::EncodeValues( + const std::vector &point_ids, EncoderBuffer *out_buffer) { + // Initialize general quantization data. + const PointAttribute *const attrib = attribute(); + if (attrib->size() == 0) { + return true; + } + + int8_t prediction_scheme_method = PREDICTION_NONE; + if (prediction_scheme_) { + if (!SetPredictionSchemeParentAttributes(prediction_scheme_.get())) { + return false; + } + prediction_scheme_method = + static_cast(prediction_scheme_->GetPredictionMethod()); + } + out_buffer->Encode(prediction_scheme_method); + if (prediction_scheme_) { + out_buffer->Encode( + static_cast(prediction_scheme_->GetTransformType())); + } + + const int num_components = portable_attribute()->num_components(); + const int num_values = + static_cast(num_components * portable_attribute()->size()); + const int32_t *const portable_attribute_data = GetPortableAttributeData(); + + // We need to keep the portable data intact, but several encoding steps can + // result in changes of this data, e.g., by applying prediction schemes that + // change the data in place. To preserve the portable data we store and + // process all encoded data in a separate array. + std::vector encoded_data(num_values); + + // All integer values are initialized. Process them using the prediction + // scheme if we have one. + if (prediction_scheme_) { + if (!prediction_scheme_->ComputeCorrectionValues( + portable_attribute_data, &encoded_data[0], num_values, + num_components, point_ids.data())) { + return false; + } + } + + if (prediction_scheme_ == nullptr || + !prediction_scheme_->AreCorrectionsPositive()) { + const int32_t *const input = + prediction_scheme_ ? encoded_data.data() : portable_attribute_data; + ConvertSignedIntsToSymbols(input, num_values, + reinterpret_cast(&encoded_data[0])); + } + + if (encoder() == nullptr || encoder()->options()->GetGlobalBool( + "use_built_in_attribute_compression", true)) { + out_buffer->Encode(static_cast(1)); + Options symbol_encoding_options; + if (encoder() != nullptr) { + SetSymbolEncodingCompressionLevel(&symbol_encoding_options, + 10 - encoder()->options()->GetSpeed()); + } + if (!EncodeSymbols(reinterpret_cast(encoded_data.data()), + static_cast(point_ids.size()) * num_components, + num_components, &symbol_encoding_options, out_buffer)) { + return false; + } + } else { + // No compression. Just store the raw integer values, using the number of + // bytes as needed. + + // To compute the maximum bit-length, first OR all values. + uint32_t masked_value = 0; + for (uint32_t i = 0; i < static_cast(num_values); ++i) { + masked_value |= encoded_data[i]; + } + // Compute the msb of the ORed value. + int value_msb_pos = 0; + if (masked_value != 0) { + value_msb_pos = MostSignificantBit(masked_value); + } + const int num_bytes = 1 + value_msb_pos / 8; + + out_buffer->Encode(static_cast(0)); + out_buffer->Encode(static_cast(num_bytes)); + + if (num_bytes == DataTypeLength(DT_INT32)) { + out_buffer->Encode(encoded_data.data(), sizeof(int32_t) * num_values); + } else { + for (uint32_t i = 0; i < static_cast(num_values); ++i) { + out_buffer->Encode(encoded_data.data() + i, num_bytes); + } + } + } + if (prediction_scheme_) { + prediction_scheme_->EncodePredictionData(out_buffer); + } + return true; +} + +bool SequentialIntegerAttributeEncoder::PrepareValues( + const std::vector &point_ids, int num_points) { + // Convert all values to int32_t format. + const PointAttribute *const attrib = attribute(); + const int num_components = attrib->num_components(); + const int num_entries = static_cast(point_ids.size()); + PreparePortableAttribute(num_entries, num_components, num_points); + int32_t dst_index = 0; + int32_t *const portable_attribute_data = GetPortableAttributeData(); + for (PointIndex pi : point_ids) { + const AttributeValueIndex att_id = attrib->mapped_index(pi); + if (!attrib->ConvertValue(att_id, + portable_attribute_data + dst_index)) { + return false; + } + dst_index += num_components; + } + return true; +} + +void SequentialIntegerAttributeEncoder::PreparePortableAttribute( + int num_entries, int num_components, int num_points) { + GeometryAttribute va; + va.Init(attribute()->attribute_type(), nullptr, num_components, DT_INT32, + false, num_components * DataTypeLength(DT_INT32), 0); + std::unique_ptr port_att(new PointAttribute(va)); + port_att->Reset(num_entries); + SetPortableAttribute(std::move(port_att)); + if (num_points) { + portable_attribute()->SetExplicitMapping(num_points); + } +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.h b/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.h new file mode 100644 index 0000000000..c1d6222ef4 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_encoder.h @@ -0,0 +1,67 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_INTEGER_ATTRIBUTE_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_INTEGER_ATTRIBUTE_ENCODER_H_ + +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h" +#include "draco/compression/attributes/sequential_attribute_encoder.h" + +namespace draco { + +// Attribute encoder designed for lossless encoding of integer attributes. The +// attribute values can be pre-processed by a prediction scheme and compressed +// with a built-in entropy coder. +class SequentialIntegerAttributeEncoder : public SequentialAttributeEncoder { + public: + SequentialIntegerAttributeEncoder(); + uint8_t GetUniqueId() const override { + return SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER; + } + + bool Init(PointCloudEncoder *encoder, int attribute_id) override; + bool TransformAttributeToPortableFormat( + const std::vector &point_ids) override; + + protected: + bool EncodeValues(const std::vector &point_ids, + EncoderBuffer *out_buffer) override; + + // Returns a prediction scheme that should be used for encoding of the + // integer values. + virtual std::unique_ptr> + CreateIntPredictionScheme(PredictionSchemeMethod method); + + // Prepares the integer values that are going to be encoded. + virtual bool PrepareValues(const std::vector &point_ids, + int num_points); + + void PreparePortableAttribute(int num_entries, int num_components, + int num_points); + + int32_t *GetPortableAttributeData() { + return reinterpret_cast( + portable_attribute()->GetAddress(AttributeValueIndex(0))); + } + + private: + // Optional prediction scheme can be used to modify the integer values in + // order to make them easier to compress. + std::unique_ptr> + prediction_scheme_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_INTEGER_ATTRIBUTE_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_encoding_test.cc b/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_encoding_test.cc new file mode 100644 index 0000000000..44485e679d --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_integer_attribute_encoding_test.cc @@ -0,0 +1,64 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include + +#include "draco/compression/attributes/sequential_integer_attribute_decoder.h" +#include "draco/compression/attributes/sequential_integer_attribute_encoder.h" +#include "draco/compression/config/compression_shared.h" +#include "draco/core/draco_test_base.h" + +namespace draco { + +class SequentialIntegerAttributeEncodingTest : public ::testing::Test { + protected: +}; + +TEST_F(SequentialIntegerAttributeEncodingTest, DoesCompress) { + // This test verifies that IntegerEncoding encodes and decodes the given data. + const std::vector values{1, 8, 7, 5, 5, 5, 9, + 155, -6, -9, 9, 125, 1, 0}; + PointAttribute pa; + pa.Init(GeometryAttribute::GENERIC, 1, DT_INT32, false, values.size()); + for (uint32_t i = 0; i < values.size(); ++i) { + pa.SetAttributeValue(AttributeValueIndex(i), &values[i]); + } + // List of point ids from 0 to point_ids.size() - 1. + std::vector point_ids(values.size()); + std::iota(point_ids.begin(), point_ids.end(), 0); + + EncoderBuffer out_buf; + SequentialIntegerAttributeEncoder ie; + ASSERT_TRUE(ie.InitializeStandalone(&pa)); + ASSERT_TRUE(ie.TransformAttributeToPortableFormat(point_ids)); + ASSERT_TRUE(ie.EncodePortableAttribute(point_ids, &out_buf)); + ASSERT_TRUE(ie.EncodeDataNeededByPortableTransform(&out_buf)); + + DecoderBuffer in_buf; + in_buf.Init(out_buf.data(), out_buf.size()); + in_buf.set_bitstream_version(kDracoMeshBitstreamVersion); + SequentialIntegerAttributeDecoder id; + ASSERT_TRUE(id.InitializeStandalone(&pa)); + ASSERT_TRUE(id.DecodePortableAttribute(point_ids, &in_buf)); + ASSERT_TRUE(id.DecodeDataNeededByPortableTransform(point_ids, &in_buf)); + ASSERT_TRUE(id.TransformAttributeToOriginalFormat(point_ids)); + + for (uint32_t i = 0; i < values.size(); ++i) { + int32_t entry_val; + pa.GetValue(AttributeValueIndex(i), &entry_val); + ASSERT_EQ(entry_val, values[i]); + } +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc b/third-party/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc new file mode 100644 index 0000000000..de36c1c36f --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.cc @@ -0,0 +1,76 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/sequential_normal_attribute_decoder.h" + +#include "draco/compression/attributes/normal_compression_utils.h" + +namespace draco { + +SequentialNormalAttributeDecoder::SequentialNormalAttributeDecoder() {} + +bool SequentialNormalAttributeDecoder::Init(PointCloudDecoder *decoder, + int attribute_id) { + if (!SequentialIntegerAttributeDecoder::Init(decoder, attribute_id)) { + return false; + } + // Currently, this encoder works only for 3-component normal vectors. + if (attribute()->num_components() != 3) { + return false; + } + // Also the data type must be DT_FLOAT32. + if (attribute()->data_type() != DT_FLOAT32) { + return false; + } + return true; +} + +bool SequentialNormalAttributeDecoder::DecodeIntegerValues( + const std::vector &point_ids, DecoderBuffer *in_buffer) { +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + if (decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) { + // Note: in older bitstreams, we do not have a PortableAttribute() decoded + // at this stage so we cannot pass it down to the DecodeParameters() call. + // It still works fine for octahedral transform because it does not need to + // use any data from the attribute. + if (!octahedral_transform_.DecodeParameters(*attribute(), in_buffer)) { + return false; + } + } +#endif + return SequentialIntegerAttributeDecoder::DecodeIntegerValues(point_ids, + in_buffer); +} + +bool SequentialNormalAttributeDecoder::DecodeDataNeededByPortableTransform( + const std::vector &point_ids, DecoderBuffer *in_buffer) { + if (decoder()->bitstream_version() >= DRACO_BITSTREAM_VERSION(2, 0)) { + // For newer file version, decode attribute transform data here. + if (!octahedral_transform_.DecodeParameters(*GetPortableAttribute(), + in_buffer)) { + return false; + } + } + + // Store the decoded transform data in portable attribute. + return octahedral_transform_.TransferToAttribute(portable_attribute()); +} + +bool SequentialNormalAttributeDecoder::StoreValues(uint32_t num_points) { + // Convert all quantized values back to floats. + return octahedral_transform_.InverseTransformAttribute( + *GetPortableAttribute(), attribute()); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.h b/third-party/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.h new file mode 100644 index 0000000000..8c2d801b76 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_normal_attribute_decoder.h @@ -0,0 +1,83 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_NORMAL_ATTRIBUTE_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_NORMAL_ATTRIBUTE_DECODER_H_ + +#include "draco/attributes/attribute_octahedron_transform.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h" +#include "draco/compression/attributes/sequential_integer_attribute_decoder.h" +#include "draco/draco_features.h" + +namespace draco { + +// Decoder for attributes encoded with SequentialNormalAttributeEncoder. +class SequentialNormalAttributeDecoder + : public SequentialIntegerAttributeDecoder { + public: + SequentialNormalAttributeDecoder(); + bool Init(PointCloudDecoder *decoder, int attribute_id) override; + + protected: + int32_t GetNumValueComponents() const override { + return 2; // We quantize everything into two components. + } + bool DecodeIntegerValues(const std::vector &point_ids, + DecoderBuffer *in_buffer) override; + bool DecodeDataNeededByPortableTransform( + const std::vector &point_ids, + DecoderBuffer *in_buffer) override; + bool StoreValues(uint32_t num_points) override; + + private: + AttributeOctahedronTransform octahedral_transform_; + + std::unique_ptr> + CreateIntPredictionScheme( + PredictionSchemeMethod method, + PredictionSchemeTransformType transform_type) override { + switch (transform_type) { +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + case PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON: { + typedef PredictionSchemeNormalOctahedronDecodingTransform + Transform; + // At this point the decoder has not read the quantization bits, + // which is why we must construct the transform by default. + // See Transform.DecodeTransformData for more details. + return CreatePredictionSchemeForDecoder( + method, attribute_id(), decoder()); + } +#endif + case PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED: { + typedef PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform< + int32_t> + Transform; + // At this point the decoder has not read the quantization bits, + // which is why we must construct the transform by default. + // See Transform.DecodeTransformData for more details. + return CreatePredictionSchemeForDecoder( + method, attribute_id(), decoder()); + } + default: + return nullptr; // Currently, we support only octahedron transform and + // octahedron transform canonicalized. + } + } +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_NORMAL_ATTRIBUTE_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc b/third-party/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc new file mode 100644 index 0000000000..3c5ef0ebcb --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.cc @@ -0,0 +1,58 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/sequential_normal_attribute_encoder.h" + +#include "draco/compression/attributes/normal_compression_utils.h" + +namespace draco { + +bool SequentialNormalAttributeEncoder::Init(PointCloudEncoder *encoder, + int attribute_id) { + if (!SequentialIntegerAttributeEncoder::Init(encoder, attribute_id)) { + return false; + } + // Currently this encoder works only for 3-component normal vectors. + if (attribute()->num_components() != 3) { + return false; + } + + // Initialize AttributeOctahedronTransform. + const int quantization_bits = encoder->options()->GetAttributeInt( + attribute_id, "quantization_bits", -1); + if (quantization_bits < 1) { + return false; + } + attribute_octahedron_transform_.SetParameters(quantization_bits); + return true; +} + +bool SequentialNormalAttributeEncoder::EncodeDataNeededByPortableTransform( + EncoderBuffer *out_buffer) { + return attribute_octahedron_transform_.EncodeParameters(out_buffer); +} + +bool SequentialNormalAttributeEncoder::PrepareValues( + const std::vector &point_ids, int num_points) { + auto portable_att = attribute_octahedron_transform_.InitTransformedAttribute( + *(attribute()), point_ids.size()); + if (!attribute_octahedron_transform_.TransformAttribute( + *(attribute()), point_ids, portable_att.get())) { + return false; + } + SetPortableAttribute(std::move(portable_att)); + return true; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.h b/third-party/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.h new file mode 100644 index 0000000000..53705c5982 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_normal_attribute_encoder.h @@ -0,0 +1,82 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_NORMAL_ATTRIBUTE_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_NORMAL_ATTRIBUTE_ENCODER_H_ + +#include "draco/attributes/attribute_octahedron_transform.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h" +#include "draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h" +#include "draco/compression/attributes/sequential_integer_attribute_encoder.h" +#include "draco/compression/config/compression_shared.h" + +namespace draco { + +// Class for encoding normal vectors using an octahedral encoding, see Cigolle +// et al.'14 “A Survey of Efficient Representations for Independent Unit +// Vectors”. Compared to the basic quantization encoder, this encoder results +// in a better compression rate under the same accuracy settings. Note that this +// encoder doesn't preserve the lengths of input vectors, therefore it will not +// work correctly when the input values are not normalized. +class SequentialNormalAttributeEncoder + : public SequentialIntegerAttributeEncoder { + public: + uint8_t GetUniqueId() const override { + return SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS; + } + bool IsLossyEncoder() const override { return true; } + + bool EncodeDataNeededByPortableTransform(EncoderBuffer *out_buffer) override; + + protected: + bool Init(PointCloudEncoder *encoder, int attribute_id) override; + + // Put quantized values in portable attribute for sequential encoding. + bool PrepareValues(const std::vector &point_ids, + int num_points) override; + + std::unique_ptr> + CreateIntPredictionScheme(PredictionSchemeMethod /* method */) override { + typedef PredictionSchemeNormalOctahedronCanonicalizedEncodingTransform< + int32_t> + Transform; + const int32_t quantization_bits = encoder()->options()->GetAttributeInt( + attribute_id(), "quantization_bits", -1); + const int32_t max_value = (1 << quantization_bits) - 1; + const Transform transform(max_value); + const PredictionSchemeMethod default_prediction_method = + SelectPredictionMethod(attribute_id(), encoder()); + const int32_t prediction_method = encoder()->options()->GetAttributeInt( + attribute_id(), "prediction_scheme", default_prediction_method); + + if (prediction_method == MESH_PREDICTION_GEOMETRIC_NORMAL) { + return CreatePredictionSchemeForEncoder( + MESH_PREDICTION_GEOMETRIC_NORMAL, attribute_id(), encoder(), + transform); + } + if (prediction_method == PREDICTION_DIFFERENCE) { + return CreatePredictionSchemeForEncoder( + PREDICTION_DIFFERENCE, attribute_id(), encoder(), transform); + } + DRACO_DCHECK(false); // Should never be reached. + return nullptr; + } + + // Used for the conversion to quantized normals in octahedral format. + AttributeOctahedronTransform attribute_octahedron_transform_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_NORMAL_ATTRIBUTE_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc b/third-party/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc new file mode 100644 index 0000000000..3d306e7dae --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc @@ -0,0 +1,88 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/sequential_quantization_attribute_decoder.h" + +#include "draco/core/quantization_utils.h" + +namespace draco { + +SequentialQuantizationAttributeDecoder:: + SequentialQuantizationAttributeDecoder() {} + +bool SequentialQuantizationAttributeDecoder::Init(PointCloudDecoder *decoder, + int attribute_id) { + if (!SequentialIntegerAttributeDecoder::Init(decoder, attribute_id)) { + return false; + } + const PointAttribute *const attribute = + decoder->point_cloud()->attribute(attribute_id); + // Currently we can quantize only floating point arguments. + if (attribute->data_type() != DT_FLOAT32) { + return false; + } + return true; +} + +bool SequentialQuantizationAttributeDecoder::DecodeIntegerValues( + const std::vector &point_ids, DecoderBuffer *in_buffer) { +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + if (decoder()->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0) && + !DecodeQuantizedDataInfo()) { + return false; + } +#endif + return SequentialIntegerAttributeDecoder::DecodeIntegerValues(point_ids, + in_buffer); +} + +bool SequentialQuantizationAttributeDecoder:: + DecodeDataNeededByPortableTransform( + const std::vector &point_ids, DecoderBuffer *in_buffer) { + if (decoder()->bitstream_version() >= DRACO_BITSTREAM_VERSION(2, 0)) { + // Decode quantization data here only for files with bitstream version 2.0+ + if (!DecodeQuantizedDataInfo()) { + return false; + } + } + + // Store the decoded transform data in portable attribute; + return quantization_transform_.TransferToAttribute(portable_attribute()); +} + +bool SequentialQuantizationAttributeDecoder::StoreValues(uint32_t num_points) { + return DequantizeValues(num_points); +} + +bool SequentialQuantizationAttributeDecoder::DecodeQuantizedDataInfo() { + // Get attribute used as source for decoding. + auto att = GetPortableAttribute(); + if (att == nullptr) { + // This should happen only in the backward compatibility mode. It will still + // work fine for this case because the only thing the quantization transform + // cares about is the number of components that is the same for both source + // and target attributes. + att = attribute(); + } + return quantization_transform_.DecodeParameters(*att, decoder()->buffer()); +} + +bool SequentialQuantizationAttributeDecoder::DequantizeValues( + uint32_t num_values) { + // Convert all quantized values back to floats. + return quantization_transform_.InverseTransformAttribute( + *GetPortableAttribute(), attribute()); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h b/third-party/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h new file mode 100644 index 0000000000..ad372dcd8a --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_quantization_attribute_decoder.h @@ -0,0 +1,52 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_QUANTIZATION_ATTRIBUTE_DECODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_QUANTIZATION_ATTRIBUTE_DECODER_H_ + +#include "draco/attributes/attribute_quantization_transform.h" +#include "draco/compression/attributes/sequential_integer_attribute_decoder.h" +#include "draco/draco_features.h" + +namespace draco { + +// Decoder for attribute values encoded with the +// SequentialQuantizationAttributeEncoder. +class SequentialQuantizationAttributeDecoder + : public SequentialIntegerAttributeDecoder { + public: + SequentialQuantizationAttributeDecoder(); + bool Init(PointCloudDecoder *decoder, int attribute_id) override; + + protected: + bool DecodeIntegerValues(const std::vector &point_ids, + DecoderBuffer *in_buffer) override; + bool DecodeDataNeededByPortableTransform( + const std::vector &point_ids, + DecoderBuffer *in_buffer) override; + bool StoreValues(uint32_t num_points) override; + + // Decodes data necessary for dequantizing the encoded values. + virtual bool DecodeQuantizedDataInfo(); + + // Dequantizes all values and stores them into the output attribute. + virtual bool DequantizeValues(uint32_t num_values); + + private: + AttributeQuantizationTransform quantization_transform_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_QUANTIZATION_ATTRIBUTE_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc b/third-party/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc new file mode 100644 index 0000000000..d3666f7a41 --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc @@ -0,0 +1,86 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/attributes/sequential_quantization_attribute_encoder.h" + +#include "draco/core/quantization_utils.h" + +namespace draco { + +SequentialQuantizationAttributeEncoder:: + SequentialQuantizationAttributeEncoder() {} + +bool SequentialQuantizationAttributeEncoder::Init(PointCloudEncoder *encoder, + int attribute_id) { + if (!SequentialIntegerAttributeEncoder::Init(encoder, attribute_id)) { + return false; + } + // This encoder currently works only for floating point attributes. + const PointAttribute *const attribute = + encoder->point_cloud()->attribute(attribute_id); + if (attribute->data_type() != DT_FLOAT32) { + return false; + } + + // Initialize AttributeQuantizationTransform. + const int quantization_bits = encoder->options()->GetAttributeInt( + attribute_id, "quantization_bits", -1); + if (quantization_bits < 1) { + return false; + } + if (encoder->options()->IsAttributeOptionSet(attribute_id, + "quantization_origin") && + encoder->options()->IsAttributeOptionSet(attribute_id, + "quantization_range")) { + // Quantization settings are explicitly specified in the provided options. + std::vector quantization_origin(attribute->num_components()); + encoder->options()->GetAttributeVector(attribute_id, "quantization_origin", + attribute->num_components(), + &quantization_origin[0]); + const float range = encoder->options()->GetAttributeFloat( + attribute_id, "quantization_range", 1.f); + if (!attribute_quantization_transform_.SetParameters( + quantization_bits, quantization_origin.data(), + attribute->num_components(), range)) { + return false; + } + } else { + // Compute quantization settings from the attribute values. + if (!attribute_quantization_transform_.ComputeParameters( + *attribute, quantization_bits)) { + return false; + } + } + return true; +} + +bool SequentialQuantizationAttributeEncoder:: + EncodeDataNeededByPortableTransform(EncoderBuffer *out_buffer) { + return attribute_quantization_transform_.EncodeParameters(out_buffer); +} + +bool SequentialQuantizationAttributeEncoder::PrepareValues( + const std::vector &point_ids, int num_points) { + auto portable_attribute = + attribute_quantization_transform_.InitTransformedAttribute( + *attribute(), point_ids.size()); + if (!attribute_quantization_transform_.TransformAttribute( + *(attribute()), point_ids, portable_attribute.get())) { + return false; + } + SetPortableAttribute(std::move(portable_attribute)); + return true; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.h b/third-party/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.h new file mode 100644 index 0000000000..e9762bdd6d --- /dev/null +++ b/third-party/draco/src/draco/compression/attributes/sequential_quantization_attribute_encoder.h @@ -0,0 +1,52 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_QUANTIZATION_ATTRIBUTE_ENCODER_H_ +#define DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_QUANTIZATION_ATTRIBUTE_ENCODER_H_ + +#include "draco/attributes/attribute_quantization_transform.h" +#include "draco/compression/attributes/sequential_integer_attribute_encoder.h" + +namespace draco { + +class MeshEncoder; + +// Attribute encoder that quantizes floating point attribute values. The +// quantized values can be optionally compressed using an entropy coding. +class SequentialQuantizationAttributeEncoder + : public SequentialIntegerAttributeEncoder { + public: + SequentialQuantizationAttributeEncoder(); + uint8_t GetUniqueId() const override { + return SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION; + } + bool Init(PointCloudEncoder *encoder, int attribute_id) override; + + bool IsLossyEncoder() const override { return true; } + + bool EncodeDataNeededByPortableTransform(EncoderBuffer *out_buffer) override; + + protected: + // Put quantized values in portable attribute for sequential encoding. + bool PrepareValues(const std::vector &point_ids, + int num_points) override; + + private: + // Used for the quantization. + AttributeQuantizationTransform attribute_quantization_transform_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ATTRIBUTES_SEQUENTIAL_QUANTIZATION_ATTRIBUTE_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h b/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h new file mode 100644 index 0000000000..faacbd5b94 --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h @@ -0,0 +1,43 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// File provides shared functions for adaptive rANS bit coding. +#ifndef DRACO_COMPRESSION_BIT_CODERS_ADAPTIVE_RANS_BIT_CODING_SHARED_H_ +#define DRACO_COMPRESSION_BIT_CODERS_ADAPTIVE_RANS_BIT_CODING_SHARED_H_ + +#include "draco/core/macros.h" + +namespace draco { + +// Clamp the probability p to a uint8_t in the range [1,255]. +inline uint8_t clamp_probability(double p) { + DRACO_DCHECK_LE(p, 1.0); + DRACO_DCHECK_LE(0.0, p); + uint32_t p_int = static_cast((p * 256) + 0.5); + p_int -= (p_int == 256); + p_int += (p_int == 0); + return static_cast(p_int); +} + +// Update the probability according to new incoming bit. +inline double update_probability(double old_p, bool bit) { + static constexpr double w = 128.0; + static constexpr double w0 = (w - 1.0) / w; + static constexpr double w1 = 1.0 / w; + return old_p * w0 + (!bit) * w1; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_BIT_CODERS_ADAPTIVE_RANS_BIT_CODING_SHARED_H_ diff --git a/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc b/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc new file mode 100644 index 0000000000..056842c4a9 --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc @@ -0,0 +1,70 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/bit_coders/adaptive_rans_bit_decoder.h" + +#include "draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h" + +namespace draco { + +AdaptiveRAnsBitDecoder::AdaptiveRAnsBitDecoder() : p0_f_(0.5) {} + +AdaptiveRAnsBitDecoder::~AdaptiveRAnsBitDecoder() { Clear(); } + +bool AdaptiveRAnsBitDecoder::StartDecoding(DecoderBuffer *source_buffer) { + Clear(); + + uint32_t size_in_bytes; + if (!source_buffer->Decode(&size_in_bytes)) { + return false; + } + if (size_in_bytes > source_buffer->remaining_size()) { + return false; + } + if (ans_read_init(&ans_decoder_, + reinterpret_cast( + const_cast(source_buffer->data_head())), + size_in_bytes) != 0) { + return false; + } + source_buffer->Advance(size_in_bytes); + return true; +} + +bool AdaptiveRAnsBitDecoder::DecodeNextBit() { + const uint8_t p0 = clamp_probability(p0_f_); + const bool bit = static_cast(rabs_read(&ans_decoder_, p0)); + p0_f_ = update_probability(p0_f_, bit); + return bit; +} + +void AdaptiveRAnsBitDecoder::DecodeLeastSignificantBits32(int nbits, + uint32_t *value) { + DRACO_DCHECK_EQ(true, nbits <= 32); + DRACO_DCHECK_EQ(true, nbits > 0); + + uint32_t result = 0; + while (nbits) { + result = (result << 1) + DecodeNextBit(); + --nbits; + } + *value = result; +} + +void AdaptiveRAnsBitDecoder::Clear() { + ans_read_end(&ans_decoder_); + p0_f_ = 0.5; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h b/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h new file mode 100644 index 0000000000..a1ea011dd6 --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h @@ -0,0 +1,54 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// File provides basic classes and functions for rANS bit decoding. +#ifndef DRACO_COMPRESSION_BIT_CODERS_ADAPTIVE_RANS_BIT_DECODER_H_ +#define DRACO_COMPRESSION_BIT_CODERS_ADAPTIVE_RANS_BIT_DECODER_H_ + +#include + +#include "draco/compression/entropy/ans.h" +#include "draco/core/decoder_buffer.h" + +namespace draco { + +// Class for decoding a sequence of bits that were encoded with +// AdaptiveRAnsBitEncoder. +class AdaptiveRAnsBitDecoder { + public: + AdaptiveRAnsBitDecoder(); + ~AdaptiveRAnsBitDecoder(); + + // Sets |source_buffer| as the buffer to decode bits from. + bool StartDecoding(DecoderBuffer *source_buffer); + + // Decode one bit. Returns true if the bit is a 1, otherwise false. + bool DecodeNextBit(); + + // Decode the next |nbits| and return the sequence in |value|. |nbits| must be + // > 0 and <= 32. + void DecodeLeastSignificantBits32(int nbits, uint32_t *value); + + void EndDecoding() {} + + private: + void Clear(); + + AnsDecoder ans_decoder_; + double p0_f_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_BIT_CODERS_ADAPTIVE_RANS_BIT_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc b/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc new file mode 100644 index 0000000000..5ce9dc388b --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc @@ -0,0 +1,59 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/bit_coders/adaptive_rans_bit_encoder.h" + +#include "draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h" + +namespace draco { + +AdaptiveRAnsBitEncoder::AdaptiveRAnsBitEncoder() {} + +AdaptiveRAnsBitEncoder::~AdaptiveRAnsBitEncoder() { Clear(); } + +void AdaptiveRAnsBitEncoder::StartEncoding() { Clear(); } + +void AdaptiveRAnsBitEncoder::EndEncoding(EncoderBuffer *target_buffer) { + // Buffer for ans to write. + std::vector buffer(bits_.size() + 16); + AnsCoder ans_coder; + ans_write_init(&ans_coder, buffer.data()); + + // Unfortunately we have to encode the bits in reversed order, while the + // probabilities that should be given are those of the forward sequence. + double p0_f = 0.5; + std::vector p0s; + p0s.reserve(bits_.size()); + for (bool b : bits_) { + p0s.push_back(clamp_probability(p0_f)); + p0_f = update_probability(p0_f, b); + } + auto bit = bits_.rbegin(); + auto pit = p0s.rbegin(); + while (bit != bits_.rend()) { + rabs_write(&ans_coder, *bit, *pit); + ++bit; + ++pit; + } + + const uint32_t size_in_bytes = ans_write_end(&ans_coder); + target_buffer->Encode(size_in_bytes); + target_buffer->Encode(buffer.data(), size_in_bytes); + + Clear(); +} + +void AdaptiveRAnsBitEncoder::Clear() { bits_.clear(); } + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h b/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h new file mode 100644 index 0000000000..9b1832844a --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h @@ -0,0 +1,61 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// File provides basic classes and functions for rANS bit encoding. +#ifndef DRACO_COMPRESSION_BIT_CODERS_ADAPTIVE_RANS_BIT_ENCODER_H_ +#define DRACO_COMPRESSION_BIT_CODERS_ADAPTIVE_RANS_BIT_ENCODER_H_ + +#include + +#include "draco/compression/entropy/ans.h" +#include "draco/core/encoder_buffer.h" + +namespace draco { + +// Class for adaptive encoding a sequence of bits using rANS. +class AdaptiveRAnsBitEncoder { + public: + AdaptiveRAnsBitEncoder(); + ~AdaptiveRAnsBitEncoder(); + + // Must be called before any Encode* function is called. + void StartEncoding(); + + // Encode one bit. If |bit| is true encode a 1, otherwise encode a 0. + void EncodeBit(bool bit) { bits_.push_back(bit); } + + // Encode |nbits| of |value|, starting from the least significant bit. + // |nbits| must be > 0 and <= 32. + void EncodeLeastSignificantBits32(int nbits, uint32_t value) { + DRACO_DCHECK_EQ(true, nbits <= 32); + DRACO_DCHECK_EQ(true, nbits > 0); + uint32_t selector = (1 << (nbits - 1)); + while (selector) { + EncodeBit(value & selector); + selector = selector >> 1; + } + } + + // Ends the bit encoding and stores the result into the target_buffer. + void EndEncoding(EncoderBuffer *target_buffer); + + private: + void Clear(); + + std::vector bits_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_BIT_CODERS_ADAPTIVE_RANS_BIT_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/bit_coders/direct_bit_decoder.cc b/third-party/draco/src/draco/compression/bit_coders/direct_bit_decoder.cc new file mode 100644 index 0000000000..2abe3382a4 --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/direct_bit_decoder.cc @@ -0,0 +1,54 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/bit_coders/direct_bit_decoder.h" + +namespace draco { + +DirectBitDecoder::DirectBitDecoder() : pos_(bits_.end()), num_used_bits_(0) {} + +DirectBitDecoder::~DirectBitDecoder() { Clear(); } + +bool DirectBitDecoder::StartDecoding(DecoderBuffer *source_buffer) { + Clear(); + uint32_t size_in_bytes; + if (!source_buffer->Decode(&size_in_bytes)) { + return false; + } + + // Check that size_in_bytes is > 0 and a multiple of 4 as the encoder always + // encodes 32 bit elements. + if (size_in_bytes == 0 || size_in_bytes & 0x3) { + return false; + } + if (size_in_bytes > source_buffer->remaining_size()) { + return false; + } + const uint32_t num_32bit_elements = size_in_bytes / 4; + bits_.resize(num_32bit_elements); + if (!source_buffer->Decode(bits_.data(), size_in_bytes)) { + return false; + } + pos_ = bits_.begin(); + num_used_bits_ = 0; + return true; +} + +void DirectBitDecoder::Clear() { + bits_.clear(); + num_used_bits_ = 0; + pos_ = bits_.end(); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/bit_coders/direct_bit_decoder.h b/third-party/draco/src/draco/compression/bit_coders/direct_bit_decoder.h new file mode 100644 index 0000000000..6273692a21 --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/direct_bit_decoder.h @@ -0,0 +1,89 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// File provides direct encoding of bits with arithmetic encoder interface. +#ifndef DRACO_COMPRESSION_BIT_CODERS_DIRECT_BIT_DECODER_H_ +#define DRACO_COMPRESSION_BIT_CODERS_DIRECT_BIT_DECODER_H_ + +#include + +#include "draco/core/decoder_buffer.h" + +namespace draco { + +class DirectBitDecoder { + public: + DirectBitDecoder(); + ~DirectBitDecoder(); + + // Sets |source_buffer| as the buffer to decode bits from. + bool StartDecoding(DecoderBuffer *source_buffer); + + // Decode one bit. Returns true if the bit is a 1, otherwise false. + bool DecodeNextBit() { + const uint32_t selector = 1 << (31 - num_used_bits_); + if (pos_ == bits_.end()) { + return false; + } + const bool bit = *pos_ & selector; + ++num_used_bits_; + if (num_used_bits_ == 32) { + ++pos_; + num_used_bits_ = 0; + } + return bit; + } + + // Decode the next |nbits| and return the sequence in |value|. |nbits| must be + // > 0 and <= 32. + bool DecodeLeastSignificantBits32(int nbits, uint32_t *value) { + DRACO_DCHECK_EQ(true, nbits <= 32); + DRACO_DCHECK_EQ(true, nbits > 0); + const int remaining = 32 - num_used_bits_; + if (nbits <= remaining) { + if (pos_ == bits_.end()) { + return false; + } + *value = (*pos_ << num_used_bits_) >> (32 - nbits); + num_used_bits_ += nbits; + if (num_used_bits_ == 32) { + ++pos_; + num_used_bits_ = 0; + } + } else { + if (pos_ + 1 == bits_.end()) { + return false; + } + const uint32_t value_l = ((*pos_) << num_used_bits_); + num_used_bits_ = nbits - remaining; + ++pos_; + const uint32_t value_r = (*pos_) >> (32 - num_used_bits_); + *value = (value_l >> (32 - num_used_bits_ - remaining)) | value_r; + } + return true; + } + + void EndDecoding() {} + + private: + void Clear(); + + std::vector bits_; + std::vector::const_iterator pos_; + uint32_t num_used_bits_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_BIT_CODERS_DIRECT_BIT_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/bit_coders/direct_bit_encoder.cc b/third-party/draco/src/draco/compression/bit_coders/direct_bit_encoder.cc new file mode 100644 index 0000000000..d39143cf56 --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/direct_bit_encoder.cc @@ -0,0 +1,39 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/bit_coders/direct_bit_encoder.h" + +namespace draco { + +DirectBitEncoder::DirectBitEncoder() : local_bits_(0), num_local_bits_(0) {} + +DirectBitEncoder::~DirectBitEncoder() { Clear(); } + +void DirectBitEncoder::StartEncoding() { Clear(); } + +void DirectBitEncoder::EndEncoding(EncoderBuffer *target_buffer) { + bits_.push_back(local_bits_); + const uint32_t size_in_byte = static_cast(bits_.size()) * 4; + target_buffer->Encode(size_in_byte); + target_buffer->Encode(bits_.data(), size_in_byte); + Clear(); +} + +void DirectBitEncoder::Clear() { + bits_.clear(); + local_bits_ = 0; + num_local_bits_ = 0; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/bit_coders/direct_bit_encoder.h b/third-party/draco/src/draco/compression/bit_coders/direct_bit_encoder.h new file mode 100644 index 0000000000..705b2ca93c --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/direct_bit_encoder.h @@ -0,0 +1,89 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// File provides direct encoding of bits with arithmetic encoder interface. +#ifndef DRACO_COMPRESSION_BIT_CODERS_DIRECT_BIT_ENCODER_H_ +#define DRACO_COMPRESSION_BIT_CODERS_DIRECT_BIT_ENCODER_H_ + +#include + +#include "draco/core/encoder_buffer.h" + +namespace draco { + +class DirectBitEncoder { + public: + DirectBitEncoder(); + ~DirectBitEncoder(); + + // Must be called before any Encode* function is called. + void StartEncoding(); + + // Encode one bit. If |bit| is true encode a 1, otherwise encode a 0. + void EncodeBit(bool bit) { + if (bit) { + local_bits_ |= 1 << (31 - num_local_bits_); + } + num_local_bits_++; + if (num_local_bits_ == 32) { + bits_.push_back(local_bits_); + num_local_bits_ = 0; + local_bits_ = 0; + } + } + + // Encode |nbits| of |value|, starting from the least significant bit. + // |nbits| must be > 0 and <= 32. + void EncodeLeastSignificantBits32(int nbits, uint32_t value) { + DRACO_DCHECK_EQ(true, nbits <= 32); + DRACO_DCHECK_EQ(true, nbits > 0); + + const int remaining = 32 - num_local_bits_; + + // Make sure there are no leading bits that should not be encoded and + // start from here. + value = value << (32 - nbits); + if (nbits <= remaining) { + value = value >> num_local_bits_; + local_bits_ = local_bits_ | value; + num_local_bits_ += nbits; + if (num_local_bits_ == 32) { + bits_.push_back(local_bits_); + local_bits_ = 0; + num_local_bits_ = 0; + } + } else { + value = value >> (32 - nbits); + num_local_bits_ = nbits - remaining; + const uint32_t value_l = value >> num_local_bits_; + local_bits_ = local_bits_ | value_l; + bits_.push_back(local_bits_); + local_bits_ = value << (32 - num_local_bits_); + } + } + + // Ends the bit encoding and stores the result into the target_buffer. + void EndEncoding(EncoderBuffer *target_buffer); + + private: + void Clear(); + + std::vector bits_; + uint32_t local_bits_; + uint32_t num_local_bits_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_BIT_CODERS_DIRECT_BIT_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/bit_coders/folded_integer_bit_decoder.h b/third-party/draco/src/draco/compression/bit_coders/folded_integer_bit_decoder.h new file mode 100644 index 0000000000..c14058b656 --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/folded_integer_bit_decoder.h @@ -0,0 +1,77 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// File provides direct encoding of bits with arithmetic encoder interface. +#ifndef DRACO_COMPRESSION_BIT_CODERS_FOLDED_INTEGER_BIT_DECODER_H_ +#define DRACO_COMPRESSION_BIT_CODERS_FOLDED_INTEGER_BIT_DECODER_H_ + +#include + +#include "draco/core/decoder_buffer.h" + +namespace draco { + +// See FoldedBit32Encoder for more details. +template +class FoldedBit32Decoder { + public: + FoldedBit32Decoder() {} + ~FoldedBit32Decoder() {} + + // Sets |source_buffer| as the buffer to decode bits from. + bool StartDecoding(DecoderBuffer *source_buffer) { + for (int i = 0; i < 32; i++) { + if (!folded_number_decoders_[i].StartDecoding(source_buffer)) { + return false; + } + } + return bit_decoder_.StartDecoding(source_buffer); + } + + // Decode one bit. Returns true if the bit is a 1, otherwise false. + bool DecodeNextBit() { return bit_decoder_.DecodeNextBit(); } + + // Decode the next |nbits| and return the sequence in |value|. |nbits| must be + // > 0 and <= 32. + void DecodeLeastSignificantBits32(int nbits, uint32_t *value) { + uint32_t result = 0; + for (int i = 0; i < nbits; ++i) { + const bool bit = folded_number_decoders_[i].DecodeNextBit(); + result = (result << 1) + bit; + } + *value = result; + } + + void EndDecoding() { + for (int i = 0; i < 32; i++) { + folded_number_decoders_[i].EndDecoding(); + } + bit_decoder_.EndDecoding(); + } + + private: + void Clear() { + for (int i = 0; i < 32; i++) { + folded_number_decoders_[i].Clear(); + } + bit_decoder_.Clear(); + } + + std::array folded_number_decoders_; + BitDecoderT bit_decoder_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_BIT_CODERS_FOLDED_INTEGER_BIT_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/bit_coders/folded_integer_bit_encoder.h b/third-party/draco/src/draco/compression/bit_coders/folded_integer_bit_encoder.h new file mode 100644 index 0000000000..375b38a61f --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/folded_integer_bit_encoder.h @@ -0,0 +1,82 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// File provides direct encoding of bits with arithmetic encoder interface. +#ifndef DRACO_COMPRESSION_BIT_CODERS_FOLDED_INTEGER_BIT_ENCODER_H_ +#define DRACO_COMPRESSION_BIT_CODERS_FOLDED_INTEGER_BIT_ENCODER_H_ + +#include + +#include "draco/core/encoder_buffer.h" + +namespace draco { + +// This coding scheme considers every bit of an (up to) 32bit integer as a +// separate context. This can be a significant advantage when encoding numbers +// where it is more likely that the front bits are zero. +// The behavior is essentially the same as other arithmetic encoding schemes, +// the only difference is that encoding and decoding of bits must be absolutely +// symmetric, bits handed in by EncodeBit32 must be also decoded in this way. +// This is the FoldedBit32Encoder, see also FoldedBit32Decoder. +template +class FoldedBit32Encoder { + public: + FoldedBit32Encoder() {} + ~FoldedBit32Encoder() {} + + // Must be called before any Encode* function is called. + void StartEncoding() { + for (int i = 0; i < 32; i++) { + folded_number_encoders_[i].StartEncoding(); + } + bit_encoder_.StartEncoding(); + } + + // Encode one bit. If |bit| is true encode a 1, otherwise encode a 0. + void EncodeBit(bool bit) { bit_encoder_.EncodeBit(bit); } + + // Encode |nbits| of |value|, starting from the least significant bit. + // |nbits| must be > 0 and <= 32. + void EncodeLeastSignificantBits32(int nbits, uint32_t value) { + uint32_t selector = 1 << (nbits - 1); + for (int i = 0; i < nbits; i++) { + const bool bit = (value & selector); + folded_number_encoders_[i].EncodeBit(bit); + selector = selector >> 1; + } + } + + // Ends the bit encoding and stores the result into the target_buffer. + void EndEncoding(EncoderBuffer *target_buffer) { + for (int i = 0; i < 32; i++) { + folded_number_encoders_[i].EndEncoding(target_buffer); + } + bit_encoder_.EndEncoding(target_buffer); + } + + private: + void Clear() { + for (int i = 0; i < 32; i++) { + folded_number_encoders_[i].Clear(); + } + bit_encoder_.Clear(); + } + + std::array folded_number_encoders_; + BitEncoderT bit_encoder_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_BIT_CODERS_FOLDED_INTEGER_BIT_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/bit_coders/rans_bit_decoder.cc b/third-party/draco/src/draco/compression/bit_coders/rans_bit_decoder.cc new file mode 100644 index 0000000000..a9b8fb9e91 --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/rans_bit_decoder.cc @@ -0,0 +1,82 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/bit_coders/rans_bit_decoder.h" + +#include "draco/compression/config/compression_shared.h" +#include "draco/core/bit_utils.h" +#include "draco/core/varint_decoding.h" + +namespace draco { + +RAnsBitDecoder::RAnsBitDecoder() : prob_zero_(0) {} + +RAnsBitDecoder::~RAnsBitDecoder() { Clear(); } + +bool RAnsBitDecoder::StartDecoding(DecoderBuffer *source_buffer) { + Clear(); + + if (!source_buffer->Decode(&prob_zero_)) { + return false; + } + + uint32_t size_in_bytes; +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + if (source_buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) { + if (!source_buffer->Decode(&size_in_bytes)) { + return false; + } + + } else +#endif + { + if (!DecodeVarint(&size_in_bytes, source_buffer)) { + return false; + } + } + + if (size_in_bytes > source_buffer->remaining_size()) { + return false; + } + + if (ans_read_init(&ans_decoder_, + reinterpret_cast( + const_cast(source_buffer->data_head())), + size_in_bytes) != 0) { + return false; + } + source_buffer->Advance(size_in_bytes); + return true; +} + +bool RAnsBitDecoder::DecodeNextBit() { + const uint8_t bit = rabs_read(&ans_decoder_, prob_zero_); + return bit > 0; +} + +void RAnsBitDecoder::DecodeLeastSignificantBits32(int nbits, uint32_t *value) { + DRACO_DCHECK_EQ(true, nbits <= 32); + DRACO_DCHECK_EQ(true, nbits > 0); + + uint32_t result = 0; + while (nbits) { + result = (result << 1) + DecodeNextBit(); + --nbits; + } + *value = result; +} + +void RAnsBitDecoder::Clear() { ans_read_end(&ans_decoder_); } + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/bit_coders/rans_bit_decoder.h b/third-party/draco/src/draco/compression/bit_coders/rans_bit_decoder.h new file mode 100644 index 0000000000..25d243eac1 --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/rans_bit_decoder.h @@ -0,0 +1,55 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// File provides basic classes and functions for rANS coding. +#ifndef DRACO_COMPRESSION_BIT_CODERS_RANS_BIT_DECODER_H_ +#define DRACO_COMPRESSION_BIT_CODERS_RANS_BIT_DECODER_H_ + +#include + +#include "draco/compression/entropy/ans.h" +#include "draco/core/decoder_buffer.h" +#include "draco/draco_features.h" + +namespace draco { + +// Class for decoding a sequence of bits that were encoded with RAnsBitEncoder. +class RAnsBitDecoder { + public: + RAnsBitDecoder(); + ~RAnsBitDecoder(); + + // Sets |source_buffer| as the buffer to decode bits from. + // Returns false when the data is invalid. + bool StartDecoding(DecoderBuffer *source_buffer); + + // Decode one bit. Returns true if the bit is a 1, otherwise false. + bool DecodeNextBit(); + + // Decode the next |nbits| and return the sequence in |value|. |nbits| must be + // > 0 and <= 32. + void DecodeLeastSignificantBits32(int nbits, uint32_t *value); + + void EndDecoding() {} + + private: + void Clear(); + + AnsDecoder ans_decoder_; + uint8_t prob_zero_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_BIT_CODERS_RANS_BIT_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/bit_coders/rans_bit_encoder.cc b/third-party/draco/src/draco/compression/bit_coders/rans_bit_encoder.cc new file mode 100644 index 0000000000..8d00ea3529 --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/rans_bit_encoder.cc @@ -0,0 +1,125 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/bit_coders/rans_bit_encoder.h" + +#include "draco/compression/entropy/ans.h" +#include "draco/core/bit_utils.h" +#include "draco/core/varint_encoding.h" + +namespace draco { + +RAnsBitEncoder::RAnsBitEncoder() : local_bits_(0), num_local_bits_(0) {} + +RAnsBitEncoder::~RAnsBitEncoder() { Clear(); } + +void RAnsBitEncoder::StartEncoding() { Clear(); } + +void RAnsBitEncoder::EncodeBit(bool bit) { + if (bit) { + bit_counts_[1]++; + local_bits_ |= 1 << num_local_bits_; + } else { + bit_counts_[0]++; + } + num_local_bits_++; + + if (num_local_bits_ == 32) { + bits_.push_back(local_bits_); + num_local_bits_ = 0; + local_bits_ = 0; + } +} + +void RAnsBitEncoder::EncodeLeastSignificantBits32(int nbits, uint32_t value) { + DRACO_DCHECK_EQ(true, nbits <= 32); + DRACO_DCHECK_EQ(true, nbits > 0); + + const uint32_t reversed = ReverseBits32(value) >> (32 - nbits); + const int ones = CountOneBits32(reversed); + bit_counts_[0] += (nbits - ones); + bit_counts_[1] += ones; + + const int remaining = 32 - num_local_bits_; + + if (nbits <= remaining) { + CopyBits32(&local_bits_, num_local_bits_, reversed, 0, nbits); + num_local_bits_ += nbits; + if (num_local_bits_ == 32) { + bits_.push_back(local_bits_); + local_bits_ = 0; + num_local_bits_ = 0; + } + } else { + CopyBits32(&local_bits_, num_local_bits_, reversed, 0, remaining); + bits_.push_back(local_bits_); + local_bits_ = 0; + CopyBits32(&local_bits_, 0, reversed, remaining, nbits - remaining); + num_local_bits_ = nbits - remaining; + } +} + +void RAnsBitEncoder::EndEncoding(EncoderBuffer *target_buffer) { + uint64_t total = bit_counts_[1] + bit_counts_[0]; + if (total == 0) { + total++; + } + + // The probability interval [0,1] is mapped to values of [0, 256]. However, + // the coding scheme can not deal with probabilities of 0 or 1, which is why + // we must clamp the values to interval [1, 255]. Specifically 128 + // corresponds to 0.5 exactly. And the value can be given as uint8_t. + const uint32_t zero_prob_raw = static_cast( + ((bit_counts_[0] / static_cast(total)) * 256.0) + 0.5); + + uint8_t zero_prob = 255; + if (zero_prob_raw < 255) { + zero_prob = static_cast(zero_prob_raw); + } + + zero_prob += (zero_prob == 0); + + // Space for 32 bit integer and some extra space. + std::vector buffer((bits_.size() + 8) * 8); + AnsCoder ans_coder; + ans_write_init(&ans_coder, buffer.data()); + + for (int i = num_local_bits_ - 1; i >= 0; --i) { + const uint8_t bit = (local_bits_ >> i) & 1; + rabs_write(&ans_coder, bit, zero_prob); + } + for (auto it = bits_.rbegin(); it != bits_.rend(); ++it) { + const uint32_t bits = *it; + for (int i = 31; i >= 0; --i) { + const uint8_t bit = (bits >> i) & 1; + rabs_write(&ans_coder, bit, zero_prob); + } + } + + const int size_in_bytes = ans_write_end(&ans_coder); + target_buffer->Encode(zero_prob); + EncodeVarint(static_cast(size_in_bytes), target_buffer); + target_buffer->Encode(buffer.data(), size_in_bytes); + + Clear(); +} + +void RAnsBitEncoder::Clear() { + bit_counts_.assign(2, 0); + bits_.clear(); + local_bits_ = 0; + num_local_bits_ = 0; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/bit_coders/rans_bit_encoder.h b/third-party/draco/src/draco/compression/bit_coders/rans_bit_encoder.h new file mode 100644 index 0000000000..1993dd3d3c --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/rans_bit_encoder.h @@ -0,0 +1,57 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// File provides basic classes and functions for rANS coding. +#ifndef DRACO_COMPRESSION_BIT_CODERS_RANS_BIT_ENCODER_H_ +#define DRACO_COMPRESSION_BIT_CODERS_RANS_BIT_ENCODER_H_ + +#include + +#include "draco/core/encoder_buffer.h" + +namespace draco { + +// Class for encoding a sequence of bits using rANS. The probability table used +// to encode the bits is based off the total counts of bits. +// TODO(fgalligan): Investigate using an adaptive table for more compression. +class RAnsBitEncoder { + public: + RAnsBitEncoder(); + ~RAnsBitEncoder(); + + // Must be called before any Encode* function is called. + void StartEncoding(); + + // Encode one bit. If |bit| is true encode a 1, otherwise encode a 0. + void EncodeBit(bool bit); + + // Encode |nbits| of |value|, starting from the least significant bit. + // |nbits| must be > 0 and <= 32. + void EncodeLeastSignificantBits32(int nbits, uint32_t value); + + // Ends the bit encoding and stores the result into the target_buffer. + void EndEncoding(EncoderBuffer *target_buffer); + + private: + void Clear(); + + std::vector bit_counts_; + std::vector bits_; + uint32_t local_bits_; + uint32_t num_local_bits_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_BIT_CODERS_RANS_BIT_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/bit_coders/rans_coding_test.cc b/third-party/draco/src/draco/compression/bit_coders/rans_coding_test.cc new file mode 100644 index 0000000000..9509ad9f35 --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/rans_coding_test.cc @@ -0,0 +1,9 @@ +#include "draco/compression/bit_coders/adaptive_rans_bit_decoder.h" +#include "draco/compression/bit_coders/adaptive_rans_bit_encoder.h" +#include "draco/compression/bit_coders/rans_bit_decoder.h" +#include "draco/compression/bit_coders/rans_bit_encoder.h" +#include "draco/core/draco_test_base.h" + +// Just including rans_coding.h and adaptive_rans_coding.h gets an asan error +// when compiling (blaze test :rans_coding_test --config=asan) +TEST(RansCodingTest, LinkerTest) {} diff --git a/third-party/draco/src/draco/compression/bit_coders/symbol_bit_decoder.cc b/third-party/draco/src/draco/compression/bit_coders/symbol_bit_decoder.cc new file mode 100644 index 0000000000..8ed50ef92e --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/symbol_bit_decoder.cc @@ -0,0 +1,49 @@ +#include "draco/compression/bit_coders/symbol_bit_decoder.h" + +#include "draco/compression/entropy/symbol_decoding.h" + +namespace draco { + +bool SymbolBitDecoder::StartDecoding(DecoderBuffer *source_buffer) { + uint32_t size; + if (!source_buffer->Decode(&size)) { + return false; + } + + symbols_.resize(size); + if (!DecodeSymbols(size, 1, source_buffer, symbols_.data())) { + return false; + } + std::reverse(symbols_.begin(), symbols_.end()); + return true; +} + +bool SymbolBitDecoder::DecodeNextBit() { + uint32_t symbol; + DecodeLeastSignificantBits32(1, &symbol); + DRACO_DCHECK(symbol == 0 || symbol == 1); + return symbol == 1; +} + +void SymbolBitDecoder::DecodeLeastSignificantBits32(int nbits, + uint32_t *value) { + DRACO_DCHECK_LE(1, nbits); + DRACO_DCHECK_LE(nbits, 32); + DRACO_DCHECK_NE(value, nullptr); + // Testing: check to make sure there is something to decode. + DRACO_DCHECK_GT(symbols_.size(), 0); + + (*value) = symbols_.back(); + symbols_.pop_back(); + + const int discarded_bits = 32 - nbits; + (*value) <<= discarded_bits; + (*value) >>= discarded_bits; +} + +void SymbolBitDecoder::Clear() { + symbols_.clear(); + symbols_.shrink_to_fit(); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/bit_coders/symbol_bit_decoder.h b/third-party/draco/src/draco/compression/bit_coders/symbol_bit_decoder.h new file mode 100644 index 0000000000..909d7174fb --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/symbol_bit_decoder.h @@ -0,0 +1,36 @@ +#ifndef DRACO_COMPRESSION_BIT_CODERS_SYMBOL_BIT_DECODER_H_ +#define DRACO_COMPRESSION_BIT_CODERS_SYMBOL_BIT_DECODER_H_ + +#include +#include + +#include "draco/core/decoder_buffer.h" + +namespace draco { + +// Class for decoding bits using the symbol entropy encoding. Wraps +// |DecodeSymbols|. Note that this uses a symbol-based encoding scheme for +// encoding bits. +class SymbolBitDecoder { + public: + // Sets |source_buffer| as the buffer to decode bits from. + bool StartDecoding(DecoderBuffer *source_buffer); + + // Decode one bit. Returns true if the bit is a 1, otherwise false. + bool DecodeNextBit(); + + // Decode the next |nbits| and return the sequence in |value|. |nbits| must be + // > 0 and <= 32. + void DecodeLeastSignificantBits32(int nbits, uint32_t *value); + + void EndDecoding() { Clear(); } + + private: + void Clear(); + + std::vector symbols_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_BIT_CODERS_SYMBOL_BIT_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/bit_coders/symbol_bit_encoder.cc b/third-party/draco/src/draco/compression/bit_coders/symbol_bit_encoder.cc new file mode 100644 index 0000000000..83834236fa --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/symbol_bit_encoder.cc @@ -0,0 +1,30 @@ +#include "draco/compression/bit_coders/symbol_bit_encoder.h" + +#include "draco/compression/entropy/symbol_encoding.h" + +namespace draco { + +void SymbolBitEncoder::EncodeLeastSignificantBits32(int nbits, uint32_t value) { + DRACO_DCHECK_LE(1, nbits); + DRACO_DCHECK_LE(nbits, 32); + + const int discarded_bits = 32 - nbits; + value <<= discarded_bits; + value >>= discarded_bits; + + symbols_.push_back(value); +} + +void SymbolBitEncoder::EndEncoding(EncoderBuffer *target_buffer) { + target_buffer->Encode(static_cast(symbols_.size())); + EncodeSymbols(symbols_.data(), static_cast(symbols_.size()), 1, nullptr, + target_buffer); + Clear(); +} + +void SymbolBitEncoder::Clear() { + symbols_.clear(); + symbols_.shrink_to_fit(); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/bit_coders/symbol_bit_encoder.h b/third-party/draco/src/draco/compression/bit_coders/symbol_bit_encoder.h new file mode 100644 index 0000000000..7f1570c1a7 --- /dev/null +++ b/third-party/draco/src/draco/compression/bit_coders/symbol_bit_encoder.h @@ -0,0 +1,36 @@ +#ifndef DRACO_COMPRESSION_BIT_CODERS_SYMBOL_BIT_ENCODER_H_ +#define DRACO_COMPRESSION_BIT_CODERS_SYMBOL_BIT_ENCODER_H_ + +#include +#include + +#include "draco/core/encoder_buffer.h" + +namespace draco { + +// Class for encoding bits using the symbol entropy encoding. Wraps +// |EncodeSymbols|. Note that this uses a symbol-based encoding scheme for +// encoding bits. +class SymbolBitEncoder { + public: + // Must be called before any Encode* function is called. + void StartEncoding() { Clear(); } + + // Encode one bit. If |bit| is true encode a 1, otherwise encode a 0. + void EncodeBit(bool bit) { EncodeLeastSignificantBits32(1, bit ? 1 : 0); } + + // Encode |nbits| LSBs of |value| as a symbol. |nbits| must be > 0 and <= 32. + void EncodeLeastSignificantBits32(int nbits, uint32_t value); + + // Ends the bit encoding and stores the result into the target_buffer. + void EndEncoding(EncoderBuffer *target_buffer); + + private: + void Clear(); + + std::vector symbols_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_BIT_CODERS_SYMBOL_BIT_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/config/compression_shared.h b/third-party/draco/src/draco/compression/config/compression_shared.h new file mode 100644 index 0000000000..c43f303bd1 --- /dev/null +++ b/third-party/draco/src/draco/compression/config/compression_shared.h @@ -0,0 +1,155 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_CONFIG_COMPRESSION_SHARED_H_ +#define DRACO_COMPRESSION_CONFIG_COMPRESSION_SHARED_H_ + +#include + +#include "draco/core/macros.h" +#include "draco/draco_features.h" + +namespace draco { + +// Latest Draco bit-stream version. +static constexpr uint8_t kDracoPointCloudBitstreamVersionMajor = 2; +static constexpr uint8_t kDracoPointCloudBitstreamVersionMinor = 3; +static constexpr uint8_t kDracoMeshBitstreamVersionMajor = 2; +static constexpr uint8_t kDracoMeshBitstreamVersionMinor = 2; + +// Concatenated latest bit-stream version. +static constexpr uint16_t kDracoPointCloudBitstreamVersion = + DRACO_BITSTREAM_VERSION(kDracoPointCloudBitstreamVersionMajor, + kDracoPointCloudBitstreamVersionMinor); + +static constexpr uint16_t kDracoMeshBitstreamVersion = DRACO_BITSTREAM_VERSION( + kDracoMeshBitstreamVersionMajor, kDracoMeshBitstreamVersionMinor); + +// Currently, we support point cloud and triangular mesh encoding. +// TODO(draco-eng) Convert enum to enum class (safety, not performance). +enum EncodedGeometryType { + INVALID_GEOMETRY_TYPE = -1, + POINT_CLOUD = 0, + TRIANGULAR_MESH, + NUM_ENCODED_GEOMETRY_TYPES +}; + +// List of encoding methods for point clouds. +enum PointCloudEncodingMethod { + POINT_CLOUD_SEQUENTIAL_ENCODING = 0, + POINT_CLOUD_KD_TREE_ENCODING +}; + +// List of encoding methods for meshes. +enum MeshEncoderMethod { + MESH_SEQUENTIAL_ENCODING = 0, + MESH_EDGEBREAKER_ENCODING, +}; + +// List of various attribute encoders supported by our framework. The entries +// are used as unique identifiers of the encoders and their values should not +// be changed! +enum AttributeEncoderType { + BASIC_ATTRIBUTE_ENCODER = 0, + MESH_TRAVERSAL_ATTRIBUTE_ENCODER, + KD_TREE_ATTRIBUTE_ENCODER, +}; + +// List of various sequential attribute encoder/decoders that can be used in our +// pipeline. The values represent unique identifiers used by the decoder and +// they should not be changed. +enum SequentialAttributeEncoderType { + SEQUENTIAL_ATTRIBUTE_ENCODER_GENERIC = 0, + SEQUENTIAL_ATTRIBUTE_ENCODER_INTEGER, + SEQUENTIAL_ATTRIBUTE_ENCODER_QUANTIZATION, + SEQUENTIAL_ATTRIBUTE_ENCODER_NORMALS, +}; + +// List of all prediction methods currently supported by our framework. +enum PredictionSchemeMethod { + // Special value indicating that no prediction scheme was used. + PREDICTION_NONE = -2, + // Used when no specific prediction scheme is required. + PREDICTION_UNDEFINED = -1, + PREDICTION_DIFFERENCE = 0, + MESH_PREDICTION_PARALLELOGRAM = 1, + MESH_PREDICTION_MULTI_PARALLELOGRAM = 2, + MESH_PREDICTION_TEX_COORDS_DEPRECATED = 3, + MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM = 4, + MESH_PREDICTION_TEX_COORDS_PORTABLE = 5, + MESH_PREDICTION_GEOMETRIC_NORMAL = 6, + NUM_PREDICTION_SCHEMES +}; + +// List of all prediction scheme transforms used by our framework. +enum PredictionSchemeTransformType { + PREDICTION_TRANSFORM_NONE = -1, + // Basic delta transform where the prediction is computed as difference the + // predicted and original value. + PREDICTION_TRANSFORM_DELTA = 0, + // An improved delta transform where all computed delta values are wrapped + // around a fixed interval which lowers the entropy. + PREDICTION_TRANSFORM_WRAP = 1, + // Specialized transform for normal coordinates using inverted tiles. + PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON = 2, + // Specialized transform for normal coordinates using canonicalized inverted + // tiles. + PREDICTION_TRANSFORM_NORMAL_OCTAHEDRON_CANONICALIZED = 3, + // The number of valid (non-negative) prediction scheme transform types. + NUM_PREDICTION_SCHEME_TRANSFORM_TYPES +}; + +// List of all mesh traversal methods supported by Draco framework. +enum MeshTraversalMethod { + MESH_TRAVERSAL_DEPTH_FIRST = 0, + MESH_TRAVERSAL_PREDICTION_DEGREE = 1, + NUM_TRAVERSAL_METHODS +}; + +// List of all variant of the edgebreaker method that is used for compression +// of mesh connectivity. +enum MeshEdgebreakerConnectivityEncodingMethod { + MESH_EDGEBREAKER_STANDARD_ENCODING = 0, + MESH_EDGEBREAKER_PREDICTIVE_ENCODING = 1, // Deprecated. + MESH_EDGEBREAKER_VALENCE_ENCODING = 2, +}; + +// Draco header V1 +struct DracoHeader { + int8_t draco_string[5]; + uint8_t version_major; + uint8_t version_minor; + uint8_t encoder_type; + uint8_t encoder_method; + uint16_t flags; +}; + +enum NormalPredictionMode { + ONE_TRIANGLE = 0, // To be deprecated. + TRIANGLE_AREA = 1, +}; + +// Different methods used for symbol entropy encoding. +enum SymbolCodingMethod { + SYMBOL_CODING_TAGGED = 0, + SYMBOL_CODING_RAW = 1, + NUM_SYMBOL_CODING_METHODS, +}; + +// Mask for setting and getting the bit for metadata in |flags| of header. +#define METADATA_FLAG_MASK 0x8000 + +} // namespace draco + +#endif // DRACO_COMPRESSION_CONFIG_COMPRESSION_SHARED_H_ diff --git a/third-party/draco/src/draco/compression/config/decoder_options.h b/third-party/draco/src/draco/compression/config/decoder_options.h new file mode 100644 index 0000000000..3b3889993e --- /dev/null +++ b/third-party/draco/src/draco/compression/config/decoder_options.h @@ -0,0 +1,34 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_CONFIG_DECODER_OPTIONS_H_ +#define DRACO_COMPRESSION_CONFIG_DECODER_OPTIONS_H_ + +#include +#include + +#include "draco/attributes/geometry_attribute.h" +#include "draco/compression/config/draco_options.h" + +namespace draco { + +// Class containing options that can be passed to PointCloudDecoder to control +// decoding of the input geometry. The options can be specified either for the +// whole geometry or for a specific attribute type. Each option is identified +// by a unique name stored as an std::string. +typedef DracoOptions DecoderOptions; + +} // namespace draco + +#endif // DRACO_COMPRESSION_CONFIG_DECODER_OPTIONS_H_ diff --git a/third-party/draco/src/draco/compression/config/decoder_options_test.cc b/third-party/draco/src/draco/compression/config/decoder_options_test.cc new file mode 100644 index 0000000000..a5cd7f1064 --- /dev/null +++ b/third-party/draco/src/draco/compression/config/decoder_options_test.cc @@ -0,0 +1,67 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/config/decoder_options.h" + +#include "draco/core/draco_test_base.h" + +namespace { + +class DecoderOptionsTest : public ::testing::Test { + protected: + DecoderOptionsTest() {} +}; + +TEST_F(DecoderOptionsTest, TestOptions) { + // This test verifies that we can update global and attribute options of the + // DecoderOptions class instance. + draco::DecoderOptions options; + options.SetGlobalInt("test", 3); + ASSERT_EQ(options.GetGlobalInt("test", -1), 3); + + options.SetAttributeInt(draco::GeometryAttribute::POSITION, "test", 1); + options.SetAttributeInt(draco::GeometryAttribute::GENERIC, "test", 2); + ASSERT_EQ( + options.GetAttributeInt(draco::GeometryAttribute::TEX_COORD, "test", -1), + 3); + ASSERT_EQ( + options.GetAttributeInt(draco::GeometryAttribute::POSITION, "test", -1), + 1); + ASSERT_EQ( + options.GetAttributeInt(draco::GeometryAttribute::GENERIC, "test", -1), + 2); +} + +TEST_F(DecoderOptionsTest, TestAttributeOptionsAccessors) { + // This test verifies that we can query options stored in DecoderOptions + // class instance. + draco::DecoderOptions options; + options.SetGlobalInt("test", 1); + options.SetAttributeInt(draco::GeometryAttribute::POSITION, "test", 2); + options.SetAttributeInt(draco::GeometryAttribute::TEX_COORD, "test", 3); + + ASSERT_EQ( + options.GetAttributeInt(draco::GeometryAttribute::POSITION, "test", -1), + 2); + ASSERT_EQ( + options.GetAttributeInt(draco::GeometryAttribute::POSITION, "test2", -1), + -1); + ASSERT_EQ( + options.GetAttributeInt(draco::GeometryAttribute::TEX_COORD, "test", -1), + 3); + ASSERT_EQ( + options.GetAttributeInt(draco::GeometryAttribute::NORMAL, "test", -1), 1); +} + +} // namespace diff --git a/third-party/draco/src/draco/compression/config/draco_options.h b/third-party/draco/src/draco/compression/config/draco_options.h new file mode 100644 index 0000000000..2bd4a3b676 --- /dev/null +++ b/third-party/draco/src/draco/compression/config/draco_options.h @@ -0,0 +1,249 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_CONFIG_DRACO_OPTIONS_H_ +#define DRACO_COMPRESSION_CONFIG_DRACO_OPTIONS_H_ + +#include +#include + +#include "draco/core/options.h" + +namespace draco { + +// Base option class used to control encoding and decoding. The geometry coding +// can be controlled through the following options: +// 1. Global options - Options specific to overall geometry or options common +// for all attributes +// 2. Per attribute options - Options specific to a given attribute. +// Each attribute is identified by the template +// argument AttributeKeyT that can be for example +// the attribute type or the attribute id. +// +// Example: +// +// DracoOptions options; +// +// // Set an option common for all attributes. +// options.SetGlobalInt("some_option_name", 2); +// +// // Geometry with two attributes. +// AttributeKey att_key0 = in_key0; +// AttributeKey att_key1 = in_key1; +// +// options.SetAttributeInt(att_key0, "some_option_name", 3); +// +// options.GetAttributeInt(att_key0, "some_option_name"); // Returns 3 +// options.GetAttributeInt(att_key1, "some_option_name"); // Returns 2 +// options.GetGlobalInt("some_option_name"); // Returns 2 +// +template +class DracoOptions { + public: + typedef AttributeKeyT AttributeKey; + + // Get an option for a specific attribute key. If the option is not found in + // an attribute specific storage, the implementation will return a global + // option of the given name (if available). If the option is not found, the + // provided default value |default_val| is returned instead. + int GetAttributeInt(const AttributeKey &att_key, const std::string &name, + int default_val) const; + + // Sets an option for a specific attribute key. + void SetAttributeInt(const AttributeKey &att_key, const std::string &name, + int val); + + float GetAttributeFloat(const AttributeKey &att_key, const std::string &name, + float default_val) const; + void SetAttributeFloat(const AttributeKey &att_key, const std::string &name, + float val); + bool GetAttributeBool(const AttributeKey &att_key, const std::string &name, + bool default_val) const; + void SetAttributeBool(const AttributeKey &att_key, const std::string &name, + bool val); + template + bool GetAttributeVector(const AttributeKey &att_key, const std::string &name, + int num_dims, DataTypeT *val) const; + template + void SetAttributeVector(const AttributeKey &att_key, const std::string &name, + int num_dims, const DataTypeT *val); + + bool IsAttributeOptionSet(const AttributeKey &att_key, + const std::string &name) const; + + // Gets/sets a global option that is not specific to any attribute. + int GetGlobalInt(const std::string &name, int default_val) const { + return global_options_.GetInt(name, default_val); + } + void SetGlobalInt(const std::string &name, int val) { + global_options_.SetInt(name, val); + } + float GetGlobalFloat(const std::string &name, float default_val) const { + return global_options_.GetFloat(name, default_val); + } + void SetGlobalFloat(const std::string &name, float val) { + global_options_.SetFloat(name, val); + } + bool GetGlobalBool(const std::string &name, bool default_val) const { + return global_options_.GetBool(name, default_val); + } + void SetGlobalBool(const std::string &name, bool val) { + global_options_.SetBool(name, val); + } + template + bool GetGlobalVector(const std::string &name, int num_dims, + DataTypeT *val) const { + return global_options_.GetVector(name, num_dims, val); + } + template + void SetGlobalVector(const std::string &name, int num_dims, + const DataTypeT *val) { + global_options_.SetVector(name, val, num_dims); + } + bool IsGlobalOptionSet(const std::string &name) const { + return global_options_.IsOptionSet(name); + } + + // Sets or replaces attribute options with the provided |options|. + void SetAttributeOptions(const AttributeKey &att_key, const Options &options); + void SetGlobalOptions(const Options &options) { global_options_ = options; } + + // Returns |Options| instance for the specified options class if it exists. + const Options *FindAttributeOptions(const AttributeKeyT &att_key) const; + const Options &GetGlobalOptions() const { return global_options_; } + + private: + Options *GetAttributeOptions(const AttributeKeyT &att_key); + + Options global_options_; + + // Storage for options related to geometry attributes. + std::map attribute_options_; +}; + +template +const Options *DracoOptions::FindAttributeOptions( + const AttributeKeyT &att_key) const { + auto it = attribute_options_.find(att_key); + if (it == attribute_options_.end()) { + return nullptr; + } + return &it->second; +} + +template +Options *DracoOptions::GetAttributeOptions( + const AttributeKeyT &att_key) { + auto it = attribute_options_.find(att_key); + if (it != attribute_options_.end()) { + return &it->second; + } + Options new_options; + it = attribute_options_.insert(std::make_pair(att_key, new_options)).first; + return &it->second; +} + +template +int DracoOptions::GetAttributeInt(const AttributeKeyT &att_key, + const std::string &name, + int default_val) const { + const Options *const att_options = FindAttributeOptions(att_key); + if (att_options && att_options->IsOptionSet(name)) { + return att_options->GetInt(name, default_val); + } + return global_options_.GetInt(name, default_val); +} + +template +void DracoOptions::SetAttributeInt(const AttributeKeyT &att_key, + const std::string &name, + int val) { + GetAttributeOptions(att_key)->SetInt(name, val); +} + +template +float DracoOptions::GetAttributeFloat( + const AttributeKeyT &att_key, const std::string &name, + float default_val) const { + const Options *const att_options = FindAttributeOptions(att_key); + if (att_options && att_options->IsOptionSet(name)) { + return att_options->GetFloat(name, default_val); + } + return global_options_.GetFloat(name, default_val); +} + +template +void DracoOptions::SetAttributeFloat( + const AttributeKeyT &att_key, const std::string &name, float val) { + GetAttributeOptions(att_key)->SetFloat(name, val); +} + +template +bool DracoOptions::GetAttributeBool(const AttributeKeyT &att_key, + const std::string &name, + bool default_val) const { + const Options *const att_options = FindAttributeOptions(att_key); + if (att_options && att_options->IsOptionSet(name)) { + return att_options->GetBool(name, default_val); + } + return global_options_.GetBool(name, default_val); +} + +template +void DracoOptions::SetAttributeBool(const AttributeKeyT &att_key, + const std::string &name, + bool val) { + GetAttributeOptions(att_key)->SetBool(name, val); +} + +template +template +bool DracoOptions::GetAttributeVector( + const AttributeKey &att_key, const std::string &name, int num_dims, + DataTypeT *val) const { + const Options *const att_options = FindAttributeOptions(att_key); + if (att_options && att_options->IsOptionSet(name)) { + return att_options->GetVector(name, num_dims, val); + } + return global_options_.GetVector(name, num_dims, val); +} + +template +template +void DracoOptions::SetAttributeVector( + const AttributeKey &att_key, const std::string &name, int num_dims, + const DataTypeT *val) { + GetAttributeOptions(att_key)->SetVector(name, val, num_dims); +} + +template +bool DracoOptions::IsAttributeOptionSet( + const AttributeKey &att_key, const std::string &name) const { + const Options *const att_options = FindAttributeOptions(att_key); + if (att_options) { + return att_options->IsOptionSet(name); + } + return global_options_.IsOptionSet(name); +} + +template +void DracoOptions::SetAttributeOptions( + const AttributeKey &att_key, const Options &options) { + Options *att_options = GetAttributeOptions(att_key); + *att_options = options; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_CONFIG_DRACO_OPTIONS_H_ diff --git a/third-party/draco/src/draco/compression/config/encoder_options.h b/third-party/draco/src/draco/compression/config/encoder_options.h new file mode 100644 index 0000000000..e8a55bbba5 --- /dev/null +++ b/third-party/draco/src/draco/compression/config/encoder_options.h @@ -0,0 +1,101 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_CONFIG_ENCODER_OPTIONS_H_ +#define DRACO_COMPRESSION_CONFIG_ENCODER_OPTIONS_H_ + +#include "draco/attributes/geometry_attribute.h" +#include "draco/compression/config/draco_options.h" +#include "draco/compression/config/encoding_features.h" +#include "draco/draco_features.h" + +namespace draco { + +// EncoderOptions allow users to specify so called feature options that are used +// to inform the encoder which encoding features can be used (i.e. which +// features are going to be available to the decoder). +template +class EncoderOptionsBase : public DracoOptions { + public: + static EncoderOptionsBase CreateDefaultOptions() { + EncoderOptionsBase options; +#ifdef DRACO_STANDARD_EDGEBREAKER_SUPPORTED + options.SetSupportedFeature(features::kEdgebreaker, true); +#endif +#ifdef DRACO_PREDICTIVE_EDGEBREAKER_SUPPORTED + options.SetSupportedFeature(features::kPredictiveEdgebreaker, true); +#endif + return options; + } + static EncoderOptionsBase CreateEmptyOptions() { + return EncoderOptionsBase(); + } + + // Returns speed options with default value of 5. + int GetEncodingSpeed() const { + return this->GetGlobalInt("encoding_speed", 5); + } + int GetDecodingSpeed() const { + return this->GetGlobalInt("decoding_speed", 5); + } + + // Returns the maximum speed for both encoding/decoding. + int GetSpeed() const { + const int encoding_speed = this->GetGlobalInt("encoding_speed", -1); + const int decoding_speed = this->GetGlobalInt("decoding_speed", -1); + const int max_speed = std::max(encoding_speed, decoding_speed); + if (max_speed == -1) { + return 5; // Default value. + } + return max_speed; + } + + void SetSpeed(int encoding_speed, int decoding_speed) { + this->SetGlobalInt("encoding_speed", encoding_speed); + this->SetGlobalInt("decoding_speed", decoding_speed); + } + bool IsSpeedSet() const { + return this->IsGlobalOptionSet("encoding_speed") || + this->IsGlobalOptionSet("decoding_speed"); + } + + // Sets a given feature as supported or unsupported by the target decoder. + // Encoder will always use only supported features when encoding the input + // geometry. + void SetSupportedFeature(const std::string &name, bool supported) { + feature_options_.SetBool(name, supported); + } + bool IsFeatureSupported(const std::string &name) const { + return feature_options_.GetBool(name); + } + + void SetFeatureOptions(const Options &options) { feature_options_ = options; } + const Options &GetFeaturelOptions() const { return feature_options_; } + + private: + // Use helper methods to construct the encoder options. + // See CreateDefaultOptions(); + EncoderOptionsBase() {} + + // List of supported/unsupported features that can be used by the encoder. + Options feature_options_; +}; + +// Encoder options where attributes are identified by their attribute id. +// Used to set options that are specific to a given geometry. +typedef EncoderOptionsBase EncoderOptions; + +} // namespace draco + +#endif // DRACO_COMPRESSION_CONFIG_ENCODER_OPTIONS_H_ diff --git a/third-party/draco/src/draco/compression/config/encoding_features.h b/third-party/draco/src/draco/compression/config/encoding_features.h new file mode 100644 index 0000000000..d6a8b7128a --- /dev/null +++ b/third-party/draco/src/draco/compression/config/encoding_features.h @@ -0,0 +1,39 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// File provides helpful macros that define features available for encoding +// the input of the input geometry. These macros can be used as an input in +// the EncoderOptions::SetSupportedFeature() method instead of the text. +// The most recent set of features supported +// by the default implementation is: +// +// kEdgebreaker +// - edgebreaker method for encoding meshes. +// kPredictiveEdgebreaker +// - advanced version of the edgebreaker method (slower but better +// compression). +// +#ifndef DRACO_COMPRESSION_CONFIG_ENCODING_FEATURES_H_ +#define DRACO_COMPRESSION_CONFIG_ENCODING_FEATURES_H_ + +namespace draco { +namespace features { + +constexpr const char *kEdgebreaker = "standard_edgebreaker"; +constexpr const char *kPredictiveEdgebreaker = "predictive_edgebreaker"; + +} // namespace features +} // namespace draco + +#endif // DRACO_COMPRESSION_CONFIG_ENCODING_FEATURES_H_ diff --git a/third-party/draco/src/draco/compression/decode.cc b/third-party/draco/src/draco/compression/decode.cc new file mode 100644 index 0000000000..92ae4ff66f --- /dev/null +++ b/third-party/draco/src/draco/compression/decode.cc @@ -0,0 +1,135 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/decode.h" + +#include "draco/compression/config/compression_shared.h" + +#ifdef DRACO_MESH_COMPRESSION_SUPPORTED +#include "draco/compression/mesh/mesh_edgebreaker_decoder.h" +#include "draco/compression/mesh/mesh_sequential_decoder.h" +#endif + +#ifdef DRACO_POINT_CLOUD_COMPRESSION_SUPPORTED +#include "draco/compression/point_cloud/point_cloud_kd_tree_decoder.h" +#include "draco/compression/point_cloud/point_cloud_sequential_decoder.h" +#endif + +namespace draco { + +#ifdef DRACO_POINT_CLOUD_COMPRESSION_SUPPORTED +StatusOr> CreatePointCloudDecoder( + int8_t method) { + if (method == POINT_CLOUD_SEQUENTIAL_ENCODING) { + return std::unique_ptr( + new PointCloudSequentialDecoder()); + } else if (method == POINT_CLOUD_KD_TREE_ENCODING) { + return std::unique_ptr(new PointCloudKdTreeDecoder()); + } + return Status(Status::DRACO_ERROR, "Unsupported encoding method."); +} +#endif + +#ifdef DRACO_MESH_COMPRESSION_SUPPORTED +StatusOr> CreateMeshDecoder(uint8_t method) { + if (method == MESH_SEQUENTIAL_ENCODING) { + return std::unique_ptr(new MeshSequentialDecoder()); + } else if (method == MESH_EDGEBREAKER_ENCODING) { + return std::unique_ptr(new MeshEdgebreakerDecoder()); + } + return Status(Status::DRACO_ERROR, "Unsupported encoding method."); +} +#endif + +StatusOr Decoder::GetEncodedGeometryType( + DecoderBuffer *in_buffer) { + DecoderBuffer temp_buffer(*in_buffer); + DracoHeader header; + DRACO_RETURN_IF_ERROR(PointCloudDecoder::DecodeHeader(&temp_buffer, &header)); + if (header.encoder_type >= NUM_ENCODED_GEOMETRY_TYPES) { + return Status(Status::DRACO_ERROR, "Unsupported geometry type."); + } + return static_cast(header.encoder_type); +} + +StatusOr> Decoder::DecodePointCloudFromBuffer( + DecoderBuffer *in_buffer) { + DRACO_ASSIGN_OR_RETURN(EncodedGeometryType type, + GetEncodedGeometryType(in_buffer)) + if (type == POINT_CLOUD) { +#ifdef DRACO_POINT_CLOUD_COMPRESSION_SUPPORTED + std::unique_ptr point_cloud(new PointCloud()); + DRACO_RETURN_IF_ERROR(DecodeBufferToGeometry(in_buffer, point_cloud.get())) + return std::move(point_cloud); +#endif + } else if (type == TRIANGULAR_MESH) { +#ifdef DRACO_MESH_COMPRESSION_SUPPORTED + std::unique_ptr mesh(new Mesh()); + DRACO_RETURN_IF_ERROR(DecodeBufferToGeometry(in_buffer, mesh.get())) + return static_cast>(std::move(mesh)); +#endif + } + return Status(Status::DRACO_ERROR, "Unsupported geometry type."); +} + +StatusOr> Decoder::DecodeMeshFromBuffer( + DecoderBuffer *in_buffer) { + std::unique_ptr mesh(new Mesh()); + DRACO_RETURN_IF_ERROR(DecodeBufferToGeometry(in_buffer, mesh.get())) + return std::move(mesh); +} + +Status Decoder::DecodeBufferToGeometry(DecoderBuffer *in_buffer, + PointCloud *out_geometry) { +#ifdef DRACO_POINT_CLOUD_COMPRESSION_SUPPORTED + DecoderBuffer temp_buffer(*in_buffer); + DracoHeader header; + DRACO_RETURN_IF_ERROR(PointCloudDecoder::DecodeHeader(&temp_buffer, &header)) + if (header.encoder_type != POINT_CLOUD) { + return Status(Status::DRACO_ERROR, "Input is not a point cloud."); + } + DRACO_ASSIGN_OR_RETURN(std::unique_ptr decoder, + CreatePointCloudDecoder(header.encoder_method)) + + DRACO_RETURN_IF_ERROR(decoder->Decode(options_, in_buffer, out_geometry)) + return OkStatus(); +#else + return Status(Status::DRACO_ERROR, "Unsupported geometry type."); +#endif +} + +Status Decoder::DecodeBufferToGeometry(DecoderBuffer *in_buffer, + Mesh *out_geometry) { +#ifdef DRACO_MESH_COMPRESSION_SUPPORTED + DecoderBuffer temp_buffer(*in_buffer); + DracoHeader header; + DRACO_RETURN_IF_ERROR(PointCloudDecoder::DecodeHeader(&temp_buffer, &header)) + if (header.encoder_type != TRIANGULAR_MESH) { + return Status(Status::DRACO_ERROR, "Input is not a mesh."); + } + DRACO_ASSIGN_OR_RETURN(std::unique_ptr decoder, + CreateMeshDecoder(header.encoder_method)) + + DRACO_RETURN_IF_ERROR(decoder->Decode(options_, in_buffer, out_geometry)) + return OkStatus(); +#else + return Status(Status::DRACO_ERROR, "Unsupported geometry type."); +#endif +} + +void Decoder::SetSkipAttributeTransform(GeometryAttribute::Type att_type) { + options_.SetAttributeBool(att_type, "skip_attribute_transform", true); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/decode.h b/third-party/draco/src/draco/compression/decode.h new file mode 100644 index 0000000000..5f3fad26bb --- /dev/null +++ b/third-party/draco/src/draco/compression/decode.h @@ -0,0 +1,80 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_DECODE_H_ +#define DRACO_COMPRESSION_DECODE_H_ + +#include "draco/compression/config/compression_shared.h" +#include "draco/compression/config/decoder_options.h" +#include "draco/core/decoder_buffer.h" +#include "draco/core/status_or.h" +#include "draco/draco_features.h" +#include "draco/mesh/mesh.h" + +namespace draco { + +// Class responsible for decoding of meshes and point clouds that were +// compressed by a Draco encoder. +class Decoder { + public: + // Returns the geometry type encoded in the input |in_buffer|. + // The return value is one of POINT_CLOUD, MESH or INVALID_GEOMETRY in case + // the input data is invalid. + // The decoded geometry type can be used to choose an appropriate decoding + // function for a given geometry type (see below). + static StatusOr GetEncodedGeometryType( + DecoderBuffer *in_buffer); + + // Decodes point cloud from the provided buffer. The buffer must be filled + // with data that was encoded with either the EncodePointCloudToBuffer or + // EncodeMeshToBuffer methods in encode.h. In case the input buffer contains + // mesh, the returned instance can be down-casted to Mesh. + StatusOr> DecodePointCloudFromBuffer( + DecoderBuffer *in_buffer); + + // Decodes a triangular mesh from the provided buffer. The mesh must be filled + // with data that was encoded using the EncodeMeshToBuffer method in encode.h. + // The function will return nullptr in case the input is invalid or if it was + // encoded with the EncodePointCloudToBuffer method. + StatusOr> DecodeMeshFromBuffer( + DecoderBuffer *in_buffer); + + // Decodes the buffer into a provided geometry. If the geometry is + // incompatible with the encoded data. For example, when |out_geometry| is + // draco::Mesh while the data contains a point cloud, the function will return + // an error status. + Status DecodeBufferToGeometry(DecoderBuffer *in_buffer, + PointCloud *out_geometry); + Status DecodeBufferToGeometry(DecoderBuffer *in_buffer, Mesh *out_geometry); + + // When set, the decoder is going to skip attribute transform for a given + // attribute type. For example for quantized attributes, the decoder would + // skip the dequantization step and the returned geometry would contain an + // attribute with quantized values. The attribute would also contain an + // instance of AttributeTransform class that is used to describe the skipped + // transform, including all parameters that are needed to perform the + // transform manually. + void SetSkipAttributeTransform(GeometryAttribute::Type att_type); + + // Returns the options instance used by the decoder that can be used by users + // to control the decoding process. + DecoderOptions *options() { return &options_; } + + private: + DecoderOptions options_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_DECODE_H_ diff --git a/third-party/draco/src/draco/compression/decode_test.cc b/third-party/draco/src/draco/compression/decode_test.cc new file mode 100644 index 0000000000..8f3e7f4e98 --- /dev/null +++ b/third-party/draco/src/draco/compression/decode_test.cc @@ -0,0 +1,245 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/decode.h" + +#include +#include + +#include "draco/compression/encode.h" +#include "draco/core/draco_test_base.h" +#include "draco/core/draco_test_utils.h" +#include "draco/io/file_utils.h" +#include "draco/io/obj_encoder.h" + +namespace { + +class DecodeTest : public ::testing::Test { + protected: + DecodeTest() {} +}; + +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED +TEST_F(DecodeTest, TestSkipAttributeTransform) { + const std::string file_name = "test_nm_quant.0.9.0.drc"; + // Tests that decoders can successfully skip attribute transform. + std::vector data; + ASSERT_TRUE( + draco::ReadFileToBuffer(draco::GetTestFileFullPath(file_name), &data)); + ASSERT_FALSE(data.empty()); + + // Create a draco decoding buffer. Note that no data is copied in this step. + draco::DecoderBuffer buffer; + buffer.Init(data.data(), data.size()); + + draco::Decoder decoder; + // Make sure we skip dequantization for the position attribute. + decoder.SetSkipAttributeTransform(draco::GeometryAttribute::POSITION); + + // Decode the input data into a geometry. + std::unique_ptr pc = + decoder.DecodePointCloudFromBuffer(&buffer).value(); + ASSERT_NE(pc, nullptr); + + const draco::PointAttribute *const pos_att = + pc->GetNamedAttribute(draco::GeometryAttribute::POSITION); + ASSERT_NE(pos_att, nullptr); + + // Ensure the position attribute is of type int32_t and that it has a valid + // attribute transform. + ASSERT_EQ(pos_att->data_type(), draco::DT_INT32); + ASSERT_NE(pos_att->GetAttributeTransformData(), nullptr); + + // Normal attribute should be left transformed. + const draco::PointAttribute *const norm_att = + pc->GetNamedAttribute(draco::GeometryAttribute::NORMAL); + ASSERT_EQ(norm_att->data_type(), draco::DT_FLOAT32); + ASSERT_EQ(norm_att->GetAttributeTransformData(), nullptr); +} +#endif + +void TestSkipAttributeTransformOnPointCloudWithColor(const std::string &file) { + std::vector data; + ASSERT_TRUE(draco::ReadFileToBuffer(draco::GetTestFileFullPath(file), &data)); + ASSERT_FALSE(data.empty()); + + // Create a draco decoding buffer. Note that no data is copied in this step. + draco::DecoderBuffer buffer; + buffer.Init(data.data(), data.size()); + + draco::Decoder decoder; + // Make sure we skip dequantization for the position attribute. + decoder.SetSkipAttributeTransform(draco::GeometryAttribute::POSITION); + + // Decode the input data into a geometry. + std::unique_ptr pc = + decoder.DecodePointCloudFromBuffer(&buffer).value(); + ASSERT_NE(pc, nullptr); + + const draco::PointAttribute *const pos_att = + pc->GetNamedAttribute(draco::GeometryAttribute::POSITION); + ASSERT_NE(pos_att, nullptr); + + // Ensure the position attribute is of type int32_t or uint32_t and that it + // has a valid attribute transform. + ASSERT_TRUE(pos_att->data_type() == draco::DT_INT32 || + pos_att->data_type() == draco::DT_UINT32); + ASSERT_NE(pos_att->GetAttributeTransformData(), nullptr); + + const draco::PointAttribute *const clr_att = + pc->GetNamedAttribute(draco::GeometryAttribute::COLOR); + ASSERT_EQ(clr_att->data_type(), draco::DT_UINT8); + + // Ensure the color attribute was decoded correctly. Perform the decoding + // again without skipping the position dequantization and compare the + // attribute values. + + draco::DecoderBuffer buffer_2; + buffer_2.Init(data.data(), data.size()); + + draco::Decoder decoder_2; + + // Decode the input data into a geometry. + std::unique_ptr pc_2 = + decoder_2.DecodePointCloudFromBuffer(&buffer_2).value(); + ASSERT_NE(pc_2, nullptr); + + const draco::PointAttribute *const clr_att_2 = + pc_2->GetNamedAttribute(draco::GeometryAttribute::COLOR); + ASSERT_NE(clr_att_2, nullptr); + for (draco::PointIndex pi(0); pi < pc_2->num_points(); ++pi) { + // Colors should be exactly the same for both cases. + ASSERT_EQ(std::memcmp(clr_att->GetAddress(clr_att->mapped_index(pi)), + clr_att_2->GetAddress(clr_att_2->mapped_index(pi)), + clr_att->byte_stride()), + 0); + } +} + +TEST_F(DecodeTest, TestSkipAttributeTransformOnPointCloud) { + // Tests that decoders can successfully skip attribute transform on a point + // cloud with multiple attributes encoded with one attributes encoder. + TestSkipAttributeTransformOnPointCloudWithColor("pc_color.drc"); + TestSkipAttributeTransformOnPointCloudWithColor("pc_kd_color.drc"); +} + +TEST_F(DecodeTest, TestSkipAttributeTransformWithNoQuantization) { + // Tests that decoders can successfully skip attribute transform even though + // the input model was not quantized (it has no attribute transform). + const std::string file_name = "point_cloud_no_qp.drc"; + std::vector data; + ASSERT_TRUE( + draco::ReadFileToBuffer(draco::GetTestFileFullPath(file_name), &data)); + ASSERT_FALSE(data.empty()); + + // Create a draco decoding buffer. Note that no data is copied in this step. + draco::DecoderBuffer buffer; + buffer.Init(data.data(), data.size()); + + draco::Decoder decoder; + // Make sure we skip dequantization for the position attribute. + decoder.SetSkipAttributeTransform(draco::GeometryAttribute::POSITION); + + // Decode the input data into a geometry. + std::unique_ptr pc = + decoder.DecodePointCloudFromBuffer(&buffer).value(); + ASSERT_NE(pc, nullptr); + + const draco::PointAttribute *const pos_att = + pc->GetNamedAttribute(draco::GeometryAttribute::POSITION); + ASSERT_NE(pos_att, nullptr); + + // Ensure the position attribute is of type float32 since the attribute was + // not quantized. + ASSERT_EQ(pos_att->data_type(), draco::DT_FLOAT32); + + // Make sure there is no attribute transform available for the attribute. + ASSERT_EQ(pos_att->GetAttributeTransformData(), nullptr); +} + +TEST_F(DecodeTest, TestSkipAttributeTransformUniqueId) { + // Tests that decoders preserve unique id of attributes even when their + // attribute transforms are skipped. + const std::string file_name = "cube_att.obj"; + auto src_mesh = draco::ReadMeshFromTestFile(file_name); + ASSERT_NE(src_mesh, nullptr); + + constexpr int kPosUniqueId = 7; + constexpr int kNormUniqueId = 42; + // Set unique ids for some of the attributes. + src_mesh + ->attribute( + src_mesh->GetNamedAttributeId(draco::GeometryAttribute::POSITION)) + ->set_unique_id(kPosUniqueId); + src_mesh + ->attribute( + src_mesh->GetNamedAttributeId(draco::GeometryAttribute::NORMAL)) + ->set_unique_id(kNormUniqueId); + + draco::EncoderBuffer encoder_buffer; + draco::Encoder encoder; + encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 10); + encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL, 11); + encoder.EncodeMeshToBuffer(*src_mesh, &encoder_buffer); + + // Create a draco decoding buffer. + draco::DecoderBuffer buffer; + buffer.Init(encoder_buffer.data(), encoder_buffer.size()); + + // First we decode the mesh without skipping the attribute transforms. + draco::Decoder decoder_no_skip; + std::unique_ptr mesh_no_skip = + decoder_no_skip.DecodeMeshFromBuffer(&buffer).value(); + ASSERT_NE(mesh_no_skip, nullptr); + + // Now we decode it again while skipping some attributes. + draco::Decoder decoder_skip; + // Make sure we skip dequantization for the position and normal attribute. + decoder_skip.SetSkipAttributeTransform(draco::GeometryAttribute::POSITION); + decoder_skip.SetSkipAttributeTransform(draco::GeometryAttribute::NORMAL); + + // Decode the input data into a geometry. + buffer.Init(encoder_buffer.data(), encoder_buffer.size()); + std::unique_ptr mesh_skip = + decoder_skip.DecodeMeshFromBuffer(&buffer).value(); + ASSERT_NE(mesh_skip, nullptr); + + // Compare the unique ids. + const draco::PointAttribute *const pos_att_no_skip = + mesh_no_skip->GetNamedAttribute(draco::GeometryAttribute::POSITION); + ASSERT_NE(pos_att_no_skip, nullptr); + ASSERT_EQ(pos_att_no_skip->data_type(), draco::DataType::DT_FLOAT32); + + const draco::PointAttribute *const pos_att_skip = + mesh_skip->GetNamedAttribute(draco::GeometryAttribute::POSITION); + ASSERT_NE(pos_att_skip, nullptr); + ASSERT_EQ(pos_att_skip->data_type(), draco::DataType::DT_INT32); + + const draco::PointAttribute *const norm_att_no_skip = + mesh_no_skip->GetNamedAttribute(draco::GeometryAttribute::NORMAL); + ASSERT_NE(norm_att_no_skip, nullptr); + ASSERT_EQ(norm_att_no_skip->data_type(), draco::DataType::DT_FLOAT32); + + const draco::PointAttribute *const norm_att_skip = + mesh_skip->GetNamedAttribute(draco::GeometryAttribute::NORMAL); + ASSERT_NE(norm_att_skip, nullptr); + ASSERT_EQ(norm_att_skip->data_type(), draco::DataType::DT_INT32); + + ASSERT_EQ(pos_att_skip->unique_id(), pos_att_no_skip->unique_id()); + ASSERT_EQ(norm_att_skip->unique_id(), norm_att_no_skip->unique_id()); + std::cout << pos_att_skip->unique_id() << " " << norm_att_skip->unique_id() + << std::endl; +} + +} // namespace diff --git a/third-party/draco/src/draco/compression/draco_compression_options.cc b/third-party/draco/src/draco/compression/draco_compression_options.cc new file mode 100644 index 0000000000..08171c6789 --- /dev/null +++ b/third-party/draco/src/draco/compression/draco_compression_options.cc @@ -0,0 +1,59 @@ +// Copyright 2022 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/draco_compression_options.h" + +#ifdef DRACO_TRANSCODER_SUPPORTED + +namespace draco { + +SpatialQuantizationOptions::SpatialQuantizationOptions(int quantization_bits) { + SetQuantizationBits(quantization_bits); +} + +void SpatialQuantizationOptions::SetQuantizationBits(int quantization_bits) { + mode_ = LOCAL_QUANTIZATION_BITS; + quantization_bits_ = quantization_bits; +} + +bool SpatialQuantizationOptions::AreQuantizationBitsDefined() const { + return mode_ == LOCAL_QUANTIZATION_BITS; +} + +SpatialQuantizationOptions &SpatialQuantizationOptions::SetGrid(float spacing) { + mode_ = GLOBAL_GRID; + spacing_ = spacing; + return *this; +} + +bool SpatialQuantizationOptions::operator==( + const SpatialQuantizationOptions &other) const { + if (mode_ != other.mode_) { + return false; + } + if (mode_ == LOCAL_QUANTIZATION_BITS) { + if (quantization_bits_ != other.quantization_bits_) { + return false; + } + } else if (mode_ == GLOBAL_GRID) { + if (spacing_ != other.spacing_) { + return false; + } + } + return true; +} + +} // namespace draco + +#endif // DRACO_TRANSCODER_SUPPORTED diff --git a/third-party/draco/src/draco/compression/draco_compression_options.h b/third-party/draco/src/draco/compression/draco_compression_options.h new file mode 100644 index 0000000000..31a4418ede --- /dev/null +++ b/third-party/draco/src/draco/compression/draco_compression_options.h @@ -0,0 +1,141 @@ +// Copyright 2019 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_DRACO_COMPRESSION_OPTIONS_H_ +#define DRACO_COMPRESSION_DRACO_COMPRESSION_OPTIONS_H_ + +#include "draco/draco_features.h" + +#ifdef DRACO_TRANSCODER_SUPPORTED +#include "draco/core/status.h" + +namespace draco { + +// Quantization options for positions. Currently there are two modes for +// quantizing positions: +// +// 1. Quantization bits: +// - User defined number of quantization bits that is evenly distributed +// to cover the compressed geometry. +// 2. Grid: +// - Positions are snapped to a global grid defined by grid spacing. +// - This method is primarily intended to be used when the location of +// quantized vertices needs to be consistent between multiple +// geometries. +class SpatialQuantizationOptions { + public: + explicit SpatialQuantizationOptions(int quantization_bits); + + // Sets quantization bits that are going to be used for the compressed + // geometry. If the geometry is a scene, the same number of quantization bits + // is going to be applied to each mesh of the scene. Quantized values are + // going to be distributed within the bounds of individual meshes. + void SetQuantizationBits(int quantization_bits); + + // If this returns true, quantization_bits() should be used to get the + // desired number of quantization bits for compression. Otherwise the grid + // mode is selected and spacing() should be used to get the desired grid + // spacing. + bool AreQuantizationBitsDefined() const; + const int quantization_bits() const { return quantization_bits_; } + + // Defines quantization grid used for the compressed geometry. All vertices + // are going to be snapped to the nearest grid vertex that corresponds to an + // integer quantized position. |spacing| defines the distance between two grid + // vertices. E.g. a grid with |spacing| = 10 would have grid vertices at + // locations {10 * i, 10 * j, 10 * k} where i, j, k are integer numbers. + SpatialQuantizationOptions &SetGrid(float spacing); + + const float spacing() const { return spacing_; } + + bool operator==(const SpatialQuantizationOptions &other) const; + + private: + enum Mode { LOCAL_QUANTIZATION_BITS, GLOBAL_GRID }; + Mode mode_ = LOCAL_QUANTIZATION_BITS; + int quantization_bits_; // Default quantization bits for positions. + float spacing_ = 0.f; +}; + +// TODO(fgalligan): Add support for unified_position_quantization. +// Struct to hold Draco compression options. +struct DracoCompressionOptions { + int compression_level = 7; // compression level [0-10], most=10, least=0. + SpatialQuantizationOptions quantization_position{11}; + int quantization_bits_normal = 8; + int quantization_bits_tex_coord = 10; + int quantization_bits_color = 8; + int quantization_bits_generic = 8; + int quantization_bits_tangent = 8; + int quantization_bits_weight = 8; + bool find_non_degenerate_texture_quantization = false; + + bool operator==(const DracoCompressionOptions &other) const { + return compression_level == other.compression_level && + quantization_position == other.quantization_position && + quantization_bits_normal == other.quantization_bits_normal && + quantization_bits_tex_coord == other.quantization_bits_tex_coord && + quantization_bits_color == other.quantization_bits_color && + quantization_bits_generic == other.quantization_bits_generic && + quantization_bits_tangent == other.quantization_bits_tangent && + quantization_bits_weight == other.quantization_bits_weight && + find_non_degenerate_texture_quantization == + other.find_non_degenerate_texture_quantization; + } + + bool operator!=(const DracoCompressionOptions &other) const { + return !(*this == other); + } + + Status Check() const { + DRACO_RETURN_IF_ERROR( + Validate("Compression level", compression_level, 0, 10)); + if (quantization_position.AreQuantizationBitsDefined()) { + DRACO_RETURN_IF_ERROR(Validate("Position quantization", + quantization_position.quantization_bits(), + 0, 30)); + } else { + if (quantization_position.spacing() <= 0.f) { + return ErrorStatus("Position quantization spacing is invalid."); + } + } + DRACO_RETURN_IF_ERROR( + Validate("Normals quantization", quantization_bits_normal, 0, 30)); + DRACO_RETURN_IF_ERROR( + Validate("Tex coord quantization", quantization_bits_tex_coord, 0, 30)); + DRACO_RETURN_IF_ERROR( + Validate("Color quantization", quantization_bits_color, 0, 30)); + DRACO_RETURN_IF_ERROR( + Validate("Generic quantization", quantization_bits_generic, 0, 30)); + DRACO_RETURN_IF_ERROR( + Validate("Tangent quantization", quantization_bits_tangent, 0, 30)); + DRACO_RETURN_IF_ERROR( + Validate("Weights quantization", quantization_bits_weight, 0, 30)); + return OkStatus(); + } + + static Status Validate(const std::string &name, int value, int min, int max) { + if (value < min || value > max) { + const std::string range = + "[" + std::to_string(min) + "-" + std::to_string(max) + "]."; + return Status(Status::DRACO_ERROR, name + " is out of range " + range); + } + return OkStatus(); + } +}; + +} // namespace draco + +#endif // DRACO_TRANSCODER_SUPPORTED +#endif // DRACO_COMPRESSION_DRACO_COMPRESSION_OPTIONS_H_ diff --git a/third-party/draco/src/draco/compression/draco_compression_options_test.cc b/third-party/draco/src/draco/compression/draco_compression_options_test.cc new file mode 100644 index 0000000000..4152952117 --- /dev/null +++ b/third-party/draco/src/draco/compression/draco_compression_options_test.cc @@ -0,0 +1,45 @@ +#include "draco/compression/draco_compression_options.h" + +#include "draco/core/draco_test_utils.h" + +#ifdef DRACO_TRANSCODER_SUPPORTED + +namespace { + +TEST(DracoCompressionOptionsTest, TestPositionQuantizationBits) { + // Test verifies that we can define draco compression options using + // quantization bits. + draco::SpatialQuantizationOptions options(10); + + // Quantization bits should be used by default. + ASSERT_TRUE(options.AreQuantizationBitsDefined()); + ASSERT_EQ(options.quantization_bits(), 10); + + // Change the quantization bits. + options.SetQuantizationBits(9); + ASSERT_TRUE(options.AreQuantizationBitsDefined()); + ASSERT_EQ(options.quantization_bits(), 9); + + // If we select the grid, quantization bits should not be used. + options.SetGrid(0.5f); + ASSERT_FALSE(options.AreQuantizationBitsDefined()); +} + +TEST(DracoCompressionOptionsTest, TestPositionQuantizationGrid) { + // Test verifies that we can define draco compression options using + // quantization grid. + draco::SpatialQuantizationOptions options(10); + + // Quantization bits should be used by default. + ASSERT_TRUE(options.AreQuantizationBitsDefined()); + + // Set the grid parameters. + options.SetGrid(0.25f); + ASSERT_FALSE(options.AreQuantizationBitsDefined()); + + ASSERT_EQ(options.spacing(), 0.25f); +} + +} // namespace + +#endif // DRACO_TRANSCODER_SUPPORTED diff --git a/third-party/draco/src/draco/compression/encode.cc b/third-party/draco/src/draco/compression/encode.cc new file mode 100644 index 0000000000..f380aec159 --- /dev/null +++ b/third-party/draco/src/draco/compression/encode.cc @@ -0,0 +1,96 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/encode.h" + +#include "draco/compression/expert_encode.h" + +namespace draco { + +Encoder::Encoder() {} + +Status Encoder::EncodePointCloudToBuffer(const PointCloud &pc, + EncoderBuffer *out_buffer) { + ExpertEncoder encoder(pc); + encoder.Reset(CreateExpertEncoderOptions(pc)); + return encoder.EncodeToBuffer(out_buffer); +} + +Status Encoder::EncodeMeshToBuffer(const Mesh &m, EncoderBuffer *out_buffer) { + ExpertEncoder encoder(m); + encoder.Reset(CreateExpertEncoderOptions(m)); + DRACO_RETURN_IF_ERROR(encoder.EncodeToBuffer(out_buffer)); + set_num_encoded_points(encoder.num_encoded_points()); + set_num_encoded_faces(encoder.num_encoded_faces()); + return OkStatus(); +} + +EncoderOptions Encoder::CreateExpertEncoderOptions(const PointCloud &pc) const { + EncoderOptions ret_options = EncoderOptions::CreateEmptyOptions(); + ret_options.SetGlobalOptions(options().GetGlobalOptions()); + ret_options.SetFeatureOptions(options().GetFeaturelOptions()); + // Convert type-based attribute options to specific attributes in the provided + // point cloud. + for (int i = 0; i < pc.num_attributes(); ++i) { + const Options *att_options = + options().FindAttributeOptions(pc.attribute(i)->attribute_type()); + if (att_options) { + ret_options.SetAttributeOptions(i, *att_options); + } + } + return ret_options; +} + +void Encoder::Reset( + const EncoderOptionsBase &options) { + Base::Reset(options); +} + +void Encoder::Reset() { Base::Reset(); } + +void Encoder::SetSpeedOptions(int encoding_speed, int decoding_speed) { + Base::SetSpeedOptions(encoding_speed, decoding_speed); +} + +void Encoder::SetAttributeQuantization(GeometryAttribute::Type type, + int quantization_bits) { + options().SetAttributeInt(type, "quantization_bits", quantization_bits); +} + +void Encoder::SetAttributeExplicitQuantization(GeometryAttribute::Type type, + int quantization_bits, + int num_dims, + const float *origin, + float range) { + options().SetAttributeInt(type, "quantization_bits", quantization_bits); + options().SetAttributeVector(type, "quantization_origin", num_dims, origin); + options().SetAttributeFloat(type, "quantization_range", range); +} + +void Encoder::SetEncodingMethod(int encoding_method) { + Base::SetEncodingMethod(encoding_method); +} + +Status Encoder::SetAttributePredictionScheme(GeometryAttribute::Type type, + int prediction_scheme_method) { + Status status = CheckPredictionScheme(type, prediction_scheme_method); + if (!status.ok()) { + return status; + } + options().SetAttributeInt(type, "prediction_scheme", + prediction_scheme_method); + return status; +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/encode.h b/third-party/draco/src/draco/compression/encode.h new file mode 100644 index 0000000000..00ccb9b2e0 --- /dev/null +++ b/third-party/draco/src/draco/compression/encode.h @@ -0,0 +1,139 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ENCODE_H_ +#define DRACO_COMPRESSION_ENCODE_H_ + +#include "draco/compression/config/compression_shared.h" +#include "draco/compression/config/encoder_options.h" +#include "draco/compression/encode_base.h" +#include "draco/core/encoder_buffer.h" +#include "draco/core/status.h" +#include "draco/mesh/mesh.h" + +namespace draco { + +// Basic helper class for encoding geometry using the Draco compression library. +// The class provides various methods that can be used to control several common +// options used during the encoding, such as the number of quantization bits for +// a given attribute. All these options are defined per attribute type, i.e., +// if there are more attributes of the same type (such as multiple texture +// coordinate attributes), the same options are going to be used for all of the +// attributes of this type. If different attributes of the same type need to +// use different options, use ExpertEncoder in expert_encode.h. +class Encoder + : public EncoderBase> { + public: + typedef EncoderBase> Base; + + Encoder(); + virtual ~Encoder() {} + + // Encodes a point cloud to the provided buffer. + virtual Status EncodePointCloudToBuffer(const PointCloud &pc, + EncoderBuffer *out_buffer); + + // Encodes a mesh to the provided buffer. + virtual Status EncodeMeshToBuffer(const Mesh &m, EncoderBuffer *out_buffer); + + // Set encoder options used during the geometry encoding. Note that this call + // overwrites any modifications to the options done with the functions below, + // i.e., it resets the encoder. + void Reset(const EncoderOptionsBase &options); + void Reset(); + + // Sets the desired encoding and decoding speed for the given options. + // + // 0 = slowest speed, but the best compression. + // 10 = fastest, but the worst compression. + // -1 = undefined. + // + // Note that both speed options affect the encoder choice of used methods and + // algorithms. For example, a requirement for fast decoding may prevent the + // encoder from using the best compression methods even if the encoding speed + // is set to 0. In general, the faster of the two options limits the choice of + // features that can be used by the encoder. Additionally, setting + // |decoding_speed| to be faster than the |encoding_speed| may allow the + // encoder to choose the optimal method out of the available features for the + // given |decoding_speed|. + void SetSpeedOptions(int encoding_speed, int decoding_speed); + + // Sets the quantization compression options for a named attribute. The + // attribute values will be quantized in a box defined by the maximum extent + // of the attribute values. I.e., the actual precision of this option depends + // on the scale of the attribute values. + void SetAttributeQuantization(GeometryAttribute::Type type, + int quantization_bits); + + // Sets the explicit quantization compression for a named attribute. The + // attribute values will be quantized in a coordinate system defined by the + // provided origin and range (the input values should be within interval: + // ). + void SetAttributeExplicitQuantization(GeometryAttribute::Type type, + int quantization_bits, int num_dims, + const float *origin, float range); + + // Sets the desired prediction method for a given attribute. By default, + // prediction scheme is selected automatically by the encoder using other + // provided options (such as speed) and input geometry type (mesh, point + // cloud). This function should be called only when a specific prediction is + // preferred (e.g., when it is known that the encoder would select a less + // optimal prediction for the given input data). + // + // |prediction_scheme_method| should be one of the entries defined in + // compression/config/compression_shared.h : + // + // PREDICTION_NONE - use no prediction. + // PREDICTION_DIFFERENCE - delta coding + // MESH_PREDICTION_PARALLELOGRAM - parallelogram prediction for meshes. + // MESH_PREDICTION_CONSTRAINED_PARALLELOGRAM + // - better and more costly version of the parallelogram prediction. + // MESH_PREDICTION_TEX_COORDS_PORTABLE + // - specialized predictor for tex coordinates. + // MESH_PREDICTION_GEOMETRIC_NORMAL + // - specialized predictor for normal coordinates. + // + // Note that in case the desired prediction cannot be used, the default + // prediction will be automatically used instead. + Status SetAttributePredictionScheme(GeometryAttribute::Type type, + int prediction_scheme_method); + + // Sets the desired encoding method for a given geometry. By default, encoding + // method is selected based on the properties of the input geometry and based + // on the other options selected in the used EncoderOptions (such as desired + // encoding and decoding speed). This function should be called only when a + // specific method is required. + // + // |encoding_method| can be one of the values defined in + // compression/config/compression_shared.h based on the type of the input + // geometry that is going to be encoded. For point clouds, allowed entries are + // POINT_CLOUD_SEQUENTIAL_ENCODING + // POINT_CLOUD_KD_TREE_ENCODING + // + // For meshes the input can be + // MESH_SEQUENTIAL_ENCODING + // MESH_EDGEBREAKER_ENCODING + // + // If the selected method cannot be used for the given input, the subsequent + // call of EncodePointCloudToBuffer or EncodeMeshToBuffer is going to fail. + void SetEncodingMethod(int encoding_method); + + // Creates encoder options for the expert encoder used during the actual + // encoding. + EncoderOptions CreateExpertEncoderOptions(const PointCloud &pc) const; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ENCODE_H_ diff --git a/third-party/draco/src/draco/compression/encode_base.h b/third-party/draco/src/draco/compression/encode_base.h new file mode 100644 index 0000000000..6211efc221 --- /dev/null +++ b/third-party/draco/src/draco/compression/encode_base.h @@ -0,0 +1,131 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ENCODE_BASE_H_ +#define DRACO_COMPRESSION_ENCODE_BASE_H_ + +#include "draco/attributes/geometry_attribute.h" +#include "draco/compression/config/compression_shared.h" +#include "draco/core/status.h" + +namespace draco { + +// Base class for our geometry encoder classes. |EncoderOptionsT| specifies +// options class used by the encoder. Please, see encode.h and expert_encode.h +// for more details and method descriptions. +template +class EncoderBase { + public: + typedef EncoderOptionsT OptionsType; + + EncoderBase() + : options_(EncoderOptionsT::CreateDefaultOptions()), + num_encoded_points_(0), + num_encoded_faces_(0) {} + virtual ~EncoderBase() {} + + const EncoderOptionsT &options() const { return options_; } + EncoderOptionsT &options() { return options_; } + + // If enabled, it tells the encoder to keep track of the number of encoded + // points and faces (default = false). + // Note that this can slow down encoding for certain encoders. + void SetTrackEncodedProperties(bool flag); + + // Returns the number of encoded points and faces during the last encoding + // operation. Returns 0 if SetTrackEncodedProperties() was not set. + size_t num_encoded_points() const { return num_encoded_points_; } + size_t num_encoded_faces() const { return num_encoded_faces_; } + + protected: + void Reset(const EncoderOptionsT &options) { options_ = options; } + + void Reset() { options_ = EncoderOptionsT::CreateDefaultOptions(); } + + void SetSpeedOptions(int encoding_speed, int decoding_speed) { + options_.SetSpeed(encoding_speed, decoding_speed); + } + + void SetEncodingMethod(int encoding_method) { + options_.SetGlobalInt("encoding_method", encoding_method); + } + + void SetEncodingSubmethod(int encoding_submethod) { + options_.SetGlobalInt("encoding_submethod", encoding_submethod); + } + + Status CheckPredictionScheme(GeometryAttribute::Type att_type, + int prediction_scheme) const { + // Out of bound checks: + if (prediction_scheme < PREDICTION_NONE) { + return Status(Status::DRACO_ERROR, + "Invalid prediction scheme requested."); + } + if (prediction_scheme >= NUM_PREDICTION_SCHEMES) { + return Status(Status::DRACO_ERROR, + "Invalid prediction scheme requested."); + } + // Deprecated prediction schemes: + if (prediction_scheme == MESH_PREDICTION_TEX_COORDS_DEPRECATED) { + return Status(Status::DRACO_ERROR, + "MESH_PREDICTION_TEX_COORDS_DEPRECATED is deprecated."); + } + if (prediction_scheme == MESH_PREDICTION_MULTI_PARALLELOGRAM) { + return Status(Status::DRACO_ERROR, + "MESH_PREDICTION_MULTI_PARALLELOGRAM is deprecated."); + } + // Attribute specific checks: + if (prediction_scheme == MESH_PREDICTION_TEX_COORDS_PORTABLE) { + if (att_type != GeometryAttribute::TEX_COORD) { + return Status(Status::DRACO_ERROR, + "Invalid prediction scheme for attribute type."); + } + } + if (prediction_scheme == MESH_PREDICTION_GEOMETRIC_NORMAL) { + if (att_type != GeometryAttribute::NORMAL) { + return Status(Status::DRACO_ERROR, + "Invalid prediction scheme for attribute type."); + } + } + // TODO(b/199760123): Try to enable more prediction schemes for normals. + if (att_type == GeometryAttribute::NORMAL) { + if (!(prediction_scheme == PREDICTION_DIFFERENCE || + prediction_scheme == MESH_PREDICTION_GEOMETRIC_NORMAL)) { + return Status(Status::DRACO_ERROR, + "Invalid prediction scheme for attribute type."); + } + } + return OkStatus(); + } + + protected: + void set_num_encoded_points(size_t num) { num_encoded_points_ = num; } + void set_num_encoded_faces(size_t num) { num_encoded_faces_ = num; } + + private: + EncoderOptionsT options_; + + size_t num_encoded_points_; + size_t num_encoded_faces_; +}; + +template +void EncoderBase::SetTrackEncodedProperties(bool flag) { + options_.SetGlobalBool("store_number_of_encoded_points", flag); + options_.SetGlobalBool("store_number_of_encoded_faces", flag); +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ENCODE_BASE_H_ diff --git a/third-party/draco/src/draco/compression/encode_test.cc b/third-party/draco/src/draco/compression/encode_test.cc new file mode 100644 index 0000000000..461dddef7c --- /dev/null +++ b/third-party/draco/src/draco/compression/encode_test.cc @@ -0,0 +1,640 @@ +// Copyright 2017 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "draco/compression/encode.h" + +#include +#include +#include + +#include "draco/attributes/attribute_quantization_transform.h" +#include "draco/compression/config/compression_shared.h" +#include "draco/compression/decode.h" +#include "draco/compression/expert_encode.h" +#include "draco/core/draco_test_base.h" +#include "draco/core/draco_test_utils.h" +#include "draco/core/vector_d.h" +#include "draco/io/file_utils.h" +#include "draco/io/obj_decoder.h" +#include "draco/mesh/triangle_soup_mesh_builder.h" +#include "draco/point_cloud/point_cloud_builder.h" + +namespace { + +class EncodeTest : public ::testing::Test { + protected: + EncodeTest() {} + std::unique_ptr CreateTestMesh() const { + draco::TriangleSoupMeshBuilder mesh_builder; + + // Create a simple mesh with one face. + mesh_builder.Start(1); + + // Add one position attribute and two texture coordinate attributes. + const int32_t pos_att_id = mesh_builder.AddAttribute( + draco::GeometryAttribute::POSITION, 3, draco::DT_FLOAT32); + const int32_t tex_att_id_0 = mesh_builder.AddAttribute( + draco::GeometryAttribute::TEX_COORD, 2, draco::DT_FLOAT32); + const int32_t tex_att_id_1 = mesh_builder.AddAttribute( + draco::GeometryAttribute::TEX_COORD, 2, draco::DT_FLOAT32); + + // Initialize the attribute values. + mesh_builder.SetAttributeValuesForFace( + pos_att_id, draco::FaceIndex(0), draco::Vector3f(0.f, 0.f, 0.f).data(), + draco::Vector3f(1.f, 0.f, 0.f).data(), + draco::Vector3f(1.f, 1.f, 0.f).data()); + mesh_builder.SetAttributeValuesForFace( + tex_att_id_0, draco::FaceIndex(0), draco::Vector2f(0.f, 0.f).data(), + draco::Vector2f(1.f, 0.f).data(), draco::Vector2f(1.f, 1.f).data()); + mesh_builder.SetAttributeValuesForFace( + tex_att_id_1, draco::FaceIndex(0), draco::Vector2f(0.f, 0.f).data(), + draco::Vector2f(1.f, 0.f).data(), draco::Vector2f(1.f, 1.f).data()); + + return mesh_builder.Finalize(); + } + + std::unique_ptr CreateTestPointCloud() const { + draco::PointCloudBuilder pc_builder; + + constexpr int kNumPoints = 100; + constexpr int kNumGenAttCoords0 = 4; + constexpr int kNumGenAttCoords1 = 6; + pc_builder.Start(kNumPoints); + + // Add one position attribute and two generic attributes. + const int32_t pos_att_id = pc_builder.AddAttribute( + draco::GeometryAttribute::POSITION, 3, draco::DT_FLOAT32); + const int32_t gen_att_id_0 = pc_builder.AddAttribute( + draco::GeometryAttribute::GENERIC, kNumGenAttCoords0, draco::DT_UINT32); + const int32_t gen_att_id_1 = pc_builder.AddAttribute( + draco::GeometryAttribute::GENERIC, kNumGenAttCoords1, draco::DT_UINT8); + + std::vector gen_att_data_0(kNumGenAttCoords0); + std::vector gen_att_data_1(kNumGenAttCoords1); + + // Initialize the attribute values. + for (draco::PointIndex i(0); i < kNumPoints; ++i) { + const float pos_coord = static_cast(i.value()); + pc_builder.SetAttributeValueForPoint( + pos_att_id, i, + draco::Vector3f(pos_coord, -pos_coord, pos_coord).data()); + + for (int j = 0; j < kNumGenAttCoords0; ++j) { + gen_att_data_0[j] = i.value(); + } + pc_builder.SetAttributeValueForPoint(gen_att_id_0, i, + gen_att_data_0.data()); + + for (int j = 0; j < kNumGenAttCoords1; ++j) { + gen_att_data_1[j] = -i.value(); + } + pc_builder.SetAttributeValueForPoint(gen_att_id_1, i, + gen_att_data_1.data()); + } + return pc_builder.Finalize(false); + } + + std::unique_ptr CreateTestPointCloudPosNorm() const { + draco::PointCloudBuilder pc_builder; + + constexpr int kNumPoints = 20; + pc_builder.Start(kNumPoints); + + // Add one position attribute and a normal attribute. + const int32_t pos_att_id = pc_builder.AddAttribute( + draco::GeometryAttribute::POSITION, 3, draco::DT_FLOAT32); + const int32_t norm_att_id = pc_builder.AddAttribute( + draco::GeometryAttribute::NORMAL, 3, draco::DT_FLOAT32); + + // Initialize the attribute values. + for (draco::PointIndex i(0); i < kNumPoints; ++i) { + const float pos_coord = static_cast(i.value()); + pc_builder.SetAttributeValueForPoint( + pos_att_id, i, + draco::Vector3f(pos_coord, -pos_coord, pos_coord).data()); + + // Pseudo-random normal. + draco::Vector3f norm(pos_coord * 2.f, pos_coord - 2.f, pos_coord * 3.f); + norm.Normalize(); + pc_builder.SetAttributeValueForPoint(norm_att_id, i, norm.data()); + } + + return pc_builder.Finalize(false); + } + + int GetQuantizationBitsFromAttribute(const draco::PointAttribute *att) const { + if (att == nullptr) { + return -1; + } + draco::AttributeQuantizationTransform transform; + if (!transform.InitFromAttribute(*att)) { + return -1; + } + return transform.quantization_bits(); + } + + void VerifyNumQuantizationBits(const draco::EncoderBuffer &buffer, + int pos_quantization, + int tex_coord_0_quantization, + int tex_coord_1_quantization) const { + draco::Decoder decoder; + + // Skip the dequantization for the attributes which will allow us to get + // the number of quantization bits used during encoding. + decoder.SetSkipAttributeTransform(draco::GeometryAttribute::POSITION); + decoder.SetSkipAttributeTransform(draco::GeometryAttribute::TEX_COORD); + + draco::DecoderBuffer in_buffer; + in_buffer.Init(buffer.data(), buffer.size()); + auto mesh = decoder.DecodeMeshFromBuffer(&in_buffer).value(); + ASSERT_NE(mesh, nullptr); + ASSERT_EQ(GetQuantizationBitsFromAttribute(mesh->attribute(0)), + pos_quantization); + ASSERT_EQ(GetQuantizationBitsFromAttribute(mesh->attribute(1)), + tex_coord_0_quantization); + ASSERT_EQ(GetQuantizationBitsFromAttribute(mesh->attribute(2)), + tex_coord_1_quantization); + } + + // Tests that the encoder returns the correct number of encoded points and + // faces for a given mesh or point cloud. + void TestNumberOfEncodedEntries(const std::string &file_name, + int32_t encoding_method) { + std::unique_ptr geometry; + draco::Mesh *mesh = nullptr; + + if (encoding_method == draco::MESH_EDGEBREAKER_ENCODING || + encoding_method == draco::MESH_SEQUENTIAL_ENCODING) { + std::unique_ptr mesh_tmp = + draco::ReadMeshFromTestFile(file_name); + mesh = mesh_tmp.get(); + if (!mesh->DeduplicateAttributeValues()) { + return; + } + mesh->DeduplicatePointIds(); + geometry = std::move(mesh_tmp); + } else { + geometry = draco::ReadPointCloudFromTestFile(file_name); + } + ASSERT_NE(mesh, nullptr); + + draco::Encoder encoder; + encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 14); + encoder.SetAttributeQuantization(draco::GeometryAttribute::TEX_COORD, 12); + encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL, 10); + + encoder.SetEncodingMethod(encoding_method); + + encoder.SetTrackEncodedProperties(true); + + draco::EncoderBuffer buffer; + if (mesh) { + encoder.EncodeMeshToBuffer(*mesh, &buffer); + } else { + encoder.EncodePointCloudToBuffer(*geometry, &buffer); + } + + // Ensure the logged number of encoded points and faces matches the number + // we get from the decoder. + + draco::DecoderBuffer decoder_buffer; + decoder_buffer.Init(buffer.data(), buffer.size()); + draco::Decoder decoder; + + if (mesh) { + DRACO_ASSIGN_OR_ASSERT(auto decoded_mesh, + decoder.DecodeMeshFromBuffer(&decoder_buffer)); + ASSERT_NE(decoded_mesh, nullptr); + ASSERT_EQ(decoded_mesh->num_points(), encoder.num_encoded_points()); + ASSERT_EQ(decoded_mesh->num_faces(), encoder.num_encoded_faces()); + } else { + DRACO_ASSIGN_OR_ASSERT( + auto decoded_pc, decoder.DecodePointCloudFromBuffer(&decoder_buffer)); + ASSERT_EQ(decoded_pc->num_points(), encoder.num_encoded_points()); + } + } +}; + +TEST_F(EncodeTest, TestExpertEncoderQuantization) { + // This test verifies that the expert encoder can quantize individual + // attributes even if they have the same type. + auto mesh = CreateTestMesh(); + ASSERT_NE(mesh, nullptr); + + draco::ExpertEncoder encoder(*mesh); + encoder.SetAttributeQuantization(0, 16); // Position quantization. + encoder.SetAttributeQuantization(1, 15); // Tex-coord 0 quantization. + encoder.SetAttributeQuantization(2, 14); // Tex-coord 1 quantization. + + draco::EncoderBuffer buffer; + encoder.EncodeToBuffer(&buffer); + VerifyNumQuantizationBits(buffer, 16, 15, 14); +} + +TEST_F(EncodeTest, TestEncoderQuantization) { + // This test verifies that Encoder applies the same quantization to all + // attributes of the same type. + auto mesh = CreateTestMesh(); + ASSERT_NE(mesh, nullptr); + + draco::Encoder encoder; + encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 16); + encoder.SetAttributeQuantization(draco::GeometryAttribute::TEX_COORD, 15); + + draco::EncoderBuffer buffer; + encoder.EncodeMeshToBuffer(*mesh, &buffer); + VerifyNumQuantizationBits(buffer, 16, 15, 15); +} + +TEST_F(EncodeTest, TestLinesObj) { + // This test verifies that Encoder can encode file that contains only line + // segments (that are ignored). + std::unique_ptr mesh( + draco::ReadMeshFromTestFile("test_lines.obj")); + ASSERT_NE(mesh, nullptr); + ASSERT_EQ(mesh->num_faces(), 0); + std::unique_ptr pc( + draco::ReadPointCloudFromTestFile("test_lines.obj")); + ASSERT_NE(pc, nullptr); + + draco::Encoder encoder; + encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 16); + + draco::EncoderBuffer buffer; + DRACO_ASSERT_OK(encoder.EncodePointCloudToBuffer(*pc, &buffer)); +} + +TEST_F(EncodeTest, TestQuantizedInfinity) { + // This test verifies that Encoder fails to encode point cloud when requesting + // quantization of attribute that contains infinity values. + std::unique_ptr pc( + draco::ReadPointCloudFromTestFile("float_inf_point_cloud.ply")); + ASSERT_NE(pc, nullptr); + + { + draco::Encoder encoder; + encoder.SetEncodingMethod(draco::POINT_CLOUD_SEQUENTIAL_ENCODING); + encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 11); + + draco::EncoderBuffer buffer; + ASSERT_FALSE(encoder.EncodePointCloudToBuffer(*pc, &buffer).ok()); + } + + { + draco::Encoder encoder; + encoder.SetEncodingMethod(draco::POINT_CLOUD_KD_TREE_ENCODING); + encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 11); + + draco::EncoderBuffer buffer; + ASSERT_FALSE(encoder.EncodePointCloudToBuffer(*pc, &buffer).ok()); + } +} + +TEST_F(EncodeTest, TestUnquantizedInfinity) { + // This test verifies that Encoder can successfully encode point cloud when + // not requesting quantization of attribute that contains infinity values. + std::unique_ptr pc( + draco::ReadPointCloudFromTestFile("float_inf_point_cloud.ply")); + ASSERT_NE(pc, nullptr); + + // Note that the KD tree encoding method is not applicable to float values. + draco::Encoder encoder; + encoder.SetEncodingMethod(draco::POINT_CLOUD_SEQUENTIAL_ENCODING); + + draco::EncoderBuffer buffer; + DRACO_ASSERT_OK(encoder.EncodePointCloudToBuffer(*pc, &buffer)); +} + +TEST_F(EncodeTest, TestQuantizedAndUnquantizedAttributes) { + // This test verifies that Encoder can successfully encode point cloud with + // two float attribiutes - one quantized and another unquantized. The encoder + // defaults to sequential encoding in this case. + std::unique_ptr pc( + draco::ReadPointCloudFromTestFile("float_two_att_point_cloud.ply")); + ASSERT_NE(pc, nullptr); + + draco::Encoder encoder; + encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 11); + encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL, 0); + draco::EncoderBuffer buffer; + DRACO_ASSERT_OK(encoder.EncodePointCloudToBuffer(*pc, &buffer)); +} + +TEST_F(EncodeTest, TestKdTreeEncoding) { + // This test verifies that the API can successfully encode a point cloud + // defined by several attributes using the kd tree method. + std::unique_ptr pc = CreateTestPointCloud(); + ASSERT_NE(pc, nullptr); + + draco::EncoderBuffer buffer; + draco::Encoder encoder; + encoder.SetEncodingMethod(draco::POINT_CLOUD_KD_TREE_ENCODING); + // First try it without quantizing positions which should fail. + ASSERT_FALSE(encoder.EncodePointCloudToBuffer(*pc, &buffer).ok()); + + // Now set quantization for the position attribute which should make + // the encoder happy. + encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 16); + DRACO_ASSERT_OK(encoder.EncodePointCloudToBuffer(*pc, &buffer)); +} + +TEST_F(EncodeTest, TestTrackingOfNumberOfEncodedEntries) { + TestNumberOfEncodedEntries("deg_faces.obj", draco::MESH_EDGEBREAKER_ENCODING); + TestNumberOfEncodedEntries("deg_faces.obj", draco::MESH_SEQUENTIAL_ENCODING); + TestNumberOfEncodedEntries("cube_att.obj", draco::MESH_EDGEBREAKER_ENCODING); + TestNumberOfEncodedEntries("test_nm.obj", draco::MESH_EDGEBREAKER_ENCODING); + TestNumberOfEncodedEntries("test_nm.obj", draco::MESH_SEQUENTIAL_ENCODING); + TestNumberOfEncodedEntries("cube_subd.obj", + draco::POINT_CLOUD_KD_TREE_ENCODING); + TestNumberOfEncodedEntries("cube_subd.obj", + draco::POINT_CLOUD_SEQUENTIAL_ENCODING); +} + +TEST_F(EncodeTest, TestTrackingOfNumberOfEncodedEntriesNotSet) { + // Tests that when tracing of encoded properties is disabled, the returned + // number of encoded faces and points is 0. + std::unique_ptr mesh( + draco::ReadMeshFromTestFile("cube_att.obj")); + ASSERT_NE(mesh, nullptr); + + draco::EncoderBuffer buffer; + draco::Encoder encoder; + + DRACO_ASSERT_OK(encoder.EncodeMeshToBuffer(*mesh, &buffer)); + ASSERT_EQ(encoder.num_encoded_points(), 0); + ASSERT_EQ(encoder.num_encoded_faces(), 0); +} + +TEST_F(EncodeTest, TestNoPosQuantizationNormalCoding) { + // Tests that we can encode and decode a file with quantized normals but + // non-quantized positions. + const auto mesh = draco::ReadMeshFromTestFile("test_nm.obj"); + ASSERT_NE(mesh, nullptr); + + // The mesh should have positions and normals. + ASSERT_NE(mesh->GetNamedAttribute(draco::GeometryAttribute::POSITION), + nullptr); + ASSERT_NE(mesh->GetNamedAttribute(draco::GeometryAttribute::NORMAL), nullptr); + + draco::EncoderBuffer buffer; + draco::Encoder encoder; + // No quantization for positions. + encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL, 8); + + DRACO_ASSERT_OK(encoder.EncodeMeshToBuffer(*mesh, &buffer)); + + draco::Decoder decoder; + + draco::DecoderBuffer in_buffer; + in_buffer.Init(buffer.data(), buffer.size()); + const auto decoded_mesh = decoder.DecodeMeshFromBuffer(&in_buffer).value(); + ASSERT_NE(decoded_mesh, nullptr); +} + +#ifdef DRACO_TRANSCODER_SUPPORTED +TEST_F(EncodeTest, TestDracoCompressionOptions) { + // This test verifies that we can set the encoder's compression options via + // draco::Mesh's compression options. + const auto mesh = draco::ReadMeshFromTestFile("test_nm.obj"); + ASSERT_NE(mesh, nullptr); + + // First set compression level and quantization manually. + draco::Encoder encoder_manual; + draco::EncoderBuffer buffer_manual; + encoder_manual.SetAttributeQuantization(draco::GeometryAttribute::POSITION, + 8); + encoder_manual.SetAttributeQuantization(draco::GeometryAttribute::NORMAL, 7); + encoder_manual.SetSpeedOptions(4, 4); + + DRACO_ASSERT_OK(encoder_manual.EncodeMeshToBuffer(*mesh, &buffer_manual)); + + // Now do the same with options provided via DracoCompressionOptions. + draco::DracoCompressionOptions compression_options; + compression_options.compression_level = 6; + compression_options.quantization_position.SetQuantizationBits(8); + compression_options.quantization_bits_normal = 7; + mesh->SetCompressionOptions(compression_options); + mesh->SetCompressionEnabled(true); + + draco::Encoder encoder_auto; + draco::EncoderBuffer buffer_auto; + DRACO_ASSERT_OK(encoder_auto.EncodeMeshToBuffer(*mesh, &buffer_auto)); + + // Ensure that both encoders produce the same result. + ASSERT_EQ(buffer_manual.size(), buffer_auto.size()); + + // Now change some of the mesh's compression settings and ensure the + // compression changes as well. + compression_options.compression_level = 7; + mesh->SetCompressionOptions(compression_options); + buffer_auto.Clear(); + DRACO_ASSERT_OK(encoder_auto.EncodeMeshToBuffer(*mesh, &buffer_auto)); + ASSERT_NE(buffer_manual.size(), buffer_auto.size()); + + // Check that |mesh| compression options do not override the encoder options. + mesh->GetCompressionOptions().compression_level = 10; + mesh->GetCompressionOptions().quantization_position.SetQuantizationBits(10); + mesh->GetCompressionOptions().quantization_bits_normal = 10; + draco::EncoderBuffer buffer; + DRACO_ASSERT_OK(encoder_manual.EncodeMeshToBuffer(*mesh, &buffer)); + ASSERT_EQ(buffer.size(), buffer_manual.size()); +} + +TEST_F(EncodeTest, TestDracoCompressionOptionsManualOverride) { + // This test verifies that we can use encoder's option to override compression + // options provided in draco::Mesh's compression options. + const auto mesh = draco::ReadMeshFromTestFile("test_nm.obj"); + ASSERT_NE(mesh, nullptr); + + // Set some compression options. + draco::DracoCompressionOptions compression_options; + compression_options.compression_level = 6; + compression_options.quantization_position.SetQuantizationBits(8); + compression_options.quantization_bits_normal = 7; + mesh->SetCompressionOptions(compression_options); + mesh->SetCompressionEnabled(true); + + draco::Encoder encoder; + draco::EncoderBuffer buffer_no_override; + DRACO_ASSERT_OK(encoder.EncodeMeshToBuffer(*mesh, &buffer_no_override)); + + // Now override some options and ensure the compression is different. + encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 5); + draco::EncoderBuffer buffer_with_override; + DRACO_ASSERT_OK(encoder.EncodeMeshToBuffer(*mesh, &buffer_with_override)); + ASSERT_LT(buffer_with_override.size(), buffer_no_override.size()); +} + +TEST_F(EncodeTest, TestDracoCompressionOptionsGridQuantization) { + // Test verifies that we can set position quantization via grid spacing. + + // 1x1x1 cube. + const auto mesh = draco::ReadMeshFromTestFile("cube_att.obj"); + ASSERT_NE(mesh, nullptr); + mesh->SetCompressionEnabled(true); + + // Set grid quantization for positions. + draco::DracoCompressionOptions compression_options; + // This should result in 10x10x10 quantization. + compression_options.quantization_position.SetGrid(0.1); + mesh->SetCompressionOptions(compression_options); + + draco::ExpertEncoder encoder(*mesh); + draco::EncoderBuffer buffer; + DRACO_ASSERT_OK(encoder.EncodeToBuffer(&buffer)); + + // The grid options should be reflected in the |encoder|. Check that the + // computed values are correct. + const int pos_att_id = + mesh->GetNamedAttributeId(draco::GeometryAttribute::POSITION); + draco::Vector3f origin; + encoder.options().GetAttributeVector(pos_att_id, "quantization_origin", 3, + &origin[0]); + ASSERT_EQ(origin, draco::Vector3f(0.f, 0.f, 0.f)); + + // We need 4 quantization bits (for 10 values). + ASSERT_EQ( + encoder.options().GetAttributeInt(pos_att_id, "quantization_bits", -1), + 4); + + // The quantization range should be ((1 << quantization_bits) - 1) * spacing. + ASSERT_NEAR(encoder.options().GetAttributeFloat(pos_att_id, + "quantization_range", 0.f), + 15.f * 0.1f, 1e-6f); +} + +TEST_F(EncodeTest, TestPointCloudGridQuantization) { + // Test verifies that we can set position quantization via grid spacing for a + // point cloud. + const auto pc = draco::ReadPointCloudFromTestFile("cube_att.obj"); + ASSERT_NE(pc, nullptr); + const int pos_att_id = + pc->GetNamedAttributeId(draco::GeometryAttribute::POSITION); + + draco::ExpertEncoder encoder(*pc); + encoder.SetAttributeGridQuantization(*pc, pos_att_id, 0.15); + draco::EncoderBuffer buffer; + DRACO_ASSERT_OK(encoder.EncodeToBuffer(&buffer)); + + // The grid options should be reflected in the |encoder|. Check that the + // computed values are correct. + draco::Vector3f origin; + encoder.options().GetAttributeVector(pos_att_id, "quantization_origin", 3, + &origin[0]); + ASSERT_EQ(origin, draco::Vector3f(0.f, 0.f, 0.f)); + + // We need 3 quantization bits for 8 grid values [0.00, 0.15, ...,1.05]. + ASSERT_EQ( + encoder.options().GetAttributeInt(pos_att_id, "quantization_bits", -1), + 3); + + // The quantization range should be ((1 << quantization_bits) - 1) * spacing. + ASSERT_NEAR(encoder.options().GetAttributeFloat(pos_att_id, + "quantization_range", 0.f), + 1.05f, 1e-6f); +} + +TEST_F(EncodeTest, TestPointCloudGridQuantizationFromCompressionOptions) { + // Test verifies that we can set position quantization via grid spacing for a + // point cloud using DracoCompressionOptions. + const auto pc = draco::ReadPointCloudFromTestFile("cube_att.obj"); + ASSERT_NE(pc, nullptr); + pc->SetCompressionEnabled(true); + + // Set grid quantization for positions. + draco::DracoCompressionOptions compression_options; + // This should result in 10x10x10 quantization. + compression_options.quantization_position.SetGrid(0.15); + pc->SetCompressionOptions(compression_options); + + draco::ExpertEncoder encoder(*pc); + draco::EncoderBuffer buffer; + DRACO_ASSERT_OK(encoder.EncodeToBuffer(&buffer)); + + // The grid options should be reflected in the |encoder|. Check that the + // computed values are correct. + const int pos_att_id = + pc->GetNamedAttributeId(draco::GeometryAttribute::POSITION); + draco::Vector3f origin; + encoder.options().GetAttributeVector(pos_att_id, "quantization_origin", 3, + &origin[0]); + ASSERT_EQ(origin, draco::Vector3f(0.f, 0.f, 0.f)); + + // We need 3 quantization bits for 8 grid values [0.00, 0.15, ...,1.05]. + ASSERT_EQ( + encoder.options().GetAttributeInt(pos_att_id, "quantization_bits", -1), + 3); + + // The quantization range should be ((1 << quantization_bits) - 1) * spacing. + ASSERT_NEAR(encoder.options().GetAttributeFloat(pos_att_id, + "quantization_range", 0.f), + 1.05f, 1e-6f); +} + +TEST_F(EncodeTest, TestDracoCompressionOptionsGridQuantizationWithOffset) { + // Test verifies that we can set position quantization via grid spacing when + // the geometry is not perfectly aligned with the quantization grid. + + // 1x1x1 cube. + const auto mesh = draco::ReadMeshFromTestFile("cube_att.obj"); + ASSERT_NE(mesh, nullptr); + + // Move all positions a bit. + auto *pos_att = mesh->attribute( + mesh->GetNamedAttributeId(draco::GeometryAttribute::POSITION)); + for (draco::AttributeValueIndex avi(0); avi < pos_att->size(); ++avi) { + draco::Vector3f pos; + pos_att->GetValue(avi, &pos[0]); + pos = pos + draco::Vector3f(-0.55f, 0.65f, 10.75f); + pos_att->SetAttributeValue(avi, &pos[0]); + } + + mesh->SetCompressionEnabled(true); + + // Set grid quantization for positions. + draco::DracoCompressionOptions compression_options; + // This should result in 16x16x16 quantization if the grid was perfectly + // aligned but since it is not we should expect 17 or 18 values per component. + compression_options.quantization_position.SetGrid(0.0625f); + mesh->SetCompressionOptions(compression_options); + + draco::ExpertEncoder encoder(*mesh); + draco::EncoderBuffer buffer; + DRACO_ASSERT_OK(encoder.EncodeToBuffer(&buffer)); + + // The grid options should be reflected in the |encoder|. Check that the + // computed values are correct. + const int pos_att_id = + mesh->GetNamedAttributeId(draco::GeometryAttribute::POSITION); + draco::Vector3f origin; + encoder.options().GetAttributeVector(pos_att_id, "quantization_origin", 3, + &origin[0]); + // The origin is the first lower value on the quantization grid for each + // component of the mesh. + ASSERT_EQ(origin, draco::Vector3f(-0.5625f, 0.625f, 10.75f)); + + // We need 5 quantization bits (for 17-18 values). + ASSERT_EQ( + encoder.options().GetAttributeInt(pos_att_id, "quantization_bits", -1), + 5); + + // The quantization range should be ((1 << quantization_bits) - 1) * spacing. + ASSERT_NEAR(encoder.options().GetAttributeFloat(pos_att_id, + "quantization_range", 0.f), + 31.f * 0.0625f, 1e-6f); +} +#endif // DRACO_TRANSCODER_SUPPORTED + +} // namespace diff --git a/third-party/draco/src/draco/compression/entropy/ans.h b/third-party/draco/src/draco/compression/entropy/ans.h new file mode 100644 index 0000000000..313546fee2 --- /dev/null +++ b/third-party/draco/src/draco/compression/entropy/ans.h @@ -0,0 +1,526 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ENTROPY_ANS_H_ +#define DRACO_COMPRESSION_ENTROPY_ANS_H_ +// An implementation of Asymmetric Numeral Systems (rANS). +// See http://arxiv.org/abs/1311.2540v2 for more information on rANS. +// This file is based off libvpx's ans.h. + +#include + +#define DRACO_ANS_DIVIDE_BY_MULTIPLY 1 +#if DRACO_ANS_DIVIDE_BY_MULTIPLY +#include "draco/core/divide.h" +#endif +#include "draco/core/macros.h" + +namespace draco { + +#if DRACO_ANS_DIVIDE_BY_MULTIPLY + +#define DRACO_ANS_DIVREM(quotient, remainder, dividend, divisor) \ + do { \ + quotient = fastdiv(dividend, divisor); \ + remainder = dividend - quotient * divisor; \ + } while (0) +#define DRACO_ANS_DIV(dividend, divisor) fastdiv(dividend, divisor) +#else +#define DRACO_ANS_DIVREM(quotient, remainder, dividend, divisor) \ + do { \ + quotient = dividend / divisor; \ + remainder = dividend % divisor; \ + } while (0) +#define DRACO_ANS_DIV(dividend, divisor) ((dividend) / (divisor)) +#endif + +struct AnsCoder { + AnsCoder() : buf(nullptr), buf_offset(0), state(0) {} + uint8_t *buf; + int buf_offset; + uint32_t state; +}; + +struct AnsDecoder { + AnsDecoder() : buf(nullptr), buf_offset(0), state(0) {} + const uint8_t *buf; + int buf_offset; + uint32_t state; +}; + +typedef uint8_t AnsP8; +#define DRACO_ANS_P8_PRECISION 256u +#define DRACO_ANS_L_BASE (4096u) +#define DRACO_ANS_IO_BASE 256 + +static uint32_t mem_get_le16(const void *vmem) { + uint32_t val; + const uint8_t *mem = (const uint8_t *)vmem; + + val = mem[1] << 8; + val |= mem[0]; + return val; +} + +static uint32_t mem_get_le24(const void *vmem) { + uint32_t val; + const uint8_t *mem = (const uint8_t *)vmem; + + val = mem[2] << 16; + val |= mem[1] << 8; + val |= mem[0]; + return val; +} + +static inline uint32_t mem_get_le32(const void *vmem) { + uint32_t val; + const uint8_t *mem = (const uint8_t *)vmem; + + val = mem[3] << 24; + val |= mem[2] << 16; + val |= mem[1] << 8; + val |= mem[0]; + return val; +} + +static inline void mem_put_le16(void *vmem, uint32_t val) { + uint8_t *mem = reinterpret_cast(vmem); + + mem[0] = (val >> 0) & 0xff; + mem[1] = (val >> 8) & 0xff; +} + +static inline void mem_put_le24(void *vmem, uint32_t val) { + uint8_t *mem = reinterpret_cast(vmem); + + mem[0] = (val >> 0) & 0xff; + mem[1] = (val >> 8) & 0xff; + mem[2] = (val >> 16) & 0xff; +} + +static inline void mem_put_le32(void *vmem, uint32_t val) { + uint8_t *mem = reinterpret_cast(vmem); + + mem[0] = (val >> 0) & 0xff; + mem[1] = (val >> 8) & 0xff; + mem[2] = (val >> 16) & 0xff; + mem[3] = (val >> 24) & 0xff; +} + +static inline void ans_write_init(struct AnsCoder *const ans, + uint8_t *const buf) { + ans->buf = buf; + ans->buf_offset = 0; + ans->state = DRACO_ANS_L_BASE; +} + +static inline int ans_write_end(struct AnsCoder *const ans) { + uint32_t state; + DRACO_DCHECK_GE(ans->state, DRACO_ANS_L_BASE); + DRACO_DCHECK_LT(ans->state, DRACO_ANS_L_BASE * DRACO_ANS_IO_BASE); + state = ans->state - DRACO_ANS_L_BASE; + if (state < (1 << 6)) { + ans->buf[ans->buf_offset] = (0x00 << 6) + state; + return ans->buf_offset + 1; + } else if (state < (1 << 14)) { + mem_put_le16(ans->buf + ans->buf_offset, (0x01 << 14) + state); + return ans->buf_offset + 2; + } else if (state < (1 << 22)) { + mem_put_le24(ans->buf + ans->buf_offset, (0x02 << 22) + state); + return ans->buf_offset + 3; + } else { + DRACO_DCHECK(0 && "State is too large to be serialized"); + return ans->buf_offset; + } +} + +// rABS with descending spread. +// p or p0 takes the place of l_s from the paper. +// DRACO_ANS_P8_PRECISION is m. +static inline void rabs_desc_write(struct AnsCoder *ans, int val, AnsP8 p0) { + const AnsP8 p = DRACO_ANS_P8_PRECISION - p0; + const unsigned l_s = val ? p : p0; + unsigned quot, rem; + if (ans->state >= + DRACO_ANS_L_BASE / DRACO_ANS_P8_PRECISION * DRACO_ANS_IO_BASE * l_s) { + ans->buf[ans->buf_offset++] = ans->state % DRACO_ANS_IO_BASE; + ans->state /= DRACO_ANS_IO_BASE; + } + DRACO_ANS_DIVREM(quot, rem, ans->state, l_s); + ans->state = quot * DRACO_ANS_P8_PRECISION + rem + (val ? 0 : p); +} + +#define DRACO_ANS_IMPL1 0 +#define UNPREDICTABLE(x) x +static inline int rabs_desc_read(struct AnsDecoder *ans, AnsP8 p0) { + int val; +#if DRACO_ANS_IMPL1 + unsigned l_s; +#else + unsigned quot, rem, x, xn; +#endif + const AnsP8 p = DRACO_ANS_P8_PRECISION - p0; + if (ans->state < DRACO_ANS_L_BASE && ans->buf_offset > 0) { + ans->state = ans->state * DRACO_ANS_IO_BASE + ans->buf[--ans->buf_offset]; + } +#if DRACO_ANS_IMPL1 + val = ans->state % DRACO_ANS_P8_PRECISION < p; + l_s = val ? p : p0; + ans->state = (ans->state / DRACO_ANS_P8_PRECISION) * l_s + + ans->state % DRACO_ANS_P8_PRECISION - (!val * p); +#else + x = ans->state; + quot = x / DRACO_ANS_P8_PRECISION; + rem = x % DRACO_ANS_P8_PRECISION; + xn = quot * p; + val = rem < p; + if (UNPREDICTABLE(val)) { + ans->state = xn + rem; + } else { + // ans->state = quot * p0 + rem - p; + ans->state = x - xn - p; + } +#endif + return val; +} + +// rABS with ascending spread. +// p or p0 takes the place of l_s from the paper. +// DRACO_ANS_P8_PRECISION is m. +static inline void rabs_asc_write(struct AnsCoder *ans, int val, AnsP8 p0) { + const AnsP8 p = DRACO_ANS_P8_PRECISION - p0; + const unsigned l_s = val ? p : p0; + unsigned quot, rem; + if (ans->state >= + DRACO_ANS_L_BASE / DRACO_ANS_P8_PRECISION * DRACO_ANS_IO_BASE * l_s) { + ans->buf[ans->buf_offset++] = ans->state % DRACO_ANS_IO_BASE; + ans->state /= DRACO_ANS_IO_BASE; + } + DRACO_ANS_DIVREM(quot, rem, ans->state, l_s); + ans->state = quot * DRACO_ANS_P8_PRECISION + rem + (val ? p0 : 0); +} + +static inline int rabs_asc_read(struct AnsDecoder *ans, AnsP8 p0) { + int val; +#if DRACO_ANS_IMPL1 + unsigned l_s; +#else + unsigned quot, rem, x, xn; +#endif + const AnsP8 p = DRACO_ANS_P8_PRECISION - p0; + if (ans->state < DRACO_ANS_L_BASE) { + ans->state = ans->state * DRACO_ANS_IO_BASE + ans->buf[--ans->buf_offset]; + } +#if DRACO_ANS_IMPL1 + val = ans->state % DRACO_ANS_P8_PRECISION < p; + l_s = val ? p : p0; + ans->state = (ans->state / DRACO_ANS_P8_PRECISION) * l_s + + ans->state % DRACO_ANS_P8_PRECISION - (!val * p); +#else + x = ans->state; + quot = x / DRACO_ANS_P8_PRECISION; + rem = x % DRACO_ANS_P8_PRECISION; + xn = quot * p; + val = rem >= p0; + if (UNPREDICTABLE(val)) { + ans->state = xn + rem - p0; + } else { + // ans->state = quot * p0 + rem - p0; + ans->state = x - xn; + } +#endif + return val; +} + +#define rabs_read rabs_desc_read +#define rabs_write rabs_desc_write + +// uABS with normalization. +static inline void uabs_write(struct AnsCoder *ans, int val, AnsP8 p0) { + AnsP8 p = DRACO_ANS_P8_PRECISION - p0; + const unsigned l_s = val ? p : p0; + while (ans->state >= + DRACO_ANS_L_BASE / DRACO_ANS_P8_PRECISION * DRACO_ANS_IO_BASE * l_s) { + ans->buf[ans->buf_offset++] = ans->state % DRACO_ANS_IO_BASE; + ans->state /= DRACO_ANS_IO_BASE; + } + if (!val) { + ans->state = DRACO_ANS_DIV(ans->state * DRACO_ANS_P8_PRECISION, p0); + } else { + ans->state = + DRACO_ANS_DIV((ans->state + 1) * DRACO_ANS_P8_PRECISION + p - 1, p) - 1; + } +} + +static inline int uabs_read(struct AnsDecoder *ans, AnsP8 p0) { + AnsP8 p = DRACO_ANS_P8_PRECISION - p0; + int s; + // unsigned int xp1; + unsigned xp, sp; + unsigned state = ans->state; + while (state < DRACO_ANS_L_BASE && ans->buf_offset > 0) { + state = state * DRACO_ANS_IO_BASE + ans->buf[--ans->buf_offset]; + } + sp = state * p; + // xp1 = (sp + p) / DRACO_ANS_P8_PRECISION; + xp = sp / DRACO_ANS_P8_PRECISION; + // s = xp1 - xp; + s = (sp & 0xFF) >= p0; + if (UNPREDICTABLE(s)) { + ans->state = xp; + } else { + ans->state = state - xp; + } + return s; +} + +static inline int uabs_read_bit(struct AnsDecoder *ans) { + int s; + unsigned state = ans->state; + while (state < DRACO_ANS_L_BASE && ans->buf_offset > 0) { + state = state * DRACO_ANS_IO_BASE + ans->buf[--ans->buf_offset]; + } + s = static_cast(state & 1); + ans->state = state >> 1; + return s; +} + +static inline int ans_read_init(struct AnsDecoder *const ans, + const uint8_t *const buf, int offset) { + unsigned x; + if (offset < 1) { + return 1; + } + ans->buf = buf; + x = buf[offset - 1] >> 6; + if (x == 0) { + ans->buf_offset = offset - 1; + ans->state = buf[offset - 1] & 0x3F; + } else if (x == 1) { + if (offset < 2) { + return 1; + } + ans->buf_offset = offset - 2; + ans->state = mem_get_le16(buf + offset - 2) & 0x3FFF; + } else if (x == 2) { + if (offset < 3) { + return 1; + } + ans->buf_offset = offset - 3; + ans->state = mem_get_le24(buf + offset - 3) & 0x3FFFFF; + } else { + return 1; + } + ans->state += DRACO_ANS_L_BASE; + if (ans->state >= DRACO_ANS_L_BASE * DRACO_ANS_IO_BASE) { + return 1; + } + return 0; +} + +static inline int ans_read_end(struct AnsDecoder *const ans) { + return ans->state == DRACO_ANS_L_BASE; +} + +static inline int ans_reader_has_error(const struct AnsDecoder *const ans) { + return ans->state < DRACO_ANS_L_BASE && ans->buf_offset == 0; +} + +struct rans_sym { + uint32_t prob; + uint32_t cum_prob; // not-inclusive. +}; + +// Class for performing rANS encoding using a desired number of precision bits. +// The max number of precision bits is currently 19. The actual number of +// symbols in the input alphabet should be (much) smaller than that, otherwise +// the compression rate may suffer. +template +class RAnsEncoder { + public: + RAnsEncoder() {} + + // Provides the input buffer where the data is going to be stored. + inline void write_init(uint8_t *const buf) { + ans_.buf = buf; + ans_.buf_offset = 0; + ans_.state = l_rans_base; + } + + // Needs to be called after all symbols are encoded. + inline int write_end() { + uint32_t state; + DRACO_DCHECK_GE(ans_.state, l_rans_base); + DRACO_DCHECK_LT(ans_.state, l_rans_base * DRACO_ANS_IO_BASE); + state = ans_.state - l_rans_base; + if (state < (1 << 6)) { + ans_.buf[ans_.buf_offset] = (0x00 << 6) + state; + return ans_.buf_offset + 1; + } else if (state < (1 << 14)) { + mem_put_le16(ans_.buf + ans_.buf_offset, (0x01 << 14) + state); + return ans_.buf_offset + 2; + } else if (state < (1 << 22)) { + mem_put_le24(ans_.buf + ans_.buf_offset, (0x02 << 22) + state); + return ans_.buf_offset + 3; + } else if (state < (1 << 30)) { + mem_put_le32(ans_.buf + ans_.buf_offset, (0x03u << 30u) + state); + return ans_.buf_offset + 4; + } else { + DRACO_DCHECK(0 && "State is too large to be serialized"); + return ans_.buf_offset; + } + } + + // rANS with normalization. + // sym->prob takes the place of l_s from the paper. + // rans_precision is m. + inline void rans_write(const struct rans_sym *const sym) { + const uint32_t p = sym->prob; + while (ans_.state >= l_rans_base / rans_precision * DRACO_ANS_IO_BASE * p) { + ans_.buf[ans_.buf_offset++] = ans_.state % DRACO_ANS_IO_BASE; + ans_.state /= DRACO_ANS_IO_BASE; + } + ans_.state = + (ans_.state / p) * rans_precision + ans_.state % p + sym->cum_prob; + } + + private: + static constexpr int rans_precision = 1 << rans_precision_bits_t; + static constexpr int l_rans_base = rans_precision * 4; + AnsCoder ans_; +}; + +struct rans_dec_sym { + uint32_t val; + uint32_t prob; + uint32_t cum_prob; // not-inclusive. +}; + +// Class for performing rANS decoding using a desired number of precision bits. +// The number of precision bits needs to be the same as with the RAnsEncoder +// that was used to encode the input data. +template +class RAnsDecoder { + public: + RAnsDecoder() {} + + // Initializes the decoder from the input buffer. The |offset| specifies the + // number of bytes encoded by the encoder. A non zero return value is an + // error. + inline int read_init(const uint8_t *const buf, int offset) { + unsigned x; + if (offset < 1) { + return 1; + } + ans_.buf = buf; + x = buf[offset - 1] >> 6; + if (x == 0) { + ans_.buf_offset = offset - 1; + ans_.state = buf[offset - 1] & 0x3F; + } else if (x == 1) { + if (offset < 2) { + return 1; + } + ans_.buf_offset = offset - 2; + ans_.state = mem_get_le16(buf + offset - 2) & 0x3FFF; + } else if (x == 2) { + if (offset < 3) { + return 1; + } + ans_.buf_offset = offset - 3; + ans_.state = mem_get_le24(buf + offset - 3) & 0x3FFFFF; + } else if (x == 3) { + ans_.buf_offset = offset - 4; + ans_.state = mem_get_le32(buf + offset - 4) & 0x3FFFFFFF; + } else { + return 1; + } + ans_.state += l_rans_base; + if (ans_.state >= l_rans_base * DRACO_ANS_IO_BASE) { + return 1; + } + return 0; + } + + inline int read_end() { return ans_.state == l_rans_base; } + + inline int reader_has_error() { + return ans_.state < l_rans_base && ans_.buf_offset == 0; + } + + inline int rans_read() { + unsigned rem; + unsigned quo; + struct rans_dec_sym sym; + while (ans_.state < l_rans_base && ans_.buf_offset > 0) { + ans_.state = ans_.state * DRACO_ANS_IO_BASE + ans_.buf[--ans_.buf_offset]; + } + // |rans_precision| is a power of two compile time constant, and the below + // division and modulo are going to be optimized by the compiler. + quo = ans_.state / rans_precision; + rem = ans_.state % rans_precision; + fetch_sym(&sym, rem); + ans_.state = quo * sym.prob + rem - sym.cum_prob; + return sym.val; + } + + // Construct a lookup table with |rans_precision| number of entries. + // Returns false if the table couldn't be built (because of wrong input data). + inline bool rans_build_look_up_table(const uint32_t token_probs[], + uint32_t num_symbols) { + lut_table_.resize(rans_precision); + probability_table_.resize(num_symbols); + uint32_t cum_prob = 0; + uint32_t act_prob = 0; + for (uint32_t i = 0; i < num_symbols; ++i) { + probability_table_[i].prob = token_probs[i]; + probability_table_[i].cum_prob = cum_prob; + cum_prob += token_probs[i]; + if (cum_prob > rans_precision) { + return false; + } + for (uint32_t j = act_prob; j < cum_prob; ++j) { + lut_table_[j] = i; + } + act_prob = cum_prob; + } + if (cum_prob != rans_precision) { + return false; + } + return true; + } + + private: + inline void fetch_sym(struct rans_dec_sym *out, uint32_t rem) { + uint32_t symbol = lut_table_[rem]; + out->val = symbol; + out->prob = probability_table_[symbol].prob; + out->cum_prob = probability_table_[symbol].cum_prob; + } + + static constexpr int rans_precision = 1 << rans_precision_bits_t; + static constexpr int l_rans_base = rans_precision * 4; + std::vector lut_table_; + std::vector probability_table_; + AnsDecoder ans_; +}; + +#undef DRACO_ANS_DIVREM +#undef DRACO_ANS_P8_PRECISION +#undef DRACO_ANS_L_BASE +#undef DRACO_ANS_IO_BASE + +} // namespace draco + +#endif // DRACO_COMPRESSION_ENTROPY_ANS_H_ diff --git a/third-party/draco/src/draco/compression/entropy/rans_symbol_coding.h b/third-party/draco/src/draco/compression/entropy/rans_symbol_coding.h new file mode 100644 index 0000000000..cd4271193b --- /dev/null +++ b/third-party/draco/src/draco/compression/entropy/rans_symbol_coding.h @@ -0,0 +1,53 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// File providing shared functionality for RAnsSymbolEncoder and +// RAnsSymbolDecoder (see rans_symbol_encoder.h / rans_symbol_decoder.h). +#ifndef DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_CODING_H_ +#define DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_CODING_H_ + +#include "draco/compression/entropy/ans.h" + +namespace draco { + +// Computes the desired precision of the rANS method for the specified number of +// unique symbols the input data (defined by their bit_length). +constexpr int ComputeRAnsUnclampedPrecision(int symbols_bit_length) { + return (3 * symbols_bit_length) / 2; +} + +// Computes the desired precision clamped to guarantee a valid functionality of +// our rANS library (which is between 12 to 20 bits). +constexpr int ComputeRAnsPrecisionFromUniqueSymbolsBitLength( + int symbols_bit_length) { + return ComputeRAnsUnclampedPrecision(symbols_bit_length) < 12 ? 12 + : ComputeRAnsUnclampedPrecision(symbols_bit_length) > 20 + ? 20 + : ComputeRAnsUnclampedPrecision(symbols_bit_length); +} + +// Compute approximate frequency table size needed for storing the provided +// symbols. +static inline int64_t ApproximateRAnsFrequencyTableBits( + int32_t max_value, int num_unique_symbols) { + // Approximate number of bits for storing zero frequency entries using the + // run length encoding (with max length of 64). + const int64_t table_zero_frequency_bits = + 8 * (num_unique_symbols + (max_value - num_unique_symbols) / 64); + return 8 * num_unique_symbols + table_zero_frequency_bits; +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_CODING_H_ diff --git a/third-party/draco/src/draco/compression/entropy/rans_symbol_decoder.h b/third-party/draco/src/draco/compression/entropy/rans_symbol_decoder.h new file mode 100644 index 0000000000..3b408c0791 --- /dev/null +++ b/third-party/draco/src/draco/compression/entropy/rans_symbol_decoder.h @@ -0,0 +1,171 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_DECODER_H_ +#define DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_DECODER_H_ + +#include "draco/compression/config/compression_shared.h" +#include "draco/compression/entropy/rans_symbol_coding.h" +#include "draco/core/decoder_buffer.h" +#include "draco/core/varint_decoding.h" +#include "draco/draco_features.h" + +namespace draco { + +// A helper class for decoding symbols using the rANS algorithm (see ans.h). +// The class can be used to decode the probability table and the data encoded +// by the RAnsSymbolEncoder. |unique_symbols_bit_length_t| must be the same as +// the one used for the corresponding RAnsSymbolEncoder. +template +class RAnsSymbolDecoder { + public: + RAnsSymbolDecoder() : num_symbols_(0) {} + + // Initialize the decoder and decode the probability table. + bool Create(DecoderBuffer *buffer); + + uint32_t num_symbols() const { return num_symbols_; } + + // Starts decoding from the buffer. The buffer will be advanced past the + // encoded data after this call. + bool StartDecoding(DecoderBuffer *buffer); + uint32_t DecodeSymbol() { return ans_.rans_read(); } + void EndDecoding(); + + private: + static constexpr int rans_precision_bits_ = + ComputeRAnsPrecisionFromUniqueSymbolsBitLength( + unique_symbols_bit_length_t); + static constexpr int rans_precision_ = 1 << rans_precision_bits_; + + std::vector probability_table_; + uint32_t num_symbols_; + RAnsDecoder ans_; +}; + +template +bool RAnsSymbolDecoder::Create( + DecoderBuffer *buffer) { + // Check that the DecoderBuffer version is set. + if (buffer->bitstream_version() == 0) { + return false; + } + // Decode the number of alphabet symbols. +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) { + if (!buffer->Decode(&num_symbols_)) { + return false; + } + + } else +#endif + { + if (!DecodeVarint(&num_symbols_, buffer)) { + return false; + } + } + // Check that decoded number of symbols is not unreasonably high. Remaining + // buffer size must be at least |num_symbols| / 64 bytes to contain the + // probability table. The |prob_data| below is one byte but it can be + // theoretically stored for each 64th symbol. + if (num_symbols_ / 64 > buffer->remaining_size()) { + return false; + } + probability_table_.resize(num_symbols_); + if (num_symbols_ == 0) { + return true; + } + // Decode the table. + for (uint32_t i = 0; i < num_symbols_; ++i) { + uint8_t prob_data = 0; + // Decode the first byte and extract the number of extra bytes we need to + // get, or the offset to the next symbol with non-zero probability. + if (!buffer->Decode(&prob_data)) { + return false; + } + // Token is stored in the first two bits of the first byte. Values 0-2 are + // used to indicate the number of extra bytes, and value 3 is a special + // symbol used to denote run-length coding of zero probability entries. + // See rans_symbol_encoder.h for more details. + const int token = prob_data & 3; + if (token == 3) { + const uint32_t offset = prob_data >> 2; + if (i + offset >= num_symbols_) { + return false; + } + // Set zero probability for all symbols in the specified range. + for (uint32_t j = 0; j < offset + 1; ++j) { + probability_table_[i + j] = 0; + } + i += offset; + } else { + const int extra_bytes = token; + uint32_t prob = prob_data >> 2; + for (int b = 0; b < extra_bytes; ++b) { + uint8_t eb; + if (!buffer->Decode(&eb)) { + return false; + } + // Shift 8 bits for each extra byte and subtract 2 for the two first + // bits. + prob |= static_cast(eb) << (8 * (b + 1) - 2); + } + probability_table_[i] = prob; + } + } + if (!ans_.rans_build_look_up_table(&probability_table_[0], num_symbols_)) { + return false; + } + return true; +} + +template +bool RAnsSymbolDecoder::StartDecoding( + DecoderBuffer *buffer) { + uint64_t bytes_encoded; + // Decode the number of bytes encoded by the encoder. +#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED + if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) { + if (!buffer->Decode(&bytes_encoded)) { + return false; + } + + } else +#endif + { + if (!DecodeVarint(&bytes_encoded, buffer)) { + return false; + } + } + if (bytes_encoded > static_cast(buffer->remaining_size())) { + return false; + } + const uint8_t *const data_head = + reinterpret_cast(buffer->data_head()); + // Advance the buffer past the rANS data. + buffer->Advance(bytes_encoded); + if (ans_.read_init(data_head, static_cast(bytes_encoded)) != 0) { + return false; + } + return true; +} + +template +void RAnsSymbolDecoder::EndDecoding() { + ans_.read_end(); +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_DECODER_H_ diff --git a/third-party/draco/src/draco/compression/entropy/rans_symbol_encoder.h b/third-party/draco/src/draco/compression/entropy/rans_symbol_encoder.h new file mode 100644 index 0000000000..4b738b50a9 --- /dev/null +++ b/third-party/draco/src/draco/compression/entropy/rans_symbol_encoder.h @@ -0,0 +1,290 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_ENCODER_H_ +#define DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_ENCODER_H_ + +#include +#include +#include + +#include "draco/compression/entropy/ans.h" +#include "draco/compression/entropy/rans_symbol_coding.h" +#include "draco/core/encoder_buffer.h" +#include "draco/core/varint_encoding.h" + +namespace draco { + +// A helper class for encoding symbols using the rANS algorithm (see ans.h). +// The class can be used to initialize and encode probability table needed by +// rANS, and to perform encoding of symbols into the provided EncoderBuffer. +template +class RAnsSymbolEncoder { + public: + RAnsSymbolEncoder() + : num_symbols_(0), num_expected_bits_(0), buffer_offset_(0) {} + + // Creates a probability table needed by the rANS library and encode it into + // the provided buffer. + bool Create(const uint64_t *frequencies, int num_symbols, + EncoderBuffer *buffer); + + void StartEncoding(EncoderBuffer *buffer); + void EncodeSymbol(uint32_t symbol) { + ans_.rans_write(&probability_table_[symbol]); + } + void EndEncoding(EncoderBuffer *buffer); + + // rANS requires to encode the input symbols in the reverse order. + static constexpr bool needs_reverse_encoding() { return true; } + + private: + // Functor used for sorting symbol ids according to their probabilities. + // The functor sorts symbol indices that index an underlying map between + // symbol ids and their probabilities. We don't sort the probability table + // directly, because that would require an additional indirection during the + // EncodeSymbol() function. + struct ProbabilityLess { + explicit ProbabilityLess(const std::vector *probs) + : probabilities(probs) {} + bool operator()(int i, int j) const { + return probabilities->at(i).prob < probabilities->at(j).prob; + } + const std::vector *probabilities; + }; + + // Encodes the probability table into the output buffer. + bool EncodeTable(EncoderBuffer *buffer); + + static constexpr int rans_precision_bits_ = + ComputeRAnsPrecisionFromUniqueSymbolsBitLength( + unique_symbols_bit_length_t); + static constexpr int rans_precision_ = 1 << rans_precision_bits_; + + std::vector probability_table_; + // The number of symbols in the input alphabet. + uint32_t num_symbols_; + // Expected number of bits that is needed to encode the input. + uint64_t num_expected_bits_; + + RAnsEncoder ans_; + // Initial offset of the encoder buffer before any ans data was encoded. + uint64_t buffer_offset_; +}; + +template +bool RAnsSymbolEncoder::Create( + const uint64_t *frequencies, int num_symbols, EncoderBuffer *buffer) { + // Compute the total of the input frequencies. + uint64_t total_freq = 0; + int max_valid_symbol = 0; + for (int i = 0; i < num_symbols; ++i) { + total_freq += frequencies[i]; + if (frequencies[i] > 0) { + max_valid_symbol = i; + } + } + num_symbols = max_valid_symbol + 1; + num_symbols_ = num_symbols; + probability_table_.resize(num_symbols); + const double total_freq_d = static_cast(total_freq); + const double rans_precision_d = static_cast(rans_precision_); + // Compute probabilities by rescaling the normalized frequencies into interval + // [1, rans_precision - 1]. The total probability needs to be equal to + // rans_precision. + int total_rans_prob = 0; + for (int i = 0; i < num_symbols; ++i) { + const uint64_t freq = frequencies[i]; + + // Normalized probability. + const double prob = static_cast(freq) / total_freq_d; + + // RAns probability in range of [1, rans_precision - 1]. + uint32_t rans_prob = static_cast(prob * rans_precision_d + 0.5f); + if (rans_prob == 0 && freq > 0) { + rans_prob = 1; + } + probability_table_[i].prob = rans_prob; + total_rans_prob += rans_prob; + } + // Because of rounding errors, the total precision may not be exactly accurate + // and we may need to adjust the entries a little bit. + if (total_rans_prob != rans_precision_) { + std::vector sorted_probabilities(num_symbols); + for (int i = 0; i < num_symbols; ++i) { + sorted_probabilities[i] = i; + } + std::stable_sort(sorted_probabilities.begin(), sorted_probabilities.end(), + ProbabilityLess(&probability_table_)); + if (total_rans_prob < rans_precision_) { + // This happens rather infrequently, just add the extra needed precision + // to the most frequent symbol. + probability_table_[sorted_probabilities.back()].prob += + rans_precision_ - total_rans_prob; + } else { + // We have over-allocated the precision, which is quite common. + // Rescale the probabilities of all symbols. + int32_t error = total_rans_prob - rans_precision_; + while (error > 0) { + const double act_total_prob_d = static_cast(total_rans_prob); + const double act_rel_error_d = rans_precision_d / act_total_prob_d; + for (int j = num_symbols - 1; j > 0; --j) { + int symbol_id = sorted_probabilities[j]; + if (probability_table_[symbol_id].prob <= 1) { + if (j == num_symbols - 1) { + return false; // Most frequent symbol would be empty. + } + break; + } + const int32_t new_prob = static_cast( + floor(act_rel_error_d * + static_cast(probability_table_[symbol_id].prob))); + int32_t fix = probability_table_[symbol_id].prob - new_prob; + if (fix == 0u) { + fix = 1; + } + if (fix >= static_cast(probability_table_[symbol_id].prob)) { + fix = probability_table_[symbol_id].prob - 1; + } + if (fix > error) { + fix = error; + } + probability_table_[symbol_id].prob -= fix; + total_rans_prob -= fix; + error -= fix; + if (total_rans_prob == rans_precision_) { + break; + } + } + } + } + } + + // Compute the cumulative probability (cdf). + uint32_t total_prob = 0; + for (int i = 0; i < num_symbols; ++i) { + probability_table_[i].cum_prob = total_prob; + total_prob += probability_table_[i].prob; + } + if (total_prob != rans_precision_) { + return false; + } + + // Estimate the number of bits needed to encode the input. + // From Shannon entropy the total number of bits N is: + // N = -sum{i : all_symbols}(F(i) * log2(P(i))) + // where P(i) is the normalized probability of symbol i and F(i) is the + // symbol's frequency in the input data. + double num_bits = 0; + for (int i = 0; i < num_symbols; ++i) { + if (probability_table_[i].prob == 0) { + continue; + } + const double norm_prob = + static_cast(probability_table_[i].prob) / rans_precision_d; + num_bits += static_cast(frequencies[i]) * log2(norm_prob); + } + num_expected_bits_ = static_cast(ceil(-num_bits)); + if (!EncodeTable(buffer)) { + return false; + } + return true; +} + +template +bool RAnsSymbolEncoder::EncodeTable( + EncoderBuffer *buffer) { + EncodeVarint(num_symbols_, buffer); + // Use varint encoding for the probabilities (first two bits represent the + // number of bytes used - 1). + for (uint32_t i = 0; i < num_symbols_; ++i) { + const uint32_t prob = probability_table_[i].prob; + int num_extra_bytes = 0; + if (prob >= (1 << 6)) { + num_extra_bytes++; + if (prob >= (1 << 14)) { + num_extra_bytes++; + if (prob >= (1 << 22)) { + // The maximum number of precision bits is 20 so we should not really + // get to this point. + return false; + } + } + } + if (prob == 0) { + // When the probability of the symbol is 0, set the first two bits to 1 + // (unique identifier) and use the remaining 6 bits to store the offset + // to the next symbol with non-zero probability. + uint32_t offset = 0; + for (; offset < (1 << 6) - 1; ++offset) { + // Note: we don't have to check whether the next symbol id is larger + // than num_symbols_ because we know that the last symbol always has + // non-zero probability. + const uint32_t next_prob = probability_table_[i + offset + 1].prob; + if (next_prob > 0) { + break; + } + } + buffer->Encode(static_cast((offset << 2) | 3)); + i += offset; + } else { + // Encode the first byte (including the number of extra bytes). + buffer->Encode(static_cast((prob << 2) | (num_extra_bytes & 3))); + // Encode the extra bytes. + for (int b = 0; b < num_extra_bytes; ++b) { + buffer->Encode(static_cast(prob >> (8 * (b + 1) - 2))); + } + } + } + return true; +} + +template +void RAnsSymbolEncoder::StartEncoding( + EncoderBuffer *buffer) { + // Allocate extra storage just in case. + const uint64_t required_bits = 2 * num_expected_bits_ + 32; + + buffer_offset_ = buffer->size(); + const int64_t required_bytes = (required_bits + 7) / 8; + buffer->Resize(buffer_offset_ + required_bytes + sizeof(buffer_offset_)); + uint8_t *const data = + reinterpret_cast(const_cast(buffer->data())); + ans_.write_init(data + buffer_offset_); +} + +template +void RAnsSymbolEncoder::EndEncoding( + EncoderBuffer *buffer) { + char *const src = const_cast(buffer->data()) + buffer_offset_; + + // TODO(fgalligan): Look into changing this to uint32_t as write_end() + // returns an int. + const uint64_t bytes_written = static_cast(ans_.write_end()); + EncoderBuffer var_size_buffer; + EncodeVarint(bytes_written, &var_size_buffer); + const uint32_t size_len = static_cast(var_size_buffer.size()); + char *const dst = src + size_len; + memmove(dst, src, bytes_written); + + // Store the size of the encoded data. + memcpy(src, var_size_buffer.data(), size_len); + + // Resize the buffer to match the number of encoded bytes. + buffer->Resize(buffer_offset_ + bytes_written + size_len); +} + +} // namespace draco + +#endif // DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_ENCODER_H_ diff --git a/third-party/draco/src/draco/compression/entropy/shannon_entropy.cc b/third-party/draco/src/draco/compression/entropy/shannon_entropy.cc new file mode 100644 index 0000000000..137eafe5fa --- /dev/null +++ b/third-party/draco/src/draco/compression/entropy/shannon_entropy.cc @@ -0,0 +1,147 @@ +#include "draco/compression/entropy/shannon_entropy.h" + +#include +#include + +#include "draco/compression/entropy/rans_symbol_coding.h" + +namespace draco { + +int64_t ComputeShannonEntropy(const uint32_t *symbols, int num_symbols, + int max_value, int *out_num_unique_symbols) { + // First find frequency of all unique symbols in the input array. + int num_unique_symbols = 0; + std::vector symbol_frequencies(max_value + 1, 0); + for (int i = 0; i < num_symbols; ++i) { + ++symbol_frequencies[symbols[i]]; + } + double total_bits = 0; + double num_symbols_d = num_symbols; + for (int i = 0; i < max_value + 1; ++i) { + if (symbol_frequencies[i] > 0) { + ++num_unique_symbols; + // Compute Shannon entropy for the symbol. + // We don't want to use std::log2 here for Android build. + total_bits += + symbol_frequencies[i] * + log2(static_cast(symbol_frequencies[i]) / num_symbols_d); + } + } + if (out_num_unique_symbols) { + *out_num_unique_symbols = num_unique_symbols; + } + // Entropy is always negative. + return static_cast(-total_bits); +} + +double ComputeBinaryShannonEntropy(uint32_t num_values, + uint32_t num_true_values) { + if (num_values == 0) { + return 0; + } + + // We can exit early if the data set has 0 entropy. + if (num_true_values == 0 || num_values == num_true_values) { + return 0; + } + const double true_freq = + static_cast(num_true_values) / static_cast(num_values); + const double false_freq = 1.0 - true_freq; + return -(true_freq * std::log2(true_freq) + + false_freq * std::log2(false_freq)); +} + +ShannonEntropyTracker::ShannonEntropyTracker() {} + +ShannonEntropyTracker::EntropyData ShannonEntropyTracker::Peek( + const uint32_t *symbols, int num_symbols) { + return UpdateSymbols(symbols, num_symbols, false); +} + +ShannonEntropyTracker::EntropyData ShannonEntropyTracker::Push( + const uint32_t *symbols, int num_symbols) { + return UpdateSymbols(symbols, num_symbols, true); +} + +ShannonEntropyTracker::EntropyData ShannonEntropyTracker::UpdateSymbols( + const uint32_t *symbols, int num_symbols, bool push_changes) { + EntropyData ret_data = entropy_data_; + ret_data.num_values += num_symbols; + for (int i = 0; i < num_symbols; ++i) { + const uint32_t symbol = symbols[i]; + if (frequencies_.size() <= symbol) { + frequencies_.resize(symbol + 1, 0); + } + + // Update the entropy of the stream. Note that entropy of |N| values + // represented by |S| unique symbols is defined as: + // + // entropy = -sum_over_S(symbol_frequency / N * log2(symbol_frequency / N)) + // + // To avoid the need to recompute the entire sum when new values are added, + // we can instead update a so called entropy norm that is defined as: + // + // entropy_norm = sum_over_S(symbol_frequency * log2(symbol_frequency)) + // + // In this case, all we need to do is update entries on the symbols where + // the frequency actually changed. + // + // Note that entropy_norm and entropy can be easily transformed to the + // actual entropy as: + // + // entropy = log2(N) - entropy_norm / N + // + double old_symbol_entropy_norm = 0; + int &frequency = frequencies_[symbol]; + if (frequency > 1) { + old_symbol_entropy_norm = frequency * std::log2(frequency); + } else if (frequency == 0) { + ret_data.num_unique_symbols++; + if (symbol > static_cast(ret_data.max_symbol)) { + ret_data.max_symbol = symbol; + } + } + frequency++; + const double new_symbol_entropy_norm = frequency * std::log2(frequency); + + // Update the final entropy. + ret_data.entropy_norm += new_symbol_entropy_norm - old_symbol_entropy_norm; + } + if (push_changes) { + // Update entropy data of the stream. + entropy_data_ = ret_data; + } else { + // We are only peeking so do not update the stream. + // Revert changes in the frequency table. + for (int i = 0; i < num_symbols; ++i) { + const uint32_t symbol = symbols[i]; + frequencies_[symbol]--; + } + } + return ret_data; +} + +int64_t ShannonEntropyTracker::GetNumberOfDataBits( + const EntropyData &entropy_data) { + if (entropy_data.num_values < 2) { + return 0; + } + // We need to compute the number of bits required to represent the stream + // using the entropy norm. Note that: + // + // entropy = log2(num_values) - entropy_norm / num_values + // + // and number of bits required for the entropy is: num_values * entropy + // + return static_cast( + ceil(entropy_data.num_values * std::log2(entropy_data.num_values) - + entropy_data.entropy_norm)); +} + +int64_t ShannonEntropyTracker::GetNumberOfRAnsTableBits( + const EntropyData &entropy_data) { + return ApproximateRAnsFrequencyTableBits(entropy_data.max_symbol + 1, + entropy_data.num_unique_symbols); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/entropy/shannon_entropy.h b/third-party/draco/src/draco/compression/entropy/shannon_entropy.h new file mode 100644 index 0000000000..85165f4cb8 --- /dev/null +++ b/third-party/draco/src/draco/compression/entropy/shannon_entropy.h @@ -0,0 +1,110 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef DRACO_COMPRESSION_ENTROPY_SHANNON_ENTROPY_H_ +#define DRACO_COMPRESSION_ENTROPY_SHANNON_ENTROPY_H_ + +#include + +#include + +namespace draco { + +// Computes an approximate Shannon entropy of symbols stored in the provided +// input array |symbols|. The entropy corresponds to the number of bits that is +// required to represent/store all the symbols using an optimal entropy coding +// algorithm. See for example "A mathematical theory of communication" by +// Shannon'48 (http://ieeexplore.ieee.org/document/6773024/). +// +// |max_value| is a required input that define the maximum value in the input +// |symbols| array. +// +// |out_num_unique_symbols| is an optional output argument that stores the +// number of unique symbols contained within the |symbols| array. +// TODO(ostava): This should be renamed or the return value should be changed to +// return the actual entropy and not the number of bits needed to represent the +// input symbols. +int64_t ComputeShannonEntropy(const uint32_t *symbols, int num_symbols, + int max_value, int *out_num_unique_symbols); + +// Computes the Shannon entropy of |num_values| Boolean entries, where +// |num_true_values| are set to true. +// Returns entropy between 0-1. +double ComputeBinaryShannonEntropy(uint32_t num_values, + uint32_t num_true_values); + +// Class that can be used to keep track of the Shannon entropy on streamed data. +// As new symbols are pushed to the tracker, the entropy is automatically +// recomputed. The class also support recomputing the entropy without actually +// pushing the symbols to the tracker through the Peek() method. +class ShannonEntropyTracker { + public: + ShannonEntropyTracker(); + + // Struct for holding entropy data about the symbols added to the tracker. + // It can be used to compute the number of bits needed to store the data using + // the method: + // ShannonEntropyTracker::GetNumberOfDataBits(entropy_data); + // or to compute the approximate size of the frequency table needed by the + // rans coding using method: + // ShannonEntropyTracker::GetNumberOfRAnsTableBits(entropy_data); + struct EntropyData { + double entropy_norm; + int num_values; + int max_symbol; + int num_unique_symbols; + EntropyData() + : entropy_norm(0.0), + num_values(0), + max_symbol(0), + num_unique_symbols(0) {} + }; + + // Adds new symbols to the tracker and recomputes the entropy accordingly. + EntropyData Push(const uint32_t *symbols, int num_symbols); + + // Returns new entropy data for the tracker as if |symbols| were added to the + // tracker without actually changing the status of the tracker. + EntropyData Peek(const uint32_t *symbols, int num_symbols); + + // Gets the number of bits needed for encoding symbols added to the tracker. + int64_t GetNumberOfDataBits() const { + return GetNumberOfDataBits(entropy_data_); + } + + // Gets the number of bits needed for encoding frequency table using the rans + // encoder. + int64_t GetNumberOfRAnsTableBits() const { + return GetNumberOfRAnsTableBits(entropy_data_); + } + + // Gets the number of bits needed for encoding given |entropy_data|. + static int64_t GetNumberOfDataBits(const EntropyData &entropy_data); + + // Gets the number of bits needed for encoding frequency table using the rans + // encoder for the given |entropy_data|. + static int64_t GetNumberOfRAnsTableBits(const EntropyData &entropy_data); + + private: + EntropyData UpdateSymbols(const uint32_t *symbols, int num_symbols, + bool push_changes); + + std::vector frequencies_; + + EntropyData entropy_data_; +}; + +} // namespace draco + +#endif // DRACO_COMPRESSION_ENTROPY_SHANNON_ENTROPY_H_ diff --git a/third-party/draco/src/draco/compression/entropy/shannon_entropy_test.cc b/third-party/draco/src/draco/compression/entropy/shannon_entropy_test.cc new file mode 100644 index 0000000000..732c7d2fb0 --- /dev/null +++ b/third-party/draco/src/draco/compression/entropy/shannon_entropy_test.cc @@ -0,0 +1,58 @@ +#include "draco/compression/entropy/shannon_entropy.h" + +#include "draco/core/draco_test_base.h" + +namespace { + +TEST(ShannonEntropyTest, TestBinaryEntropy) { + // Test verifies that computing binary entropy works as expected. + ASSERT_EQ(draco::ComputeBinaryShannonEntropy(0, 0), 0); + ASSERT_EQ(draco::ComputeBinaryShannonEntropy(10, 0), 0); + ASSERT_EQ(draco::ComputeBinaryShannonEntropy(10, 10), 0); + ASSERT_NEAR(draco::ComputeBinaryShannonEntropy(10, 5), 1.0, 1e-4); +} + +TEST(ShannonEntropyTest, TestStreamEntropy) { + // Test verifies that the entropy of streamed data is computed correctly. + const std::vector symbols = {1, 5, 1, 100, 2, 1}; + + draco::ShannonEntropyTracker entropy_tracker; + + // Nothing added, 0 entropy. + ASSERT_EQ(entropy_tracker.GetNumberOfDataBits(), 0); + + // Try to push symbols one by one. + uint32_t max_symbol = 0; + for (int i = 0; i < symbols.size(); ++i) { + if (symbols[i] > max_symbol) { + max_symbol = symbols[i]; + } + const auto entropy_data = entropy_tracker.Push(&symbols[i], 1); + + const int64_t stream_entropy_bits = entropy_tracker.GetNumberOfDataBits(); + // Ensure the returned entropy_data is in sync with the stream. + ASSERT_EQ(draco::ShannonEntropyTracker::GetNumberOfDataBits(entropy_data), + stream_entropy_bits); + + // Make sure the entropy is approximately the same as the one we compute + // directly from all symbols. + const int64_t expected_entropy_bits = draco::ComputeShannonEntropy( + symbols.data(), i + 1, max_symbol, nullptr); + + // For now hardcoded tolerance of 2 bits. + ASSERT_NEAR(expected_entropy_bits, stream_entropy_bits, 2); + } + + // Compare it also to the case when we add all symbols in one call. + draco::ShannonEntropyTracker entropy_tracker_2; + entropy_tracker_2.Push(symbols.data(), symbols.size()); + const int64_t stream_2_entropy_bits = entropy_tracker_2.GetNumberOfDataBits(); + ASSERT_EQ(entropy_tracker.GetNumberOfDataBits(), stream_2_entropy_bits); + + // Ensure that peeking does not change the entropy. + entropy_tracker_2.Peek(symbols.data(), 1); + + ASSERT_EQ(stream_2_entropy_bits, entropy_tracker_2.GetNumberOfDataBits()); +} + +} // namespace diff --git a/third-party/draco/src/draco/compression/entropy/symbol_coding_test.cc b/third-party/draco/src/draco/compression/entropy/symbol_coding_test.cc new file mode 100644 index 0000000000..ba7166bbe7 --- /dev/null +++ b/third-party/draco/src/draco/compression/entropy/symbol_coding_test.cc @@ -0,0 +1,170 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/config/compression_shared.h" +#include "draco/compression/entropy/symbol_decoding.h" +#include "draco/compression/entropy/symbol_encoding.h" +#include "draco/core/bit_utils.h" +#include "draco/core/decoder_buffer.h" +#include "draco/core/draco_test_base.h" +#include "draco/core/encoder_buffer.h" + +namespace draco { + +class SymbolCodingTest : public ::testing::Test { + protected: + SymbolCodingTest() : bitstream_version_(kDracoMeshBitstreamVersion) {} + + template + void TestConvertToSymbolAndBack(SignedIntTypeT x) { + typedef typename std::make_unsigned::type Symbol; + Symbol symbol = ConvertSignedIntToSymbol(x); + SignedIntTypeT y = ConvertSymbolToSignedInt(symbol); + ASSERT_EQ(x, y); + } + + uint16_t bitstream_version_; +}; + +TEST_F(SymbolCodingTest, TestLargeNumbers) { + // This test verifies that SymbolCoding successfully encodes an array of large + // numbers. + const uint32_t in[] = {12345678, 1223333, 111, 5}; + const int num_values = sizeof(in) / sizeof(uint32_t); + EncoderBuffer eb; + ASSERT_TRUE(EncodeSymbols(in, num_values, 1, nullptr, &eb)); + + std::vector out; + out.resize(num_values); + DecoderBuffer db; + db.Init(eb.data(), eb.size()); + db.set_bitstream_version(bitstream_version_); + ASSERT_TRUE(DecodeSymbols(num_values, 1, &db, &out[0])); + for (int i = 0; i < num_values; ++i) { + EXPECT_EQ(in[i], out[i]); + } +} + +TEST_F(SymbolCodingTest, TestManyNumbers) { + // This test verifies that SymbolCoding successfully encodes an array of + // several numbers that repeat many times. + + // Value/frequency pairs. + const std::pair in[] = { + {12, 1500}, {1025, 31000}, {7, 1}, {9, 5}, {0, 6432}}; + + const int num_pairs = sizeof(in) / sizeof(std::pair); + + std::vector in_values; + for (int i = 0; i < num_pairs; ++i) { + in_values.insert(in_values.end(), in[i].second, in[i].first); + } + for (int method = 0; method < NUM_SYMBOL_CODING_METHODS; ++method) { + // Test the encoding using all available symbol coding methods. + Options options; + SetSymbolEncodingMethod(&options, static_cast(method)); + + EncoderBuffer eb; + ASSERT_TRUE( + EncodeSymbols(in_values.data(), in_values.size(), 1, &options, &eb)); + std::vector out_values; + out_values.resize(in_values.size()); + DecoderBuffer db; + db.Init(eb.data(), eb.size()); + db.set_bitstream_version(bitstream_version_); + ASSERT_TRUE(DecodeSymbols(in_values.size(), 1, &db, &out_values[0])); + for (uint32_t i = 0; i < in_values.size(); ++i) { + ASSERT_EQ(in_values[i], out_values[i]); + } + } +} + +TEST_F(SymbolCodingTest, TestEmpty) { + // This test verifies that SymbolCoding successfully encodes an empty array. + EncoderBuffer eb; + ASSERT_TRUE(EncodeSymbols(nullptr, 0, 1, nullptr, &eb)); + DecoderBuffer db; + db.Init(eb.data(), eb.size()); + db.set_bitstream_version(bitstream_version_); + ASSERT_TRUE(DecodeSymbols(0, 1, &db, nullptr)); +} + +TEST_F(SymbolCodingTest, TestOneSymbol) { + // This test verifies that SymbolCoding successfully encodes an a single + // symbol. + EncoderBuffer eb; + const std::vector in(1200, 0); + ASSERT_TRUE(EncodeSymbols(in.data(), in.size(), 1, nullptr, &eb)); + + std::vector out(in.size()); + DecoderBuffer db; + db.Init(eb.data(), eb.size()); + db.set_bitstream_version(bitstream_version_); + ASSERT_TRUE(DecodeSymbols(in.size(), 1, &db, &out[0])); + for (uint32_t i = 0; i < in.size(); ++i) { + ASSERT_EQ(in[i], out[i]); + } +} + +TEST_F(SymbolCodingTest, TestBitLengths) { + // This test verifies that SymbolCoding successfully encodes symbols of + // various bit lengths + EncoderBuffer eb; + std::vector in; + constexpr int bit_lengths = 18; + for (int i = 0; i < bit_lengths; ++i) { + in.push_back(1 << i); + } + std::vector out(in.size()); + for (int i = 0; i < bit_lengths; ++i) { + eb.Clear(); + ASSERT_TRUE(EncodeSymbols(in.data(), i + 1, 1, nullptr, &eb)); + DecoderBuffer db; + db.Init(eb.data(), eb.size()); + db.set_bitstream_version(bitstream_version_); + ASSERT_TRUE(DecodeSymbols(i + 1, 1, &db, &out[0])); + for (int j = 0; j < i + 1; ++j) { + ASSERT_EQ(in[j], out[j]); + } + } +} + +TEST_F(SymbolCodingTest, TestLargeNumberCondition) { + // This test verifies that SymbolCoding successfully encodes large symbols + // that are on the boundary between raw scheme and tagged scheme (18 bits). + EncoderBuffer eb; + constexpr int num_symbols = 1000000; + const std::vector in(num_symbols, 1 << 18); + ASSERT_TRUE(EncodeSymbols(in.data(), in.size(), 1, nullptr, &eb)); + + std::vector out(in.size()); + DecoderBuffer db; + db.Init(eb.data(), eb.size()); + db.set_bitstream_version(bitstream_version_); + ASSERT_TRUE(DecodeSymbols(in.size(), 1, &db, &out[0])); + for (uint32_t i = 0; i < in.size(); ++i) { + ASSERT_EQ(in[i], out[i]); + } +} + +TEST_F(SymbolCodingTest, TestConversionFullRange) { + TestConvertToSymbolAndBack(static_cast(-128)); + TestConvertToSymbolAndBack(static_cast(-127)); + TestConvertToSymbolAndBack(static_cast(-1)); + TestConvertToSymbolAndBack(static_cast(0)); + TestConvertToSymbolAndBack(static_cast(1)); + TestConvertToSymbolAndBack(static_cast(127)); +} + +} // namespace draco diff --git a/third-party/draco/src/draco/compression/entropy/symbol_decoding.cc b/third-party/draco/src/draco/compression/entropy/symbol_decoding.cc new file mode 100644 index 0000000000..79e8118183 --- /dev/null +++ b/third-party/draco/src/draco/compression/entropy/symbol_decoding.cc @@ -0,0 +1,181 @@ +// Copyright 2016 The Draco Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "draco/compression/entropy/symbol_decoding.h" + +#include +#include + +#include "draco/compression/entropy/rans_symbol_decoder.h" + +namespace draco { + +template